المثال يفترض ان المستخدم عليه ان:
-ان يختار مدينة من القائمة (DropDownLis) ,اسم القائمة CitiesDDL وتدعم الauto post back اي ان autopostback=true
-احدى عناصر القائمة هي القيمة Other
-هناك حقل نص TextBox بالاسم CityTB موجود على يمين القائمة.حقل النص هذا مخفي ,اي visible=false
-هناك RequiredValidator مربوط مع حقل النص CityTB لاجبار المستخدم على ملء حقل النص ,واسمه CityTBVal.هذا الvalidator غير مفعل اي enabled=false
-اذا اختار المستخدم مدينة معينة فالامور عادية ,اما اذا اختار Other فان حقل النص CityTB يصبح ظاهر اي visible=true و الvalidator المسمى CityTBVal يتم تفعيله كي نجبر المستخدم على ادخال قيمة المدينة.اذا عاد و اختار مدينة معينة فيجب اخفاء حقل النص و عدم تفعيل الvalidator
-الصفحة تستخدم ajax
المشكلة:
كيف نظهر و نخفي حقل النص فقط عند الحاجة.اي:
-يجب على قائمة المدن CitiesDDL ان تعمل postback فقط عندما تكون القيمة المختارة هي "Other" وليس عند كل تغير في القيمة المختارة.هذا الامر مهم خاصة ان كنت تحرص على الperformance وفي حالات تكون سيرفرات الاستضافة ليست سريعة بما فيه الكفاية مع الajax
-عند اختيار "Other" فيجب ان يتم اظهار حقل النص CityTB ويتم تفعيل CityTBVal كي نجبر المستخدم على ادخال قيمة المدينة واذا عاد المستخدم واختار مدينة معينة فاننا نخفي حقل النص من جديد و ننهي فاعلية CityTBVal كي لا يجبر المستخدم على ادخال قيمة في حقل النص المخفي والا فان ارسال الفورم سيفشل.
انشاء قائمة المدن و حقل النص: (على افتراض وجود جدول داخل UpdatePanel)
<tr> <td> City:</td> <td> <asp:DropDownList ID="CitiesDDL" runat="server" AppendDataBoundItems="True" DataSourceID="CitiesSDS" DataTextField="Name" DataValueField="Id" OnSelectedIndexChanged="CitiesDDL_SelectedIndexChanged" Width="207px"> <asp:ListItem Value="">Select</asp:ListItem> </asp:DropDownList> <asp:TextBox ID="CityTB" runat="server" Visible="False"></asp:TextBox> <asp:RequiredFieldValidator ID="CityTBVal" runat="server" ControlToValidate="CityTB" ErrorMessage="*" Enabled="False"> </asp:RequiredFieldValidator> </td> </tr>
اضافة العنصر Other الى القائمة:
if (!IsPostBack)
{
CitiesDDL.DataBind();
CitiesDDL.Items.Insert(CitiesDDL.Items.Count,"Other");
}باقي ان نخبر النظام اننا نريد عمل postback فقط في الحالتين التاليتن:
-عندما يختار المستخدم القيمة Other من القائمة CitiesDDL ويكون حقل النص CityTB في حالة الاخفاء.الهدف من الpostback في هذه الحالة هو لاظهار حقل النص و تفعيل الvalidator المربوط بحقل النص
-او عندما يختار المستخدم مدينة معينة ك Dubai مثلا و يكون CityTB في حالة ظاهرة.الهدف من الpostback في هذه الحالة هو لاخفاء حقل النص و عدم تفعيل الvalidator المربوط بحقل النص
الكود لعمل ذلك هو ب:
-اضافة شرط لحدث الجافاسكريبت المربوط بالقائمة CitiesDDL :
CitiesDDL.Attributes["onchange"] = "if((this.options[this.selectedIndex].value=='Other' && document.getElementById('" + CityTB.ClientID + "')==null) || (this.options[this.selectedIndex].value!='Other' && document.getElementById('" + CityTB.ClientID + "')!=null)){" + ClientScript.GetPostBackEventReference(CitiesDDL, "") + ";}";ثم التقاط الحدث SelectedIndexChanged الخاص بالقائمة CitiesDDL :
protected void CitiesDDL_SelectedIndexChanged(object sender, EventArgs e)
{
if (CitiesDDL.SelectedValue.Equals("Other"))
{
CityTB.Visible = true;
CityTBVal.Enabled = true;
}
else
{
CityTB.Visible = false;
CityTBVal.Enabled = false;
}
}كما تلاحظون فان الدالة document.getElementById تقوم بالبحث عن حقل النص باستخدام الclient id فان كانت القيمة المعادة تساوي null فمعناه ان حقل النص غير ظاهر او غير موجود وبالتالي يمكننا مع تحقق الشرط الاخر (وهو اختيار القيمة Other) ان نقوم بعمل post back .نفس الشيء يقال عن الحالة الثانية مع تغير الشروط (اي مع وجود حقل النص و اختيار قيمة غير القيمة Other من القائمة).دالة ClientScript.GetPostBackEventReference تقوم باعادة كود الجافا سكريبت الذي يقوم بعمل الpost back للقائمة.
الحدث CitiesDDL_SelectedIndexChanged يقوم باظهار/اخفاء حقل النص و تفعيل/عدم تفعيل الvalidator المربوط بحقل النص.
بالمناسبة الكود يعمل على IE و FireFox و يمكن تحسينه بافكار جديدة