همان طور که میدانید کاربرد پذیری در خیلی از
پروژهها حرف اول رو میزند و کاربر دوست دارد کارهایی که انجام میدهد خیلی راحت
و با استفاده از موس باشد.یکی از کار هایی که در اکثر پروژهها نیاز است ، چیدمان
ترتیب رکوردها است. ما میخواهیم در این پست ترتیبی اتخاذ کنیم که کاربر بتواند رکوردها را به هر ترتیبی که دوست دارد نمایش دهد.
از توضیحاتی که قبلا دادم مشخص است که این کار
احتمالا در ASP.NET WebForm کار سختی نیست ولی این کار باید در MVC از ابتدا طراحی شود.
طرح سوال : یک سری رکورد از یک Table داریم که میخواهیم به ترتیب وارد شدن رکوردها نباشد و ترتیبی که ما میخواهیم نمایش داده
شود.
پاسخ کوتاه : خب باید ابتدا یک فیلد (برای
اولویت بندی) به Table اضافه کنیم
بعد اون فیلد رو بنا به ترتیبی که دوست داریم رکوردها نمایش داده شود پر
کنیم (Sort می کنیم ) و در آخر هم هنگام نمایش در View رکوردها را بر اساس این فیلد نمایش میدهیم.
(این پست هم در ادامه پست قبلی در همان پروژه
است و از همان Table ها استفاده شده است)
اضافه کردن فیلد :
ابتدا یک فیلد به Table مورد نظر اضافه میکنیم. من اسم این فیلد رو Priority گذاشتم. Table من چنین وضعیتی دارد.
افزودن فایلهای jQuery UI :
در این مرحله شما نیاز دارید فایلهای مورد نیاز
برای Sort کردن رکوردها را اضافه کنید. شما میتوانید فقط
فایلهای مربوط به Sortable را به صفحه خودتان اضافه کنید و یا مثل من فایل
هایی که حاوی تمام قسمتهای jQuery
UI هست را اضافه کنید.
من برای این کار از Section استفاده کردم ، ابتدا در Head فایل Layout دو Section تعریف کردم برای CSS و JavaScript . و فایلهای مربوط به Sort کردن را در صفحه ای که باید عمل Sort انجام بشود در این Section ها قرار دادم.
فایل Layout
<head>
<meta charset="utf-8" />
@RenderSection("meta", false)
<title>@ViewBag.Title</title>
<link href="@Url.Content("~/Content/~Site.css")" rel="stylesheet" type="text/css" />
<link href="@Url.Content("~/Content/redactor/css/redactor.css")" rel="stylesheet" type="text/css" />
<link href="@Url.Content("~/Content/css/bootstrap-rtl.min.css")" rel="stylesheet" type="text/css" />
@RenderSection("css", false)
<script src="@Url.Content("~/Scripts/jquery-1.8.2.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/modernizr-1.7.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Content/js/bootstrap-rtl.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Content/redactor/redactor.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
@RenderSection("js", false)
</head>
فایل Index.chtml در پوشه کنترلر Type
@model IEnumerable<KhazarCo.Models.Type>
@{
ViewBag.Title = "Index";
Layout = "~/Areas/Administrator/Views/Shared/_Layout.cshtml";
}
@section css
{<link href="@Url.Content("~/Content/themes/base/jquery-ui.css")" rel="stylesheet" type="text/css" />
}
@section js
{
<script src="@Url.Content("~/Scripts/jquery-ui-1.9.0.min.js")" type="text/javascript"></script>
}
در آخر فایل Index.chtml به اینصورت شده است:
<h2>
نوع ها</h2>
<p>
@Html.ActionLink("ایجاد یک مورد جدید", "Create", null, new { @class = "btn btn-info" })
</p>
<table>
<thead>
<tr>
<th>
عنوان
</th>
<th>
توضیحات
</th>
<th>
فعال
</th>
<th>
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.OrderBy(m => m.Priority))
{
<tr id="@item.Id">
<td>
@Html.DisplayFor(modelItem => item.Title)
</td>
<td>
@(new HtmlString(item.Description))
</td>
<td>
@Html.DisplayFor(modelItem => item.IsActive)
</td>
<td>
@Html.ActionLink("ویرایش", "Edit", new { id = item.Id }, new { @class = "btnEdit label label-warning" })
|
@Html.ActionLink("مشاهده", "Details", new { id = item.Id }, new { @class = "btnDetails label label-info" })
|
@Html.ActionLink("حذف", "Delete", new { id = item.Id }, new { @class = "btnDelete label label-important" })
</td>
</tr>
}
</tbody>
</table>
** توجه داشته باشید که من به هر tr یک id اختصاص داده ام که این مقدار id همان مقدار فیلد Id همان رکورد هست ، ما برای مرتب کردن به این Id نیاز داریم (خط 25).
افزودن کدهای کلاینت:
حالا باید کدی بنویسم که دو کار را برای ما
انجام دهد : اول حالت Sort پذیری را به سطرهای Table بدهد و دوم اینکه هنگامی که ترتیب سطرهای تغییر
کرد ما را با خبر کند:
<script type="text/javascript">
$(function () {
$("table tbody").sortable({
helper: fixHelper,
update: function (event, ui) {
jQuery.ajax('@Url.Action("Sort", "Type", new { area = "Administrator" })', {
data: { s: $(this).sortable('toArray').toString() }
});
}
}).disableSelection();
});
var fixHelper = function (e, ui) {
ui.children().each(function () {
$(this).width($(this).width());
});
return ui;
};
</script>
توضیح کد :
در این کد ما حالت ترتیب پذیری را به Table می دهیم و هنگامی که عمل Update در Table انجام شد تابع مربوطه اجرا میشود. ما در این
تایع، ترتیب جدید سطرها را میگیریم ( ** به کمک مقدار Id که به هر سطر دادیم ، این مقدار Id برابر بود با Id خود رکورد در Database ) و به کمکjQuery.ajax به تابع Sort از کنترلر Type در منطقه (area ) Administrator ارسال میکنیم و در آنجا ادامه کار را انجام
میدهیم.
تابع fixHelper هم به ما کمک میکند که هنگامی که سطرها از جای
خود جدا میشوند ، دارای عرض یکسانی باشند و عرض آنها تغییری نکند.
افزودن کد Server:
حالا باید تابع Sort که مقادیر را به آن ارسال کردیم بنویسم. من این
تابع را بر اساس مقداری که از کلاینت ارسال میشود اینگونه طراحی کردم.
public EmptyResult Sort(string s)
{
if (s != null)
{
var ids = new List<int>();
foreach (var item in s.Split(','))
{
ids.Add(int.Parse(item));
}
int intpriority = 0;
foreach (var item in ids)
{
intpriority++;
db.Types.Single(m => m.Id == item).Priority = intpriority;
}
db.SaveChanges();
}
return new EmptyResult();
}
در ایتدا مقادیر Id که از کلاینت به صورت String ارسال شده است را میگیریم و بعد به همان ترتیب
ارسال در لیستی از int قرار میدهیم ids.
سپس به اضای هر رکورد Type مقدار اولویت را به فیلدی که برای همین مورد
اضافه کردیم Priority
اختصاص میدهیم. و
در آخر هم تغییرات را ذخیره میکنیم. (خود کد کاملا واضح است و نیاری به توضیح بیشتر نیست )
حالا باید هنگامی که لیست Type ها نمایش داده میشود به ترتیب (OrderBy) فیلد Priority نمایش داده شود پس تابع Index را اینطور تغییر میدهیم.
public ViewResult Index()
{
return View(db.Types.Where(m => m.IsDeleted == false).OrderBy(m => m.Priority));
}
این هم خروجی کار من:
این عکس مربوط به است به قسمت مدیریت پروژه شیرآلات مرجان خزر.