65.9K
CodeProject 正在变化。 阅读更多。
Home

jQuery Datatables 包装器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.20/5 (6投票s)

2016年12月2日

CPOL

2分钟阅读

viewsIcon

24146

downloadIcon

112

为了简化使用 jQuery DataTables 的工作。

引言

jQuery DataTables 插件是一个优秀的客户端组件,可用于在 Web 浏览器中创建功能丰富的表格。该插件为放置在网页中的普通 HTML 表格添加了许多功能,例如过滤、分页、排序、更改页面长度等。但将其插件集成到 MVC 应用程序中需要一些努力。

假设您想在 DataTables 的某个页面上编辑、删除记录,并且在执行这些操作后,您想返回到同一页面。假设您还想从不同的数据源将不同的列放入 DataTable 中。

为了在 mvc 应用程序中实现这一点,您需要创建和处理“编辑”、“删除”按钮,记住当前页面、筛选字符串、排序的列,并从某个地方获取有关要放入 DataTable 中的列的信息。要完成所有这些操作,当然需要在 Java Script 和 C# 代码中付出一些努力。

本文以一个简单的 外资银行系统 为例,展示了如何简化该过程。

使用代码

这里是实现您在图片中看到的视图页面的代码。

@using BankRegistry.Models
@using BankRegistry.Class
@model RcBnk
@{
    ViewBag.Title = "Довідник іноземних банків";
}
 
<h2>Перелік іноземних банків</h2>
 
@using (Html.BeginForm("Create", "EditBank",
    new Position(ViewBag.cp), FormMethod.Get))
    {
        if (((Infrastructure)ViewBag.cp).IsAdmin)
        {
            @*  Html Helper to to generate add button  *@
            @Html.AddRecord();
        }
    }
@*  Html Helper to to generate HTML Tag for Table tag for nessesary columns from table source   *@
@(Html.DataTable<RcBnk, RcBnkMetaData>(ViewData))
<div style="width:300;">
<link href="~/Content/css/jquery.dataTables.min.css" rel="stylesheet" />
@section Scripts
{
    <script src="~/Scripts/datatable_ext/table_init.js"></script>
    <script type="text/javascript">
    $(document).ready(function () {
        @*  Html Helper to to generate HTML java script code for call DataTables and make hundler for "edit" and "delete" buttons   *@
        @(BankRegistry.Class.DataTableHelper.DataTableInit<RcBnk, RcBnkMetaData>(
                    ViewData,
                    @* Infrastructure class  *@
                    ViewBag.cp,
                    @*  Controler and action to load data from datasource *@
                    "/Banks/LoadTable",
                    @*  key field *@
                    "B010",
                    @*  Controler and action to edit current row *@
                    "/EditBank/EditBankRecord",
                    @*  Controler and action to delete current row *@
                    "/Banks/DeleteRecord",
                    ((Infrastructure)ViewBag.cp).IsAdmin
                    ))
    }
    )
</script>
 }
</div>

为了标记要在 DataTable 中显示的列,我使用了用户属性 DataTableColumnAttribute

 [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
   sealed public class DataTableColumnAttribute : Attribute
   {
       public DataTableColumnAttribute(bool active, string name="")
       {
       }
   }

然后,我在模型中标记必要的列。

[MetadataType(typeof(RcBnkMetaData))]
    public partial class RcBnk
    {
    }
    public class RcBnkMetaData
    {
        [Key]
        [Display(Name = "Код")]
        [DataTableColumnAttribute(true)]
        public string B010 { get; set; }
        [Display(Name = "Країна")]
        [Required]
        [DataTableColumnAttribute(active: true, name: "K0401")]
        public string K040 { get; set; }
        [DataTableColumnAttribute(true)]
        public string SWIFT { get; set; }
        [Display(Name = "Назва")]
        [DataTableColumnAttribute(true)]
        public string Name { get; set; }
        [Display(Name = "Місцезнаходження")]
        [DataTableColumnAttribute(true)]
        public string Location { get; set; }
        [Display(Name = "Статус")]
        public int Status { get; set; }
        public int InQueue { get; set; }
        [Display(Name = "Користувач")]
        public int UserID { get; set; }
        [Display(Name = "Дата заведення")]
        [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
        public System.DateTime EntryTime { get; set; }
        [Display(Name = "Файл імпорту")]
        public Nullable<int> ImpFile { get; set; }
        [Display(Name = "Файл експорту")]
        public Nullable<int> ExpFile { get; set; }
        [Display(Name = "Користувач, який останеній коригував")]
        [ReadOnly(true)]
        public Nullable<int> UpdUserID { get; set; }
        [Display(Name = "Дата останнього коригування")]
        [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
        public Nullable<System.DateTime> LastUpdated { get; set; }
        public Nullable<int> CountryID { get; set; }
    }

这里是 Html.DataTableDataTableInit 的代码。它们都从元数据中读取有关必要列的信息。因此,我可以将这些信息放在一个地方。

DataTable

public static IHtmlString DataTable<T,metatData>(this HtmlHelper helper, ViewDataDictionary<T> Model)
       {
 
           TagBuilder table = new TagBuilder("table id=\"tblGreed\" class=\"table table-striped table-bordered\" cellspacing=\"0\" data-page-length='10'");
           TagBuilder tableThead = new TagBuilder("thead");
           TagBuilder tableTr = new TagBuilder("tr");
 
           var type = typeof(metatData);
           TagBuilder tableTh;
           foreach (var property in Model.ModelMetadata.Properties)
           {
               var memInfo = type.GetMember(property.PropertyName);
               if (memInfo.Length == 0) continue;
               var attributes = memInfo[0].GetCustomAttributes(typeof(BankRegistry.Controllers.DataTableColumnAttribute), true);
               if (attributes.Count() > 0)
               {
                   var attributeName = memInfo[0].GetCustomAttributes(typeof(System.ComponentModel.DataAnnotations.DisplayAttribute), true);
                   string colname = attributeName.Length > 0 ? 
                       ((System.ComponentModel.DataAnnotations.DisplayAttribute)attributeName[0]).Name :
                       property.PropertyName;
                   tableTh = new TagBuilder("th");
                   tableTh.InnerHtml = colname;
                   tableTr.InnerHtml += tableTh;
              }
           }
           tableTh = new TagBuilder("th");
           tableTr.InnerHtml += tableTh;
 
           tableThead.InnerHtml += tableTr;
           table.InnerHtml += tableThead;
           return new HtmlString(table.ToString());
       }

DataTableInit

 public static IHtmlString DataTableInit<T,metaData>
                                   (ViewDataDictionary<T> Model, 
                                    Infrastructure cp,
                                    string LoadTable="",
                                    string KeyColumn="",
                                    string EditUrl="",
                                    string DeleteUrl = "",
                                    bool   FullAccess = true
                                    )
        {
 
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            sb.Append("var ColumnsArray = new Array;");
            var type = typeof(metaData);
 
            foreach (var property in Model.ModelMetadata.Properties)
            {
                var memInfo = type.GetMember(property.PropertyName);
                if (memInfo.Length == 0) continue;
                var attributes = memInfo[0].GetCustomAttributes(typeof(BankRegistry.Controllers.DataTableColumnAttribute), true);
                if (attributes.Count() > 0)
                {
                    sb.Append("ColumnsArray.push({data: \"" + property.PropertyName + "\", autoWidth: true});");
                    sb.Append(Environment.NewLine);
 
                }
            }
            if (FullAccess)
                sb.Append("ColumnsArray.push({data:\"\", width: \"20%\", orderable: false});");
            else
                sb.Append("ColumnsArray.push({data:\"\", width: \"10%\", orderable: false});");
            sb.Append(Environment.NewLine);
            sb.Append("var CurrentPage=" + cp.currentPage + ";");
            sb.Append(Environment.NewLine);
            sb.Append("var Sorting=" + cp.sorting + ";");
            sb.Append(Environment.NewLine);
            sb.Append("var Filter='" + cp.filter + "'" + ";");
            sb.Append(Environment.NewLine);
            sb.Append("var FullAccess='" + FullAccess + "'" + ";");
            sb.Append(Environment.NewLine);
            sb.Append("var table = DataTable(ColumnsArray, '" + LoadTable + "', CurrentPage, Sorting, Filter, FullAccess)" + ";");
 
            string editclick =
                "$('#tblGreed tbody').on('click', '#edit', function () {"+
                "var data = table.row($(this).parents('tr')).data();"+
                "$(location).attr('href', '" + EditUrl + "?id=' + data['" + KeyColumn + "']" +
                    "+ '&pageNumber=' + table.page.info().page"+
                    "+ '&filter=' + $('div.dataTables_filter input').val()"+
                    "+ '&sorting=' + table.order()[0][0]);});";
 
            sb.Append(editclick);
 
            string deleteclick =
                "$('#tblGreed tbody').on('click', '#delete', function () {"+
                "var conf = confirm('Вилучити запис ?');"+
                "if (conf==true)"+
                "{"+
                    "var data = table.row($(this).parents('tr')).data();"+
                    "$(location).attr('href', '" + DeleteUrl + "?id=' + data['" + KeyColumn + "']" +
                        "+ '&pageNumber=' + table.page.info().page"+
                        "+ '&filter=' + $('div.dataTables_filter input').val()"+
                        "+ '&sorting=' + table.order()[0][0]);"+
                "}})";
            sb.Append(deleteclick);
            return new HtmlString(sb.ToString());
        }

这里是 Jquery DataTable 模式的 Java Script 代码。这里有保存页面当前位置、筛选器、管理员标志所需的基础设施的必要参数。

function DataTable(
                    ColumnsArray, // Array of columns to show
                    LoadTable,    // Url of mvc code to load date
                    CurrentPage,  //  Int number of current page
                    Sorting,      // int number of  column by with DataTable is sorted
                    Filter,       //  string filter by with DataTable is filtered
                    FullAccess    //  sign of full access to show update buttons 
                   )
{
 
    var texteditbutton = 'Коригувати'
    var deletetag = "<button id='delete' type='button' class='btn btn-default'>Вилучити</button>"
    if (FullAccess != 'True') {
        texteditbutton = 'Переглянути'
        deletetag = ''
    }
 
    var table = $('#tblGreed').DataTable({
        "lengthMenu": [[5, 10, 25, 50, -1], [5, 10, 25, 50, "Всі"]],
        iDisplayLength: -1,
        initComplete: function () {
            table.search(Filter).draw();
            table.page(CurrentPage).draw(false);
        },
        searching: true,
        ordering: true,
        order: [[Sorting, "desc"]],
        "bInfo": false,
        'bLengthChange': true,
        oLanguage: {
            oPaginate: {
                sNext: "Вперед",
                sPrevious: "Назад",
                sFirst: "Початок",
                sLast: "Кінець",
            },
            sLengthMenu: "Відображати _MENU_",
            sSearch: "Пошук: "
        },
        ajax: {
            url: LoadTable,
            contentType: "application/json"
 
        },
        columns: ColumnsArray,
        columnDefs: [{
            "targets": -1,
            "data": null,
            "defaultContent":
            "<div class='btn-group'>" +
            "<button id='edit' type='button' class='btn btn-default'>" + texteditbutton + "</button><span> </span>" +
            deletetag
        }]
    });
 
    $('#tblGreed thead th').each(function () {
        var title = $(this).text();
        $(this).html('<input type="text" placeholder="Пошук ' + title + '" />');
    });
    table.columns().eq(0).each(function (colIdx) {
        $('input', table.column(colIdx).header()).on('keyup change', function () {
            table
                .column(colIdx)
                .search(this.value)
                .draw();
        });
    })
 
    return table;
}

这里是 MVC 操作中的代码,用于将数据加载到 DataTable 中。这里,有关列的信息也从模型元数据中读取。

[HttpGet]
        //[OutputCache(Duration=50, VaryByParam="none")]
        public ActionResult LoadTable()
        {
 
            var names = typeof(RcBnk).GetProperties()
                        .Select(property => property.Name)
                        .ToArray();
            var type = typeof(RcBnkMetaData);
 
            StringBuilder sb = new StringBuilder("new (");
 
            foreach (string property in names)
            {
                var memInfo = type.GetMember(property);
                if (memInfo.Length == 0) continue;
                var attributes = memInfo[0].GetCustomAttributes(typeof(BankRegistry.Controllers.<code>DataTableColumnAttribute</code>), true);
                if (attributes.Length == 0) continue;
                if (attributes.Count() > 0)
                {
                    string sbstring;
                    if (property == "K040") sbstring = "K0401.TXT as K040";
                    else
                        sbstring = property;
                    sb.Append(sbstring + ",");
                }
            }
            sb.Append(")");
            string select = sb.ToString();
            select = select.Remove(select.LastIndexOf(','),1);
 
 
            var jsonData = new
            {
                data = _db.Banks.All.Where(x => x.Status == 0).OrderBy(r => r.Name).
                    Select(select)
            };
            return Json(jsonData, JsonRequestBehavior.AllowGet);
        }

摘要

通过这种方式,您可以处理 MVC 应用程序中的任何其他数据源。您需要做的就是通过属性标记必要的列,并在控制器中编写用于更新数据的操作。使用实体框架,这非常简单。

© . All rights reserved.