上一篇随笔提到了MvcPager,最近用到了一款前端JQ插件------DataTable(简称DT),很好用。
DT是一款前端插件,和后端完全分离开,就这点来看,我就特别喜欢。
一.使用DT,需要以下支持
js:jq+jquery.dataTables.min.js
二、页面上进行引入js,直接使用DT功能
前端代码:
1 @{ 2 Layout = null; 3 } 4 <!DOCTYPE html> 5 6 <html> 7 <head> 8 <meta charset="utf-8"> 9 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 10 <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" /> 11 <title>用户列表</title> 12 <link href="~/Content/Scripts/h-ui/css/H-ui.min.css" rel="stylesheet" /> 13 <link href="~/Content/Scripts/h-ui.admin/css/H-ui.admin.css" rel="stylesheet" /> 14 <link href="~/Content/Scripts/Hui-iconfont/1.0.8/iconfont.css" rel="stylesheet" /> 15 16 <style> 17 .page-container { 18 padding: 10px; 19 } 20 21 .operation { 22 background: #EFEEF0; 23 padding: 3px; 24 } 25 26 .search { 27 background: #EFEEF0; 28 padding: 5px; 29 margin-top: 5px; 30 } 31 32 .table { 33 margin-top: 10px; 34 } 35 36 .dataTables_info { 37 margin-left: 5px; 38 } 39 40 #table1_info { 41 padding: 0; 42 } 43 44 #table1_length { 45 margin-left: 15px; 46 } 47 </style> 48 <!--引入脚本解决兼容性(hack技术,必须放入head中)--> 49 <!--[if lt IE 9]> 50 <script src="~/Content/Scripts/html5_css3/html5shiv.min.js"></script> 51 <script src="~/Content/Scripts/html5_css3/respond.min.js"></script> 52 <script src="~/Content/Scripts/PIE-2.0beta1/PIE_IE678.js"></script> 53 <![endif]--> 54 </head> 55 <body> 56 <div class="page-container"> 57 <div class="operation"> 58 <a class="btn btn-danger radius" href="javascript:;"><i class="Hui-iconfont"></i> 批量删除</a> 59 <a class="btn btn-primary radius" href="javascript:;"><i class="Hui-iconfont"></i> 添加用户</a> 60 </div> 61 62 <div class="search"> 63 <input type="text" id="nickname" class="input-text" style="100px;" placeholder="昵称"> 64 <button id="search" class="btn btn-success" type="submit"><i class="Hui-iconfont"></i> 查询</button> 65 </div> 66 67 <div class="table"> 68 <table id="table1" class="table table-border table-bordered table-bg table-hover"> 69 <thead> 70 <tr class="text-c"> 71 <th><input type="checkbox" name="" value=""></th> 72 <th>昵称</th> 73 <th>账号</th> 74 <th>密码</th> 75 <th>添加时间</th> 76 <th>修改时间</th> 77 <th>是否禁用</th> 78 <th>操作</th> 79 </tr> 80 </thead> 81 </table> 82 </div> 83 </div> 84 </body> 85 </html> 86 <script src="~/Content/Scripts/jquery-2.0.3.min.js"></script> 87 <script src="~/Content/Scripts/datatables/1.10.13/jquery.dataTables.min.js"></script> 88 <script src="~/Content/Scripts/h-ui/js/H-ui.js"></script> 89 <script src="~/Content/Scripts/h-ui.admin/js/H-ui.admin.js"></script> 90 91 <script type="text/javascript"> 92 var table1 = null; 93 $(function() { 94 table1=initializeTable(); 95 $("#search").click(function() { 96 table1.ajax.reload(); 97 }); 98 }); 99 100 function initializeTable() {//初始化table 101 var table = $("#table1").DataTable({ 102 /****************************************表格数据加载****************************************************/ 103 "serverSide": true, 104 "ajax": {//ajax请求数据源 105 "url": "/UserInfo/Manager/Search", 106 "type": "post", 107 "data": function (data) {//添加额外的数据给服务器 108 data.pageIndex = (data.start / data.length) + 1; 109 data.nickname = $("#nickname").val().trim(); 110 } 111 }, 112 "columns": [//列绑定 113 { "defaultContent": "" }, 114 { "data": "Nickname" }, 115 { "data": "LoginName" }, 116 { "data": "LoginPassword" }, 117 { "data": "AddTime" }, 118 { "data": "ModifyTime" }, 119 { "data": "IsForbidden" }, 120 { "defaultContent": "" } 121 ], 122 "columnDefs": [//列定义 123 { 124 "targets": [0], 125 "data": "UserInfoId", 126 "render": function (data, type, full) {//全部列值可以通过full.列名获取,一般单个列值用data PS:这里的render是有多少列就执行多少次方法。。。不知道为啥 127 return "<input type='checkbox' value='" + data + "' name='UserInfoId'>"; 128 } 129 }, 130 { 131 "targets": [4], 132 "data": "AddTime", 133 "render": function (data, type, full) {//全部列值可以通过full.列名获取,一般单个列值用data PS:这里的render是有多少列就执行多少次方法。。。不知道为啥 134 if (data == null || data.trim() == "") { return ""; } 135 else { var date = new Date(parseInt(data.slice(6))); return date.getFullYear() + "/" + date.getMonth() + "/" + date.getDate(); } 136 } 137 }, 138 { 139 "targets": [5], 140 "data": "ModifyTime", 141 "render": function (data, type, full) {//全部列值可以通过full.列名获取,一般单个列值用data PS:这里的render是有多少列就执行多少次方法。。。不知道为啥 142 if (data == null || data.trim() == "") { return "/"; } 143 else { var date = new Date(parseInt(data.slice(6))); return date.getFullYear() + "/" + date.getMonth() + "/" + date.getDate(); } 144 } 145 }, 146 { 147 "targets": [6], 148 "data": "IsForbidden", 149 "render": function (data, type, full) {//全部列值可以通过full.列名获取,一般单个列值用data PS:这里的render是有多少列就执行多少次方法。。。不知道为啥 150 if (data) { return "是"; } 151 else { return "否"; } 152 } 153 }, 154 { 155 "targets": [7], 156 "data": "UserInfoId", 157 "render": function (data, type, full) {//全部列值可以通过full.列名获取,一般单个列值用data PS:这里的render是有多少列就执行多少次方法。。。不知道为啥 158 return "<a style='text-decoration:none' class='ml-5 f-14' onclick=article_edit('资讯编辑','article-add.html','" + data + "') href='javascript:;' title='编辑'><i class='Hui-iconfont'></i></a>" + 159 "<a style='text-decoration:none' class='ml-5 f-14' onclick=article_del(this,'" + data + "') href='javascript:;' title='删除'><i class='Hui-iconfont'></i></a>"; 160 } 161 }, 162 163 { "orderable": false, "targets": [0, 7] },// 是否排序 164 //{ "visible": false, "targets": [3, 5] }//是否可见 165 ], 166 "rowCallback": function (row, data, displayIndex) {//行定义 167 $(row).attr("class", "text-c"); 168 }, 169 "initComplete": function (settings, json) { //表格初始化完成后调用 170 171 }, 172 /****************************************表格数据加载****************************************************/ 173 /****************************************表格样式控制****************************************************/ 174 "dom": "t<'dataTables_info'il>p",//表格布局 175 "language": {//语言国际化 176 "lengthMenu": "每页 _MENU_ 条", 177 "zeroRecords": "没有找到记录", 178 "info": "当前显示 _START_ 到 _END_ 条,共 _TOTAL_条", 179 "infoEmpty": "无记录", 180 "paginate": 181 { 182 "first": "首页", 183 "previous": "前一页", 184 "next": "后一页", 185 "last": "末页" 186 } 187 }, 188 "pagingType": "full_numbers",//分页格式 189 "processing": true,//等待加载效果 190 "ordering": false,//排序功能 191 /****************************************表格样式控制****************************************************/ 192 }); 193 return table; 194 } 195 </script>
后端代码:
1 /****************Controller后台代码******************/ 2 public ActionResult Search(DataTable dt,string nickname) 3 { 4 int total; 5 int pageSize = dt.length; 6 int pageIndex = dt.pageIndex; 7 8 IQueryable<Model.UserInfo> userInfoIq=CurrentBllSession.UserInfoBll.GetIQueryableBySearchPage(pageIndex,pageSize,out total,nickname); 9 List<Model.UserInfo> userInfoList = userInfoIq.ToList(); 10 dt.recordsTotal = total; 11 dt.recordsFiltered = total ; 12 dt.data = userInfoList; 13 14 return Json(dt); 15 } 16 17 18 /**************************Bll服务代码************************/ 19 public IQueryable<UserInfo> GetIQueryableBySearchPage(int pageIndex,int pageSize,out int total,string nickname) 20 { 21 IQueryable<UserInfo> userInfoIq= CurrentDal.GetIQueryable(); 22 23 if (!string.IsNullOrEmpty(nickname)) 24 { 25 userInfoIq=userInfoIq.Where(a => a.Nickname.Contains(nickname)); 26 } 27 total=userInfoIq.Count(); 28 userInfoIq=userInfoIq.OrderByDescending(a => a.AddTime); 29 userInfoIq=userInfoIq.Skip((pageIndex - 1)*pageSize).Take(pageSize);//分页前必须排序,不然EF报错 30 31 return userInfoIq; 32 }
1 using System; 2 using System.Collections; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 7 namespace ViewModel 8 { 9 /// <summary> 10 /// JqueryDataTable插件交互的DT格式的数据(DT参数区分大小写) 11 /// </summary> 12 public class DataTable 13 { 14 /// <summary> 15 /// 请求次数(前端==》后端) 16 /// </summary> 17 public int draw { get; set; } 18 19 /// <summary> 20 /// 总记录数(前端《==后端) 21 /// </summary> 22 public int recordsTotal { get; set; } 23 24 /// <summary> 25 /// 过滤后的总记录数(前端《==后端) 26 /// </summary> 27 public int recordsFiltered { get; set; } 28 29 /// <summary> 30 /// 记录开始索引(前端==》后端) 31 /// </summary> 32 public int start { get; set; } 33 34 /// <summary> 35 /// PageIndex(前端==》后端) 36 /// </summary> 37 public int pageIndex { get; set; } 38 39 /// <summary> 40 /// PageSize(前端==》后端) 41 /// </summary> 42 public int length { get; set; } 43 44 /// <summary> 45 /// 集合分页数据(前端《==后端) 46 /// </summary> 47 public IList data { get; set; } 48 } 49 }
这样就搞定了。。。是不是很简单(● ̄(エ) ̄●)
╮(╯_╰)╭好的,我来解释下。
前台:
首先我们的table只是给出了thead部分,那么tbody部分呢?交给DT来完成,由DT来控制。那么我们先来初始化DT,js会调用initializeTable()方法,方法里调用$("#table1").DataTable({各种配置});来配置DT。至于这些配置的作用,我代码里都做了注释,详细的配置解释,可以查看官网的文档。
配置里有一项很重要,就是ajax配置项,这里是数据源的配置项,数据源可以有多种,我这里选用了ajax异步请求数据源。
"url": "/UserInfo/Manager/Search"这个是配置了DT请求数据的url地址
"type": "post"指明了以post方式发送请求
"data": function (data) {//添加额外的数据给服务器
data.pageIndex = (data.start / data.length) + 1;
data.nickname = $("#nickname").val().trim();
}这了由于我用到了搜索的功能,所以每次请求数据的时候,要把搜索的条件作为附加的数据传给服务器
最后,注意要加上"serverSide": true,因为我们的数据都是从后台过来的,不是前台的静态数据,要开启“服务器模式”,这样,你每次对表格的操作,都会变成一次次的请求发送给服务器。
后台:
后台负责提供数据源,使用自定义的DataTable类来作为格式化的数据进行交互。当然这里的DataTable类不是必须的,你只要满足前后数据交互的格式就可以,这里封装成一个类,是为了方便。
DT建议我们交互的数据格式,最起码要包含以下几项,我用匿名类来表示(区分大小写):
new {
draw=***,
recordsTotal=***,
recordsFiltered=***,
data=***,
}
其他项的话,你可以根据自己的实际情况自行添加。
准备好了数据之后呢,把数据Json序列化后,返回给前端,即可。
效果图: