منبع اصلی نوشتار زیر در این لینک قرار دارد

باز هم آژاکس – قسمت سوم

توی دو پست قبلی توضیح دادم که چطوری میشه بدون اینکه نیازی باشه کد html اصلی رو تغییر داد فقط با اضافه کردن جاوا اسکریپت به صفحه و با کمک jQuery میشه یه صفحه رو بدون اینکه قابلیت کار معمولی خودشو از دست بده (مثل خیلی صفحه ها که میبینید اگه جاوااسکرپت نباشه کار نمیکنن) به یه صفحه کاملا آژاکسی تبدیل کرد. البته تو این نوشته همون صفحه واقعا Full Ajax میشه :)‌ توی قسمت قبلی مونده بود قسمت ویرایش که بگی نگی یه کم سنگینتره و نیازمند دقت بیشتر.
اول از همه یه کم نیازمند تغییر کد هستیم دلیلشم اینه که من زیاد دقت نکرده بودم وقتی کد اولیه رو ایجاد کردم. (خوب اصولا من آدم بی دقتی هستم، یا به قول دوستم که معتقده هیچ وقت نگو بی! بگو کم! کم دقتم)‌. به هر صورت بنا به دلایلی برای ویرایش دو تا درخواست آژاکس انجام میشه. اولی اطلاعات فیلد مورد نظر رو درخواست میکنه و دومی هم واقعا درخواست ویرایش رو به سرور میفرسته. خیلی وقتها میشه اولین درخواست رو از بین برد،‌یعنی به یه نحوی اطلاعات مورد نظر رو از فیلدهای html گرفت، مثلا اطلاعات رو از داخل عنصر td (تو این مثال)‌بگیریم که لازمه اون، افزودن یه id به اون فیلده که بعد بشه محتواشو به راحتی گرفت. به هر صورت،‌اینجا درخواست اول حاوی id اون اطلاعات مورد نظره که نیازی نیست اصلا نگرانش باشیم،‌چرا که از قبل لینک حاوی این اطلاعات هست. یعنی هر لینک مقصدی داره که کاملا مشخصه و اطلاعات مربوط به همون id رو داره. اما برای راحتی،‌ id ردیف جدول که بعدا باید محتواش عوض بشه تو خصیصه rel مربوط به لینک ویرایش ذخیره کردم واسه روز مبادا (امروز).
اما اولین درخواست :

	//3-1 we can use stored data to create new form, but I want to
	//use the get request to get the data :)
	//So get the target of this link
	var target=$(this).attr('href');
	//3-2 Send request to server and get the current data
	$.get(
		target,// Target of this link
		{},//No data needed at all, all required is 
		function(data){//Call 
				//3-3 :Just show message
				$("#msg").removeClass('message')  //Remove any old class, just in case
					 .removeClass('errmessage')
					 .addClass(data.class) //Add new 
					 .html(data.msg);	//change message(innerHTML)
				//3-4 :	If done show the edit form (or in this case simply alter 
					// Edit form. 	
				if (data.affected>-1) {
					//Simply change the add form to edit form.
					//Change the oper field to edit 
					$('#addform input[name=oper]').attr('value','edit');
					//Add a hidden field contain id of field,first remove it if any :)
					$('#addform input[name=id]').remove();
					$('<input type="hidden" name="id" value="'+data.affected+'" />').appendTo('#addform');
					//ID of form is not important :) let it be add form :)
					//Change the label of data field
					$('#addform label[for=data]').html('Edit this data :');
					//Set the data in text box(we add a new part to result json)
					$('#addform input[name=data]').attr('value',data.data);
					$('#addform input[name=submit]').attr('value','Edit');
					//Remove cancel btn if any
					$('#addform input[name=cancel]').remove();
					$('<input type="submit" value="Cancel" name="cancel" />').appendTo('#addform')
						.click(resetFunction);
				}
			},
		"json"	//Data type, see add function
	);			


روند کار به این صورته، مثل قبل مقصد لینک رو میگیریم. و به اون مقصد یه درخواست get میفرستیم.

	//3-1 we can use stored data to create new form, but I want to
	//use the get request to get the data :)
	//So get the target of this link
	var target=$(this).attr('href');
	//3-2 Send request to server and get the current data
	$.get(
		target,// Target of this link 

		//and ....

وقتی این درخواست تموم شد،‌تابع داخلی فراخوانی میشه. اول پیغام رو نشون میدیم،‌که شاید بد نباشه واسه این یکی از اون چشم پوشی کنیم :)‌و کلا نشونش ندیم. بعد وقتشه که فرم ویرایش رو نشون بدیم،‌که من اینجا همون فرم افزودن رو یه کم تغییر دادم. فیلد کلیدی oper که طرف سرور از طریق اون میفهمه که چه فرمی ارسال شده،‌تغییر میکنه به edit اگه از قبل فیلد id باشه یعنی اینکه فرم از قبل در حال ویرایش بوده، اونو حذف میکنیم، یه فیلد جدید id ایندفعه حاوی id که از طرف سرور اومده، ایجاد میکنیم، متن label و دکمه رو عوض میکنیم، محتوای فیلد متنی رو تغییر میدیم که حاوی اطلاعاتی باشه که قراره ویرایش بشه

	//Simply change the add form to edit form.
	//Change the oper field to edit 
	$('#addform input[name=oper]').attr('value','edit');
	//Add a hidden field contain id of field,first remove it if any :)
	$('#addform input[name=id]').remove();
	$('<input type="hidden" name="id" value="'+data.affected+'" />').appendTo('#addform');
	//ID of form is not important :) let it be add form :)
	//Change the label of data field
	$('#addform label[for=data]').html('Edit this data :');
	//Set the data in text box(we add a new part to result json)
	$('#addform input[name=data]').attr('value',data.data);
	$('#addform input[name=submit]').attr('value','Edit');
	//Remove cancel btn if any
	$('#addform input[name=cancel]').remove();
	$('<input type="submit" value="Cancel" name="cancel" />').appendTo('#addform')
		.click(resetFunction);

و اگه دقت کنید به کد PHP من یه فیلد data هم اضافه کردم به پاسخی که سرور به کلاینت میفرسته و این همون تغییریه که به خاطر کم دقتی من پیشش اومده و قبلا ازش صحبت کرده بودم :)‌

	if ($isAjax) {
		
		$data=array('class'=>$class,'msg'=>$msg,'affected'=>$affected,'data'=>$value);
		echo json_encode($data); //Send data in json format
		exit();		//Finish the script, in ajax mode it's critical, just result data in 
					//proper format, not anything else
	}

آخرش هم یه دکمه اضافه کردم به نام cancel که تو حالت عادی نیست، و شاید بد نباشه توی کد مرحله اولم اون رو هم اضافه کنم که حقیقتا حسش نیست. این دکمه به فرم اضافه میشه، و هنگام کلیک شدن فرم دوباره میره به حالت قبلیش یا همون حالت افزودن. کد مربوط به تابع reset اینه :

var resetFunction=function(){
	//Reset it to add form :)
	$('#addform input[name=oper]').attr('value','add');
	$('#addform input[name=id]').remove();
	$('#addform label[for=data]').html('Your new data :');
	$('#addform input[name=data]').attr('value','');
	$('#addform input[name=submit]').attr('value','Add');
	$('#addform input[name=cancel]').remove();			
}

این کد هم که به سادگی هر چی تغییر ایجاد شده برمیگردونه به حالت اولش. oper رو دوباره میکنه add فیلد id رو حذف میکنه، دکمه cancel رو هم همینطور،‌متن دکمه و label رو برمیگردونه به حالت عادی و متن داخل فیلد متنی رو هم پاک میکنه.

اما عمل اصلی تازه با فشرده شدن دکمه add که حالا داره نقش دکمه edit رو هم بازی میکنه، انجام میشه. میشد که یه تابع اضافه هم نوشته بشه و موقتا رویداد submit فرم بره روی تابع جدید که من اینکارو نکردم ،‌راحت و ساده یه کم همون تابعی رو که برای add نوشتم تغییر دادم :

	//this code just contain changes not full code, see the attachment for full code

	//first change this to get oper data from oper field.
	postData.oper=$('#addform input[name=oper]').attr('value');

	//And secound handle the add and edit requests.
	if (postData.oper=='add'){//If add, like old code
		//Create new table row with new data, see the table rows, this is just a duplicate of that.
		$("<tr id='row_"+id+"'><td>"+id+"</td><td>"+postData.data+"</td><td>"+delLink+"</td><td>"+
			editLink+"</td></tr>")
			.appendTo('#dataList tbody'); //Append it to end of table
	}else if (postData.oper=='edit'){//If edit, new code.
		$('tr#row_'+id).html('<td>'+id+'</td><td>'+postData.data+'</td><td>'+delLink+'</td><td>'+editLink+'</td>');
		resetFunction();
	}

تفاوتها در اینه که قبلا فیلد oper رو خودمون نوشته بودیم add ایندفعه از توی فرم میخونیمش (اینم باز نتیجه کم دقتیه و گرنه از اول همین هم میشد باشه) و در نهایت با یه if چک میکنیم اگه زمان ویرایش بود،‌به جای اضافه کردن یه ردیف همون ردیف قبلی رو عوض میکنیم. (یه چیزی که الان متوجه شدم،‌اصلا نیازی به ذخیره id ردیف جدول تو فیلد rel نبود. خوب بابا شد دیگه!!) و در نهایت تابع resetFunction رو هم فراخوانی میکنیم. (انقدر از jQuery استفاده کردم که یه لحظه تابع معمولی میخواستم استفاده کنم گیج شدم!!! ) همین و تمام!

کد کامل رو از آخر پست بگیرید، نمونه کار رو هم اینجا ببینید.
البته این کار هنوز هم ناقصه،‌یعنی یه سری مشکلات داره که سعی میکنم توی نوشته بعدیم حلش کنم. یعنی یه کم effect و مدیریت خطاهایی که ممکنه برای کد پیش بیاد مثلا اگه سرور در دسترس نباشه و یا نشون دادن یه پروگرس تو صفحه و یا اینکه دست کم دکمه ها تا پایان درخواست نشه روشون کلیک کرد و از این حرفا!!

اینم لینک دانلود



برچسب ها : , , , , ,