PDA

View Full Version : بررسی یک سری نکات گیج کننده در مورد مفاهیم submit فرم , postback شدن با به کار گیری jquery



majid_darab
دوشنبه 06 تیر 1390, 19:01 عصر
با سلام و عرض خسته نباشید خدمت دوستان محترم :
نکته ای که می خوام خدمتتون عرض کنم موردی ست که در یکی از پروژه های خود به آن برخورده ام.
قضیه از این قرار است که دنبال نوشتن ولیدیتورهای فرم سمت کلاینت با جی کویری بودم و مکانیزم کار به این صورت می باشد که هنگام کلیک یک دکمه از فرم می بایست ابتدا ولیدیتورهای جی کویری سیستم را موشکافی کنند و در صورت داشتن ارور ، ارورها را در یک div به صورت modal به کاربر نشان دهند و
این در حالی ست که هیچ گونی پست بکی در اینجا نباید اتفاق بیفتد. چرا ؟ چون مدال میاد و میره!
پس از اینکه page ولید شد آنوقت پست بک باید اتفاق بیفتد که ما در اینجا کدهای سرورساید دکمه را لازم داریم ...
خوب مشکلی که عنوان خواهم نمود در مورد دکمه های معمولی دات نت و دکمه های html وجود ندارد و این مشکل در مورد linkbutton و anchor پدیدار شده است.
دکمه ای که من در فرم می خواهم استفاده کنم بنا به دلایل دیزاینی باید از لینک باتن استفاده نماید که من برای به چالش کشیدن این قضیه دکمه را با المنت a اچ تی ام ال طراحی کردم.
دکمه به صورت زیر است :



<div id="btnPaymentContainerInside">
<p id="PaymentParag">
<a id="PaymentLink" onclick="SubmitForm();" name="PaymentLink" runat="server"
onserverclick="PaymentLink_Click" title="پرداخت"></a>
</p>
</div>


خوب همان طور که گفتم ما به کدهای سرورساید دکمه پس از ولید بودن page نیاز داریم.
برای همین من runat="server" و "onserverclick="PaymentLink_Click رو به دکمه اضافه کردم...
پس وقتی این دکمه (منظور شبه دکمه با anchor) کلیک می شود عمل پست بک صورت می گیرد و ما به کدهای سرورساید دکمه دسترسی داریم.
نکته ای که دراینجا وجود داره اینه مگر نباید با هر بار پست بک شدن فرم عمل submit فرم هم اتفاق بیفتد یا بالعکس.
این قضیه در مورد دکمه ی مورد نظر ما عمل نمی کند ...
اما چگونه آن را تست کردم!
با کد زیر :


$(function () {
$('#form1').submit(function (e) {
alert('this is submit form1');
این آلرت در مورد دکمه های معمولی عمل می کند یا دکمه های html ، اما در مورد لینک باتن و یا المنت a نه.
برای همین کد زیرو به شبه دکمه اضافه کردم :

onclick="SubmitForm();"


function SubmitForm() {
$('#form1').submit();
}


خوب حالا هم submit form را داریم هم پست بک
اما حالا برای اینکه وقتی ولیدیتورها اروری پیدا کردند جلوی پست بکو بگیریم کد زیرو نوشتم :




$(function () {

$('#form1').submit(function (e) {

alert('this is submit form1');

if (error[0]) {
ErrorsInsideMessageBox.append(FormMessages.html()) ;
showErrorDiv();
e.preventDefault();
}
});
});


قسمت

e.preventDefault(); در مورد دکمه های معمولی به خوبی کار می کند ، اما در مورد دکمه ی شبیه سازی شده ی ما همچنان پست بک اتفاق می افتد.
خلاصه که من متوجه نشدم :
1-چرا submit پس از سرور ساید کردن شبه دکمه اتفاق نیفتاد و فقط پست بکو داشتیم.
2-چرا

e.preventDefault(); رو شبه دکمه عمل نمی کند و چگونه می توان این مشکلو مرتفع نمود؟

با تشکر از حسن توجه شما دوستان عزیز و گرامی

Himalaya
دوشنبه 06 تیر 1390, 20:22 عصر
سلام. من که دقیقا متوجه نشدم. بهتر بود یه پروژه کوچیک اینجا قرار میدادید که این مشکلو داشته باشه و بعد مثلا میگفتید که تو این پروژه من میخوام این کار رو انجام بدم ولی نمیشه.
به هر حال. اون چیزی که من برداشت کردم اینه که شما میخواید رو یه LinkButton یا تگ a کلیک کنید و قبل از اینکه کدای سمت سرور مربوطه اجرا بشن، توسط Jquery اعتبار سنجی سمت کلاینت رو انجام بدید و اگه همه چیز ok بود کدای سمت سرور مربوطه رو اجرا کنید. اگه منظورتون اینه، کاری که تو کدای زیر انجام شده رو، روی پروژه خودتون پیاده کنید (البته منظورم قسمت اعتبار سنجیش نیستا. این که تکست باکس خالی باشه یا نه رو واسه تست نوشتم)


<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<style>
#Controls label
{
color: Red;
display: none;
}
</style>
<script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script>
<script>
var result = true;
function SubmitForm() {
result = true;
$('#Controls input').each(function () {
if ($(this).val().replace(' ','') == '') {
$(this).next('label').css('display', 'inline-block');
result = false;
}
else
$(this).next('label').css('display', 'none');
});
return result;
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<div id="Controls">
TextBox 1:&nbsp;<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox><label>*</label><br />
TextBox 2:&nbsp;<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox><label>*</label><br />
TextBox 3:&nbsp;<asp:TextBox ID="TextBox3" runat="server"></asp:TextBox><label>*</label>
</div>
<p id="PaymentParag">
<asp:LinkButton ID="LinkButton1" runat="server" OnClientClick="return SubmitForm();" onclick="PaymentLink_Click">LinkButton</asp:LinkButton>
<br />
<a id="PaymentLink" onclick="return SubmitForm();" name="PaymentLink" runat="server"
title="پرداخت" onserverclick="PaymentLink_Click">Anchor</a>
</p>
</div>
</form>
</body>
</html>

majid_darab
دوشنبه 06 تیر 1390, 21:17 عصر
از شما دوست عزیز بابت همراهی تشکر می کنم.
حقیقت موضوع اینه که من جایی نگفتم نمی شه و اگرم گفتم از شما عذرخواهی می کنم.
من بیشتر دنبال یادگیری و حل مساله هستم...
خوب شما به روش دیگری این موضوعو حل کردید و با submit فرم درگیر نشدید و کار راه افتاد...
اما هنوز جواب مساله مجهول است.
اجازه بدید یه سوال کوچک دیگه در رابطه با function ساب میت جی کویری ازتون بپرسم که با حل اون احتمالا مشکل منم حل شود.
کد anchor ی که من به عنوان دکمه ی خودم استفاده می کنم رو در یک فرم قرار دهید.
حال کد زیرو به المنت فرم اضافه نمایید :

onsubmit="alert('alibaba');return false;"
خوب حالا وقتی رو شبه دکمه کلیک می کنیم آلرت مزبور دیده می شود و پست بکی هم اتفاق نمی افتد.پس تا اینجا همه چی درسته و میشه از این قابلیت برای مقصود خود استفاده کرد.
سوال اینه که چرا کد زیر پس از اضافه شدن و کلیک anchor اجرا نمی شه ؟

$(function () {
$('#form1').submit(function (e) {
alert('alert2');
});
});

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

با تشکر از حسن توجه شما

Himalaya
سه شنبه 07 تیر 1390, 13:12 عصر
سلام

برای همین بود که من هم مثل شما کمی گیج شدمحالا از کجا فهمیدی که من کیج شدم؟ :گیج:
راستش من زیاد خودمو درگیر این که چرا فلان راه جواب نمیده نمیکنم. (مگه این که فقط همون یه راه جلوی پام باشه و مجبور باشم ازش استفاده کنم. اونوقت میبرمش زیر زره بین)
بگذریم
در مورد سوال شما. این مورد ارتباطی به Jquery نداره
ببینید 2 تا مفهوم وجود داره. client browser's built-in submit mechanism or the ASP.NET postback mechanism
شما میگید

چرا submit پس از سرور ساید کردن شبه دکمه (تگ anchor یا لینک باتن) اتفاق نیفتاد و فقط پست بکو داشتیم. پیشنهاد میکنم یه دکمه از نوع asp:button و همون تگ anchor خودتون رو هم زمان رو صفحه قرار بدید و صفحه رو اجرا و ViewSource رو بزنید.
اگه تگ های گفته شده تو صفحه به صورت زیر باشن


<a id="PaymentLink" runat="server" title="پرداخت" onserverclick="PaymentLink_Click">Anchor</a>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="PaymentLink_Click" />
سورستون واسه این 2 بخش به صورت زیر میشه

تگ anchor بعد از رندر تو صفحه


<a id="PaymentLink" title="پرداخت" href="javascript:__doPostBack('PaymentLink','')">Anchor</a>
توضیح: این بخش داره از ASP.NET postback mechanism برای ارسال فرم استفاده میکنه. البته واسه این منظور باید یه چند خط کد جاوا اسکریپت تو صفحه رجیستر بشه که این کار رو خود دات نت بعد از تبدیل کردن تگ a به کنترل سمت سرور انجام میده. (در مورد کنترل asp:button تو حالت معمول به این صورت نیست)


<script type="text/javascript">
//<![CDATA[
var theForm = document.forms['form1'];
if (!theForm) {
theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
//]]>
</script>
تگ asp:button بعد از رندر تو صفحه


<input type="submit" name="Button1" value="Button" id="Button1" />

به خصوصیت type نگاه کن.این تگ از client browser's built-in submit mechanism برای ارسال فرم استفاده میکنه. تفاوت تو این بخشه و این ارتباطی با Jquery نداره. البته همین asp:button رو هم میشه کاری کرد که مثل تگ anchor از ASP.NET postback mechanism استفاده کنه و این کار رو میشه با خصوصیت
UseSubmitBehavior کنترل Button انجام داد


<asp:Button ID="Button1" runat="server" Text="Button" OnClick="PaymentLink_Click" UseSubmitBehavior=false />
و بعد از رندر تو صفحه


<input type="button" name="Button1" value="Button" onclick="javascript:__doPostBack('Button1','')" id="Button1" />

majid_darab
سه شنبه 07 تیر 1390, 21:35 عصر
با تشکز از پاسخ شما

حالا از کجا فهمیدی که من کیج شدم؟
از اینجا

سلام. من که دقیقا متوجه نشدم.بگذریم ...
از پاسخ شما مشخص است که در این مورد مطالعه فرمودید و پاسخ جامعی را ارایه فرمودید - لذا از این بابت صمیمانه از شما تشکر می کنم.
برای تکمیل کردن این بحث باید بگم که حالت معکوس پاسخ شما هم امکان پذیر است - یعنی می توان با تغییر دادن مکانیزم پست بک دات نت از المنت (تاکید می کنم المنت نه تگ) anchor آن گونه که لازم است بهره ببریم.
به صورت زیر :


addToPostBack = function(func) {
var old__doPostBack = __doPostBack;
if (typeof __doPostBack != 'function') {
__doPostBack = func;
} else {
__doPostBack = function(t, a) {
if (func(t, a)) old__doPostBack(t, a);
}
}
};

$(document).ready(function() {
alert("Document ready.");
addToPostBack(function(t,a) {
return confirm("Really?")
});
});