系統中都須要表格,我見過最好的表格就是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的顯示\排序\分頁就都完成了