上一篇随笔提到了MvcPager,最近用到了一款前端JQ插件------DataTable(简称DT),很好用。
上一篇随笔提到了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="width: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>
View Code
后端代码:
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 }
View Code
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 }
View Code
这样就搞定了。。。是不是很简单(● ̄(エ) ̄●)
╮(╯_╰)╭好的,我来解释下。
前台:
首先我们的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序列化后,返回给前端,即可。
效果图:
你的山楂能分点给我吗?