بعد از استفاده از گریدهای Grid.mvc , JQGrid, Kendo و مشکلاتی که با هر کدام از آنها داشتم، در نهایت به WebGrid که به صورت توکار وجود دارد، برای استفاده جهت نمایش اطلاعات رسیدم؛ از این جهت که به کتابخانهی جانبی نیازی ندارد و از نظر سرعت و لود شدن بهینه میباشد، البته با اضافه کردن یکسری کدهای css.
برای آشنایی بیشتر با این helper توصیه میکنم ابتدا این
مقاله را مطالعه نمایید.
به صورت پیش فرش WbebGrid صفحه بندی را به صورت خیلی ساده فقط با نمایش اعداد و جهت نماهای جلو و عقب، نشان میدهد که برای پروژههای رسمی تا حدودی جالب نیست.
در این مطلب قصد داریم از کتابخانهی bootstrap جهت صفحه بندی استفاده کنیم و در نهایت به صفحه بندی زیر برسیم:
برای اینکار، ابتدا قبل از هر چیزی به یک متد الحاقی برای انجام صفحه بندی سفارشی سازی شده، نیاز داریم که کدهای این متد به صورت زیر خواهد بود:
public static class WebGridExtensions
{
public static HelperResult PagerList(
this WebGrid webGrid,
WebGridPagerModes mode = WebGridPagerModes.NextPrevious | WebGridPagerModes.Numeric,
string firstText = null,
string previousText = null,
string nextText = null,
string lastText = null,
int numericLinksCount = 5)
{
return PagerList(webGrid, mode, firstText, previousText, nextText, lastText, numericLinksCount, explicitlyCalled: true);
}
private static HelperResult PagerList(
WebGrid webGrid,
WebGridPagerModes mode,
string firstText,
string previousText,
string nextText,
string lastText,
int numericLinksCount,
bool explicitlyCalled)
{
int currentPage = webGrid.PageIndex;
int totalPages = webGrid.PageCount;
int lastPage = totalPages - 1;
var ul = new TagBuilder("ul");
var li = new List<TagBuilder>();
if (ModeEnabled(mode, WebGridPagerModes.FirstLast)) {
if (String.IsNullOrEmpty(firstText)) {
firstText = "اولین";
}
var part = new TagBuilder("li") {
InnerHtml = GridLink(webGrid, webGrid.GetPageUrl(0), firstText)
};
if (currentPage == 0) {
part.MergeAttribute("class", "disabled");
}
li.Add(part);
}
if (ModeEnabled(mode, WebGridPagerModes.NextPrevious)) {
if (String.IsNullOrEmpty(previousText)) {
previousText = "قبلی";
}
int page = currentPage == 0 ? 0: currentPage - 1;
var part = new TagBuilder("li") {
InnerHtml = GridLink(webGrid, webGrid.GetPageUrl(page), previousText)
};
if (currentPage == 0) {
part.MergeAttribute("class", "disabled");
}
li.Add(part);
}
if (ModeEnabled(mode, WebGridPagerModes.Numeric) && (totalPages > 1)) {
int last = currentPage + (numericLinksCount / 2);
int first = last - numericLinksCount + 1;
if (last > lastPage) {
first -= last - lastPage;
last = lastPage;
}
if (first < 0) {
last = Math.Min(last + (0 - first), lastPage);
first = 0;
}
for (int i = first; i <= last; i++) {
var pageText = (i + 1).ToString(CultureInfo.InvariantCulture);
var part = new TagBuilder("li") {
InnerHtml = GridLink(webGrid, webGrid.GetPageUrl(i), pageText)
};
if (i == currentPage) {
part.MergeAttribute("class", "active");
}
li.Add(part);
}
}
if (ModeEnabled(mode, WebGridPagerModes.NextPrevious)) {
if (String.IsNullOrEmpty(nextText)) {
nextText = "بعدی";
}
int page = currentPage == lastPage ? lastPage: currentPage + 1;
var part = new TagBuilder("li") {
InnerHtml = GridLink(webGrid, webGrid.GetPageUrl(page), nextText)
};
if (currentPage == lastPage) {
part.MergeAttribute("class", "disabled");
}
li.Add(part);
}
if (ModeEnabled(mode, WebGridPagerModes.FirstLast)) {
if (String.IsNullOrEmpty(lastText)) {
lastText = "آخرین";
}
var part = new TagBuilder("li") {
InnerHtml = GridLink(webGrid, webGrid.GetPageUrl(lastPage), lastText)
};
if (currentPage == lastPage) {
part.MergeAttribute("class", "disabled");
}
li.Add(part);
}
ul.InnerHtml = string.Join("", li);
var html = "";
if (explicitlyCalled && webGrid.IsAjaxEnabled) {
var span = new TagBuilder("span");
span.MergeAttribute("data-swhgajax", "true");
span.MergeAttribute("data-swhgcontainer", webGrid.AjaxUpdateContainerId);
span.MergeAttribute("data-swhgcallback", webGrid.AjaxUpdateCallback);
span.InnerHtml = ul.ToString();
html = span.ToString();
} else {
html = ul.ToString();
}
return new HelperResult(writer => {
writer.Write(html);
});
}
private static String GridLink(WebGrid webGrid, string url, string text)
{
TagBuilder builder = new TagBuilder("a");
builder.SetInnerText(text);
builder.MergeAttribute("href", url);
if (webGrid.IsAjaxEnabled) {
builder.MergeAttribute("data-swhglnk", "true");
}
return builder.ToString(TagRenderMode.Normal);
}
private static bool ModeEnabled(WebGridPagerModes mode, WebGridPagerModes modeCheck)
{
return (mode & modeCheck) == modeCheck;
}
}
کلاس فوق باید در پوشهی App_Code قرار گیرد.
پس از آن در View یی که اطلاعات را نمایش میدهید، فقط لازم است کد زیر را اضافه نمایید:
<div>
@grid.PagerList(mode: WebGridPagerModes.All)
</div>
تا اینجا متد مورد نظر برای انجام صفحه بندی گرید پیاده سازی شد. ادامهی کار هم مشخص است؛ داشتن یک PartialView جهت نمایش لیست اطلاعات، پاس دادن دیتا به Partial و تمام.
در ادامه برای تکمیل بحث مثالی را از نحوهی نمایش اطلاعات و صفحه بندی سفارشی نشان خواهیم داد:
PartialView لازم برای نمایش اطلاعات
تنظیمات لازم گرید :
@{
WebGrid grid = new WebGrid(Model,
rowsPerPage: 10,
ajaxUpdateContainerId: "grid");
var rowIndex = ((grid.PageIndex + 1) * grid.RowsPerPage) - (grid.RowsPerPage - 1);
}
تعیین فیلدهای گرید :
@grid.Table(
tableStyle: "table table-striped table-hover",
headerStyle: "webgrid-header",
alternatingRowStyle: "webgrid-alternating-row",
selectedRowStyle: "webgrid-selected-row",
rowStyle: "webgrid-row-style",
columns: grid.Columns(
grid.Column(columnName: "Name", header: "نام استان", style: "myfont"),
grid.Column(columnName: "NameEn", header: "نام استان ( انگلیسی )", style: "myfont"),
grid.Column(header: "", format: item => @Html.ActionLink("مدیریت شهرها", actionName: MVC.Admin.City.ActionNames.Index, controllerName: MVC.Admin.City.Name, routeValues: new {Code=item.Code },htmlAttributes:null)),
grid.Column(header: "",
style: "text-align-center-col smallcell",
format: item => @Html.ActionLink(linkText: "ویرایش", actionName: "Edit",
controllerName: "Province", routeValues: new { area = "Admin", code = item.Code },
htmlAttributes: new { @class = "btn-sm btn-info vertical-center" }))
) )
<div>
@grid.PagerList(mode: WebGridPagerModes.All)
</div>
خروجی حاصل به صورت زیر خواهد بود :
اگر طبق توضیحات بالا عمل کرده باشید، در نهایت صفحه بندی شما به صورت عمودی نمایش داده میشود؛ یعنی هر کدام از شماره صفحات در یک سطر. دلیل آن هم این است که تگ ul، کلاس .pagination را ندارد. در کدهای بوت استراپ تعریف شده است که تمام li هایی که به صورت مستقیم داخل کلاس .pagination هستند خصوصیات مورد نظر را بگیرند.
برای این کار دو راه حل وجود دارد :
راه حل اول: تغییر کدهای css
کدهای نوشته شده برای صفحه بندی در بوت استراپ را از حالت زیر:
به حالت زیر تغییر دهید:
یادآوری : علامت < در CSS یعنی به صورت مستقیم و در شاخهی اول.
راه حل دوم - افزودن کلاس .pagination به تگ ul:
ابتدا کلاس .pagination را از تگ div حذف نمایید:
<div >
@grid.PagerList(mode: WebGridPagerModes.All)
</div>
و در کدهایی کلاس WebGridExtensions، در قسمتی که تگ ul اصافه میشود، کلاس مورد نظر را به آن اضافه میکنیم:
var ul = new TagBuilder("ul");
ul.AddCssClass("pagination");
دانلود کدهای این مثال
نکتهای در مورد Webgrid
اگر نیاز داشتید به یکباره تمام اطلاعات را در گرید لود نکنید و به صورت n تاn تا رکوردها را نمایش دهید، در این حالت پس از پاس دادن لیستی از اطلاعات به View مورد نظر لازم است تعداد کل رکوردها را در یک متغییر به سمت View بفرستید. این کار به این دلیل میباشد که بتوان صفحه بندی را تولید کرد. برای این کار در بخش تنظیمات Webgrid مقدار source را برابر null قرار دهید و از قطعه کد زیر جهت بایند کردن گرید، بعد از کدهای تنظیمات WebGrid استفاده نمایید:
grid.Bind(Model, rowCount: (int)ViewBag.PageCount);