系统中都须要表格,我见过最好的表格就是Datatables了,但中文文档有限,英文能力有限,就写一些简单用法css
上图看效果先html
要了分页和排序前端
基本用法jquery
引入js和cssajax
bundles.Add(new ScriptBundle("~/bundles/datatablesJs").Include( "~/Content/vendors/datatables.net/js/jquery.dataTables.min.js", "~/Content/vendors/datatables.net-bs/js/dataTables.bootstrap.min.js", "~/Content/vendors/iCheck/icheck.min.js", "~/Scripts/datatables.helper.js")); bundles.Add(new StyleBundle("~/Content/vendors/datatables.net-bs/css/datatablesCss1").Include( "~/Content/vendors/datatables.net-bs/css/dataTables.bootstrap.min.css")); bundles.Add(new StyleBundle("~/Content/vendors/iCheck/skins/flat/datatablesCss2").Include( "~/Content/vendors/iCheck/skins/flat/green.css"));
html正则表达式
<table id="usertable" class="table table-striped table-bordered"> <thead> <tr> <th><input type="checkbox" id="check-all"></th> <th>序号</th> <th>登陆名</th> <th>昵称</th> <th>有效状态</th> <th>建立时间</th> <th>修改时间</th> </tr> </thead> </table>
jsjson
var $datatable = $("#usertable"); var $btnadd = $("#btn_add"); var $btndel = $("#btn_del"); var $btnmodify = $("#btn_modify"); var $myaddmodal = $("#myAddModal"); var $mymodifymodal = $("#myModifyModal"); var $formadd = $("#form_add"); var $formmodify = $("#form_modify"); var $submitadd = $("#submit_add"); var $submitmodify = $("#submit_modify"); var $modifyId = $("#MId"); //---------------------datatables表格初始化---------------- var tbl = $datatable.DataTable({ "ajax": { "url": "/Admin/Back/GetDatas", "data": function (data) { return JSON.stringify(data); } }, "columns": [ { "data": "Id" }, { "data": null }, { "data": "Account" }, { "data": "NickName" }, { "data": "IsEnabled" }, { "data": "AddTime" }, { "data": "LastTime" } ], 'columnDefs': [ { targets: [0], "render": function (data, type, full, meta) { return '<input type="checkbox" name="checklist" value="' + data + '" />'; }, "bSortable": false }, { targets: [1], "render": function (data, type, full, meta) { return meta.row + 1; }, "bSortable": false }, { targets: [4], "render": function (data, type, full, meta) { return get_enabled(data); } }, { targets: [5, 6], "render": function (data, type, full, meta) { return moment(data).format("YYYY-MM-DD HH:mm:ss"); } } ] }); //tbl.order([6, 'desc']).draw(); //绘制表格事件 $datatable.on("draw.dt", function () { turn_on_icheck(); check_all(); });
$datatable.DataTable就是表格的初始化bootstrap
"data": function (data) { return JSON.stringify(data); }
保证了传入的参数为json格式服务器
'columnDefs': [ { targets: [0], "render": function (data, type, full, meta) { return '<input type="checkbox" name="checklist" value="' + data + '" />'; }, "bSortable": false }, { targets: [1], "render": function (data, type, full, meta) { return meta.row + 1; }, "bSortable": false } ]
columnDefs是列渲染
[0]表明第一列,代码将第一页渲染成了checkbox,将第二页渲染成了自增列(只是本页自增)
"bSortable": false 表示该列不排序
这样固然是不够的,由于咱们没有看到datatables的配置项都在哪,是由于我把它封装了
$.extend($.fn.dataTable.defaults, { "processing": true,//加载中 "ordering": true, // 是否开启排序功能(默认开启) "order": [[0, "asc"]], // 设置默认排序的表格列[参数1是表格列的下标,从0开始] "serverSide": true,//服务器模式(★★★★★重要,本文主要介绍服务器模式) "searching": false,//datatables自带的搜索 "ajax": { "type": "POST",//(★★★★★重要) "contentType": "application/json; charset=utf-8" }, "language": { "processing": "加载中...", "lengthMenu": "每页显示 _MENU_ 条数据", "zeroRecords": "没有匹配结果", "info": "显示第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项", "infoEmpty": "显示第 0 至 0 项结果,共 0 项", "infoFiltered": "(由 _MAX_ 项结果过滤)", "infoPostFix": "", "search": "搜索:", "url": "", "emptyTable": "没有匹配结果", "loadingRecords": "载入中...", "thousands": ",", "paginate": { "previous": "上一页", "next": "下一页" } } }); function get_enabled(parameters) { if (parameters === 1) { return "有效"; } else { return "已禁用"; } } //渲染页面全部的checkbox为icheck function turn_on_icheck() { $("input[type=checkbox]").iCheck({ checkboxClass: "icheckbox_flat-green" }); } //全选 function check_all() { var $checkboxAll = $("#check-all"), $checkbox = $("tbody").find("[type='checkbox']"); $checkboxAll.on('ifClicked', function (event) { if (event.target.checked) { $checkbox.iCheck("uncheck"); } else { $checkbox.iCheck("check"); } }); }
这里我将checkbox渲染成了一个icheck,还有全选,这些都须要在绘制datatables事件中完成app
//绘制表格事件 $datatable.on("draw.dt", function () { turn_on_icheck(); check_all(); });
OK,前端搞定,看看后台吧
后台
[HttpPost] public JsonResult GetDatas(DataTablesParameters query) { var totalCount = 0; var result = _bll.QueryPage(GetLamada(query.OrderBy), (int)query.OrderDir, query.Start, query.Length, ref totalCount).ToList(); var viewResult = result.ToModelList(); var resultJson = new DataTablesResult<UserViewModel>(query.Draw, totalCount, totalCount, viewResult); return Json(resultJson); }
能够看到,传入的参数也被我封装了,由于datatables会固定传入一些值
封装类DataTablesParameters
using System.Collections.Generic; using System.Linq; namespace FuturesContest.ViewModel.DataTables { public class DataTablesParameters { /// <summary> /// 请求次数计数器 /// </summary> public int Draw { get; set; } /// <summary> /// 第一条数据的起始位置 /// </summary> public int Start { get; set; } /// <summary> /// 每页显示的数据条数 /// </summary> public int Length { get; set; } /// <summary> /// 数据列 /// </summary> public List<DataTablesColumns> Columns { get; set; } /// <summary> /// 排序 /// </summary> public List<DataTablesOrder> Order { get; set; } /// <summary> /// 搜索 /// </summary> public DataTablesSearch Search { get; set; } /// <summary> /// 排序字段 /// </summary> public string OrderBy => Columns != null && Columns.Any() && Order != null && Order.Any() ? Columns[Order[0].Column].Data : string.Empty; /// <summary> /// 排序模式 /// </summary> public DataTablesOrderDir OrderDir => Order != null && Order.Any() ? Order[0].Dir : DataTablesOrderDir.Desc; } /// <summary> /// 排序 /// </summary> public class DataTablesOrder { /// <summary> /// 排序的列的索引 /// </summary> public int Column { get; set; } /// <summary> /// 排序模式 /// </summary> public DataTablesOrderDir Dir { get; set; } } /// <summary> /// 排序模式 /// </summary> public enum DataTablesOrderDir { /// <summary> /// 正序 /// </summary> Asc, /// <summary> /// 倒序 /// </summary> Desc } /// <summary> /// 数据列 /// </summary> public class DataTablesColumns { /// <summary> /// 数据源 /// </summary> public string Data { get; set; } /// <summary> /// 名称 /// </summary> public string Name { get; set; } /// <summary> /// 是否能够被搜索 /// </summary> public bool Searchable { get; set; } /// <summary> /// 是否能够排序 /// </summary> public bool Orderable { get; set; } /// <summary> /// 搜索 /// </summary> public DataTablesSearch Search { get; set; } } /// <summary> /// 搜索 /// </summary> public class DataTablesSearch { /// <summary> /// 全局的搜索条件的值 /// </summary> public string Value { get; set; } /// <summary> /// 是否为正则表达式处理 /// </summary> public bool Regex { get; set; } } }
这里传入的orderby是一个字符串,咱们的方法须要一个lamada,那么就须要一个笨方法,将string转换成lamada
其实这个方法应该放到bll层里
private static Expression<Func<User, object>> GetLamada(string name) { Expression<Func<User, object>> func; switch (name) { case "Id": func = m => m.Id; break; case "Account": func = m => m.Account; break; case "NickName": func = m => m.NickName; break; case "IsEnabled": func = m => m.IsEnabled; break; case "AddTime": func = m => m.AddTime; break; case "LastTime": func = m => m.LastTime; break; default: func = m => m.OrderId; break; } return func; }
var viewResult = result.ToModelList();
这里用到了autoMapper,我感受我用的不太对,就先不讲了
参数被封装,返回值也有固定的格式,固然也被封装
using System.Collections.Generic; namespace FuturesContest.ViewModel.DataTables { public class DataTablesResult<T> { public DataTablesResult(int drawParam, int recordsTotalParam, int recordsFilteredParam, IReadOnlyList<T> dataParam) { draw = drawParam; recordsTotal = recordsTotalParam; recordsFiltered = recordsFilteredParam; data = dataParam; } public DataTablesResult(string errorParam) { error = errorParam; } public int draw { get; set; } public int recordsTotal { get; set; } public int recordsFiltered { get; set; } public IReadOnlyList<T> data { get; set; } public string error { get; set; } } }
var resultJson = new DataTablesResult<UserViewModel>(query.Draw, totalCount, totalCount, viewResult);
接受返回的封装泛型,转换成json到前端
到这里,datatables的显示\排序\分页就都完成了