Extension Methods :
قبل از هر چیز باید از تاخیر بوجود آمده در ارسال قسمتهای جدید عذر خواهی کنم و این
نکته را متذکر شوم که در این قسمت سعی کرده ام از JQuery و JSON به
عنوان مکملی برای MVC استفاده کنم. با یک جستجوی ساده در اینترنت
خواهید دید که مثالی که در آخر این مقاله آمده است ، مورد سئوال در بسیاری از
فارومهای معروف و بین المللی برنامه نویسی مثل StackOverFlow و ASP.Net بوده است که
متاسفانه تا آنجا که من دیدم جوابهای مناسبی هم داده نشده بود.
همانطور که در بخشهای قبلی این سری مقالات دیدید، با استفاده از متدهای کلاس Helper
می توانید بسیاری از ابزارها یا عناصر Html ی مورد نیاز را استفاده کنید. مثال زیر
برای ایجاد یک لینک به کار می رود که متن آن Create است و به اکشن
CreateUser لینک شده است :
@Html.ActionLink("Create", "CreateUser ")
یا مثال زیر برای ایجاد یک CheckBox بکار می رود، نام آن cb1 است ، به طور پیش فرض تیک خورده و از کلاس class1 استفاده می کند:
@Html.CheckBox("cb1" , true , new {@class = "class1"})
، مثال زیر یک DropDownList است ، نامش ddl1 است. مقددار پیش فرض --select -- به آن اضافه شده و از کلاس class1 ( منظور کلاس استایل شیت ، Css است) استفاده می کند:
@Html.DropDownList("dd1","--Select--",new { @class="class1" })
بسیاری از نمونه های اینچنینی را می توانید در این لینک ببینید.
اما مسئله ای که وجود دارد این است که در کلاس HtmlHelper متد یا متدهایی برای
نمایش ابزارهایی که یک گروه از مقادیر را نشان می دهند ، مثل CheckListBox یا
RadioButtonList وجود ندارد . برای ایجاد آنها باید خودمان در متدهای که به
Extension Methods معروف هستند ، آنها را ایجاد کنیم . این متدها به ما کمک
می کنند تا ابزارهای مورد نیاز خود را به صورت سفارشی ایجاد و به کلاس
HtmlHelper اضافه کنیم. (مقاله ای مفید در مورد Extension Method )
در ادامه می خواهیم یک CheckBoxList را از طریق Extension Method ها به کلاس
HtmlHelper اضافه کنیم. قبل از نوشتن کد آن ، لازم است یاد آور شوم که معمولا یک checkBocList برای نمایش لیستی از اطلاعات ( مثلا لیست علاقهمندیها ) به کار می
رود. ابتدا من اکشنی که این لیست را میخواند، مینویسم. این
اکشن بسیار ساده است و قبلا نمونه آن را در همین سری مقالات دیدهایم:
public ActionResult Index()
{
Dictionary<Int32, string> interests = new Dictionary<Int32, string>();
interests.Add(2, "Sport");
interests.Add(3, "Travel");
interests.Add(4, "Music");
ViewBag.Cities = interests;
return View();
}
توضیح اینکه من به این دلیل متغیر از نوع دیکشنری انتخاب کردم که بتوانم علاوه بر اسم علاقه مندی، مقداری نیز به آن پاس دهم. البته شما ممکن است که این مقادیر را در بانک اطلاعاتی خود ثبت کرده باشید که مشکلی نیست و می توانید آن ها را براحتی درون متغیر دیکشنری بریزید
نویت به ایجاد Extention Method رسید .
برای این کار در پروژه خود فولدری به نام دلخواه ، مثلا
CommonClasses ایجاد کنید،
سپس کلاسی به نام CheckBoxListHelper در آن بسازید.
سپس کد زیر را در آن تایپ کنید :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
public static class CheckBoxListHelper
{
public static MvcHtmlString CheckListBox(this HtmlHelper helper, string Name, Dictionary<Int32, string> citiesList, bool IsVertical, string cssClass)
{
StringBuilder sb = new StringBuilder();
sb.Append(string.Format("<div >"));
foreach (var item in citiesList)
{
sb.Append(helper.CheckBox(item.Value,true , new { @class = cssClass, value = item.Key }));
sb.Append(helper.Label("RadioButtonItems", item.Value));
sb.Append(" ");
if (IsVertical) sb.Append("<br>");
}
sb.Append("</div> ");
return MvcHtmlString.Create(sb.ToString());
}
}
توضیح و تذکر:
1- name space ها فراموش نشود.
2- به آرگومانها دقت کنید: Name نام هر Checkbox را تشکیل می دهد .
interestList همان دیکشنری است که نام علاقهمندیها و مقادیرشان در آن ذخیره شده
است. IsVertical مشخص کننده این است که CheckBox ها افقی یا عمودی در صفحه قرار
بگیرند. cssClass نام کلاس css هر CheckBox است .
3- کلاس از نوع Static است
حال کافی است در صفحه (View یی ) که می خواهیم از
CheckBoxList
استفاده کنیم ، ابتدا این کلاس را معرفی کنیم (در اینجا نام پروژه نیز Extention_Methods است ):
@using Extention_Methods.CommonClasses
و سپس آن را فراخوانی کنیم :
@Html.CheckBoxList("cb1" , (Dictionary<int, string>) ViewBag.Cities , false , "myCssClas" )
همانطور که می بینید من کلاس myCssClas را به همه عناصر CheckBoxList انتصاب
کرده ا م ، به این ترتیب باعث ایجاد تگهای input با خصوصیت class="myCssClass"
خواهیم شد. خروجی نیزبه صورت زیر به نمایش در خواهد آمد:
اما مهمترین قسمت :
یک مسئله باقی می ماند:
چگونه مقدار گزینههای را که کاربر تیک زده ، بدست بیاوریم؟ برای این کار از JQuery
استفاده می کنیم. من دکمه ای به فرم اضافه کردم که با کلیک روی آن مقدار value
گزینه انتخابی به اکشن save از کنترلر home ارسال می شود. ابتدا دکمه ای را به
صفحه اضافه می کنم و آن را درون یک فرم با مدل Razor می گذارم :
@using (Html.BeginForm("SaveCities", "Home"))
{
@Html.CheckListBox("clb1", (Dictionary<int, string>)ViewBag.Interest, false, "myCssClass")
<input type="submit" name="btnSubmit" id="btnSubmit" value="Save" />
}
حال با نوشتن یک بخش JQuery در همان View کار را دنبال می کنیم و مقدارValue هر
CheckBox ی که تیک خورده است را ابتدا در یک آرایه ذخیره می کنیم و سپس با استفاده
از ajax آن را به اکشن Save از کنترلر Home ارسال می کنیم:
<script src="../../Scripts/jquery-1.5.1.js" type="text/javascript"></script>
<script src="../../Scripts/jquery.json.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#btnSubmit").click(sendValues);
});
function populateValues() {
var data = new Array();
$('.myCssClass').each(function () {
if ($(this).attr('checked')) {
var x = $(this).attr("value");
data.push(x);
}
}); // of each
return data;
}
function sendValues() {
event.preventDefault();
var data = populateValues();
$.ajax({
type: 'POST',
url: '@Url.Content("~/Home/Save")',
data: $.json.encode(data),
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function () { alert("1"); }
});
} // of sendValues
</script>
توضیح: در کد فوق با کلیک روی btnSubmit تابع sendValues را فراخوانی می کنیم. در این تابع ابتدا با preventDefault از ارسال فرم به کنترلر خودداری می کنیم (چون هنوز مقادیر CheckBox ها را دریافت نکردهایم) و سپس تابع populateValues هستیم که با استفاده از همان کلاس myCssClass مقدار value همه CheckBox ها را می گیرد و در آرایه ای به نام data ذخیره می کند. این آرایه سپس توسط ajax با فرمت json به اکشن svae از کنترلر Home ارسال می شود.
اگر در مورد نحوه فراخوانی ajax در Jquery اطلاعاتی می خواهید به این لینک مراجعه کنید.
اگر می خواهید JQuery یاد بگیرید از این لینک شروع کنید.
در اکشن Save مقادیر ارسال شده از View توسط آرگومان خوانده می شوند ( int[] val ) :
--
اکنون برای ادامه و تمرین به کلاس Helper یک RadioButtonList اضافه کنید و مقدار انتخابی را در کنترلر دریافت کنید.