PDA

View Full Version : گفتگو: ارسال مقادیر به سرور توسط jQuery - روشن شدن مسئله



LORD AELX
چهارشنبه 20 مرداد 1389, 17:06 عصر
هدف من از ایجاد این تاپیک اینه که تجربیات این چند روز خودم رو با شما به اشتراک بگذارم و همینطور راه هایی رو که از اون ها جواب گرفتم ذکر کنم و راجع بهشون تبادل نظر کنیم. ضمن اینکه بررسی کنیم که چرا روش های دیگر عملیاتی نمی باشند. :متفکر:

ببینید، هدف از ارسال مقادیر به سرور توسط jQuery فقط AJAX بودن کار نیست، مزایای دیگری هم داره که باعث میشه کد HTML کمتر و استفاده کمتر از دکمه submit داشته باشیم ضمن اینکه یکسری از کار ها رو سمت کلاینت انجام بدهیم. :لبخندساده:

من تو این چند روز خیلی تو وب گشتم و روش های ارسال رو بررسی کردم ولی خوب، بعضی از اونا کار نمی کنند. در واقع بهتر بگویم، آن دسته از ورودی هایی که درون تگ فرم قرار نگرفته بودند و Form Submit ای در کار نبود، بازگشت نتیجه ای نداشتند. علاوه بر آن، تنها چیزی که غیر از ارسال تگ فرم قابلیت عملیاتی داشت، لینک هایی بود که href آن ها برابر یک آدرس بعلاوه Query String بود.

آیا من نباید بتونم با انتخاب یک مقدار از SELECT (همون Combo Box یا DropDown Box)، بلافاصله مقدار آن را بدست بیاورم و آن را به سرور ارسال کنم و سرور هم نتیجه را بازگشت بدهد؟ چرا حتما باید Refresh ای در کار باشد؟! بیشتر منظورم زمانی هست که همه عملیات و HTML و ... در یک فایل PHP پیاده سازی می شود. در این صورت چطور می توان با کدی همانند زیر، چنین مقداری را به سرور ارسال کرد و نتیجه را هم دید؟!


<?php
# I'm test.php
if(isset($_POST['s1'])) {
echo $_POST['s1'];
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Example 1</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="styles.css" type="text/css" />
<script language="javascript" src="jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#s1').change(function(){
var selected = $("#s1 option:selected").val();
$.post("test.php", { name: selected} ); // or => $.post("test.php", { 'name': selected} ); => There is no difference between
});
});
</script>
</head>
<body>
<select name="s1" id="s1">
<option value="v1">Value 1</option>
<option value="v2">Value 2</option>
<option value="v3">Value 3</option>
</select>
</body>
</html>


ولی مثلا همین مثال را به این شکل می توان پیاده سازی کرد:


<?php
# I'm test.php
if(isset($_POST['s1'])) {
echo $_POST['s1'];
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Example 2</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="styles.css" type="text/css" />
<script language="javascript" src="jquery.min.js" type="text/javascript"></script>
</head>
<body>
<form name="frm" id="frm" action="<?php echo $PHP_SELF?>" method="POST">
<select name="s1" onchange="javascript: $('#frm').submit();">
<option value="v1">Value 1</option>
<option value="v2">Value 2</option>
<option value="v3">Value 3</option>
</select>
</form>
</body>
</html>


خوب، چرا کد اولی عملیاتی نیست؟! نمیگم که باید به اون شکلی که نوشته شده کار کنه، مسلما چون refresh ای در کار نیست، این انتظار هم ازش نمیره ولی آیا راه دیگه ای نیست؟ یا آیا راهی نیست تا AJAX را برای خود آن فایل بصورت درونی کار کنیم؟

این مسئله به همین جا ختم نمی شود... :اشتباه: حتی مثلا وقتی من می خواستم با کلیک روی یک تصویر یک رکورد از دیتابیس را حذف کنم و با کلیک بر روی دیگری آن را ویرایش نمایم، مجبور شدم بجای راه های ساده و ... علاوه بر قرار دادن فرم در اطراف این ناحیه، چند input از نوع hidden هم تعریف کنم و سپس با jQuery مقدار value آن ها را ست کرده و سپس فرم را submit کنم....

و ... و ... و ... . الآن دیگه حوصله بیشتر نوشتن رو ندارم، فقط به عنوان شروع بپذیرید تا بعدا بیشتر بحث کنیم... بچه هایی هم که میدونند اینا رو و میدونم که میدونند، لطف کنن این قضیه رو توجیه کنند. راه کار منطقی، بهینه و عملیاتی ارایه دهید وگرنه یک کار به n طریق قابل انجام است و به کار انداختن یک وبسایت فقط صرف کار کردن آن از هر کسی بر میاید. مسئله مهم برای من مثل همیشه کدنویسی کمتر، بهینه، منطقی، قدرتمند و قابل انعطاف است.

متشکرم :قلب:

mehdi.mousavi
چهارشنبه 20 مرداد 1389, 22:37 عصر
سلام.
مساله اول اینه که وقتی change رو می گیرید، دیگه نباید برید از ابتدا توی DOM Document جستجو کنید. کافیه بدین شکل عمل کنید:

$('#s1').change(function () {
var selected = $(this).val();
$.post("test.php", { name: selected });
});


اما نکته مهم چیه، اینجا Post بصورت Asynchronous انجام میشه. به بیان دیگه، اطلاعات به صفحه test.php پست میشه، اما دیگه منتظر نمی مونه ببین پاسخ چی هستش و اجرا به خط بعد از $.post منتقل میشه. اگه به پاسخش علاقمند هستید، می تونید از پارامتر سوم این متود استفاده کنید. بدین ترتیب هر وقت پاسخ از سرور دریافت بشه، پارامتر سوم که یه تابع هستش فراخوانی میشه و شما میتونید با پاسخ دریافتی هر کاری که نیاز دارید انجام بدید (که یکی از این کارها، طبیعتا Refresh کردن اطلاعات بخشی از صفحه میتونه باشه):

$('#s1').change(function () {
var selected = $(this).val();
$.post("test.php", { name: selected }, function (data) {
//this function gets called if the request succeeds...
alert(data);
});
});


موفق باشید.

LORD AELX
چهارشنبه 20 مرداد 1389, 23:55 عصر
مهدی جان، متشکرم که پاسخ دادید :بوس:

فقط فعلا یک مسئله دیگری هم هست که ذهن منو به خودش مشغول کرده، دیگه نمیگم برای حل این مشکلم از چه راه هایی استفاده کردم چون کمی طولانی و بیهوده میشه... فقط میخوام بگم قصد انجام چه کاری رو دارم و امیدوارم بتونید در این مورد هم کمکم کنید... :چشمک:

ببینید، خیلی از مواقع نیاز میشه که ما از تگ <a> یا به اصطلاح همون لینک ها در صفحه مون استفاده کنیم. این تگ میتونه به عنوان یک دکمه معمولی، دکمه submit، لینک منو و ... استفاده و شبیه سازی بشه. خوب مسلما در مواقعی همچون استفاده به عنوان یک دکمه (مثلا استفاده از یک icon برای پاک کردن یک record) نیاز به ارسال یک یا چند مقدار به سرور داریم. همونطور که میدونید تگ <a> دارای خاصیت value نیست، اگر هم مقدار href ای برای آن تنظیم شود، مرورگر به آن آدرس ارجاع داده می شود و در نتیجه با خطا مواجه می شویم. حالا اگر این مقدار یک دستور javascript باشد، مشکلی ندارد (در صورت نیاز).

تا به این لحظه دقیقا نمیدونستم برای حالت قبلی که ذکر کردم و مخصوصا این حالتی که الآن گفتم چه کاری باید انجام داد. چون متد post باعث refresh صفحه نمیشد! مگر اینکه من یک فرم را submit می کردم و در این صورت هم مجبور بودم با jQuery مقدار value چند تا input از نوع hidden رو تغییر بدهم و سپس فرم را بفرستم. که این کار برای صفحاتی با تعداد آبجکت بالا کدنویسی مضاعف و بیهوده می برد.

حالا که گفتید میشه از پارامتر سوم متد post یعنی همان CallBack برای refresh صفحه استفاده کرد، احساس می کنم این مشکلم حل شده. حالا آیا واقعا باید از این ترکیب استفاده کرد؟! :متفکر: یعنی ابتدا رویداد jQuery را بگیرم و سپس درون آن عملیات post را انجام دهم و در نهایت پارامتر سوم post را تابعی تعریف کنم که عمل reload را انجام دهد؟! آیا این راه استاندارد است؟

متشکرم :قلب:

mehdi.mousavi
چهارشنبه 27 مرداد 1389, 23:48 عصر
حالا که گفتید میشه از پارامتر سوم متد post یعنی همان CallBack برای refresh صفحه استفاده کرد، احساس می کنم این مشکلم حل شده. حالا آیا واقعا باید از این ترکیب استفاده کرد؟! یعنی ابتدا رویداد jQuery را بگیرم و سپس درون آن عملیات post را انجام دهم و در نهایت پارامتر سوم post را تابعی تعریف کنم که عمل reload را انجام دهد؟! آیا این راه استاندارد است؟

سلام.
بله، این روش کاملا اصولی هستش و استاندارد. البته اگر بتونید از متود load (http://www.jqapi.com/#p=load) برای Load بخشی از صفحه استفاده کنید، خوب طبیعتا این کار ساده تر خواهد بود و نیاز به نوشتن کد کمتری هستش. اما همیشه نمیشه از load استفاده کرد، چون سرویسها عموما داده برمیگردونن، نه HTML. اگر Web Method ای دارید که HTML برمیگردونه (من البته این ایده رو زیاد نمی پسندم، مگر در شرایط خاص، منظورم از خاص شرایطی هستش که هر 20 سال یکبار یک درصد امکان داره رخ بده) میتونید از load استفاده کنید تا بخشی از پاسخ رو در Element دیگه ای که در حال حاضر روی صفحه هستش قرار بدید. بطور نمونه:

$('#result').load('myservice/whatever.php?id=2&action=getCustomerInfo #container');

این کد باعث میشه تا درخواست GET ای به whatever.php ارسال بشه، پاسخ دریافتی که یک HTML هستش گرفته بشه، در درون پاسخ Element ای با ID ی container انتخاب بشه، و محتویات این Element جایگزین محتوای element ای با ID ی result بشه. همونطوریکه می بینید، این روش بسیار ساده تر هستش، اما همونطور که گفتم، معمولا سرویسها داده برمیگردونن و نه HTML. چون اینطوری سرویس شما مختص یک Client خواهد بود و سرویس به Presentation Layer شما، بطور Tightly Coupled میچسبه...

موفق باشید.