DT的基础之上再使用jquery的一款插件:treegrid,官网地址:http://maxazan.github.io/jquery-treegrid/
一、使用treegrid,需要以下支持
jquery.min.js+jquery.treegrid.min.js
二、后端提供树状列表格式的集合数据,借助前端的DT的配置控制,来在页面上输出满足treegrid格式要求的html
前台:
1 @using Model
2 @{
3 Layout = null;
4 UserInfo userInfo = null;
5
6 if (ViewData["LoginUser"] != null)
7 {
8 userInfo = ViewData["LoginUser"] as UserInfo;
9 }
10 else
11 {
12 Response.Redirect("/Login/Index");
13 }
14 }
15
16 <!DOCTYPE html>
17
18 <html>
19 <head>
20 <meta charset="utf-8">
21 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
22 <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
23 <title>用户列表</title>
24 <link href="~/Content/Scripts/h-ui/css/H-ui.min.css" rel="stylesheet" />
25 <link href="~/Content/Scripts/h-ui.admin/css/H-ui.admin.css" rel="stylesheet" />
26 <link href="~/Content/Scripts/Hui-iconfont/1.0.8/iconfont.css" rel="stylesheet" />
27 <link href="~/Content/Scripts/treegrid/css/jquery.treegrid.css" rel="stylesheet" />
28
29 <style>
30 .page-container {
31 padding: 10px;
32 }
33
34 .operation {
35 background: #EFEEF0;
36 padding: 3px;
37 }
38
39 .search {
40 background: #EFEEF0;
41 padding: 5px;
42 margin-top: 5px;
43 }
44
45 .table {
46 margin-top: 10px;
47 }
48
49 .dataTables_info {
50 margin-left: 5px;
51 }
52
53 #table1_info {
54 padding: 0;
55 }
56
57 #table1_length {
58 margin-left: 15px;
59 }
60 </style>
61 <!--引入脚本解决兼容性(hack技术,必须放入head中)-->
62 <!--[if lt IE 9]>
63 <script src="~/Content/Scripts/html5_css3/html5shiv.min.js"></script>
64 <script src="~/Content/Scripts/html5_css3/respond.min.js"></script>
65 <script src="~/Content/Scripts/PIE-2.0beta1/PIE_IE678.js"></script>
66 <![endif]-->
67 </head>
68 <body>
69 <div class="page-container">
70 <div class="operation">
71 @Html.Partial("CRUDBtn", userInfo)
72 </div>
73
74 <div class="table">
75 <table id="table1" class="table table-border table-bordered table-bg table-hover">
76 <thead>
77 <tr class="text-c">
78 <th><input type="checkbox" name="" value=""></th>
79 <th>菜单名</th>
80 <th>请求路径</th>
81 <th>描述</th>
82 <th>添加时间</th>
83 <th>修改时间</th>
84 </tr>
85 </thead>
86 </table>
87 </div>
88 </div>
89 </body>
90 </html>
91 <script src="~/Content/Scripts/jquery-2.0.3.min.js"></script>
92 <script src="~/Content/Scripts/datatables/1.10.13/jquery.dataTables.min.js"></script>
93 <script src="~/Content/Scripts/layer/2.1/layer.js"></script>
94 <script src="~/Content/Scripts/My97DatePicker/WdatePicker.js"></script>
95 <script src="~/Content/Scripts/h-ui/js/H-ui.js"></script>
96 <script src="~/Content/Scripts/h-ui.admin/js/H-ui.admin.js"></script>
97 <script src="~/Content/Scripts/treegrid/js/jquery.treegrid.min.js"></script>
98
99 <script type="text/javascript">
100 var table1 = null;
101 $(function () {
102 table1 = initializeTable();
103 clickDeal();
104 });
105
106 /*点击处理*/
107 function clickDeal() {
108 var addBtn = $("#add");
109 var deleteBtn = $("#delete");
110 var editBtn = $("#edit");
111 var viewBtn = $("#view");
112
113 $("#search").click(function () {
114 table1.ajax.reload();
115 return false;
116 });
117 if (addBtn != null) {
118 addBtn.click(function () {
119 var title = $(this).text().substring(1).trim();
120 var url = $(this).attr("url");
121
122 layer_show(title, url, 600, 360);
123 });
124 }
125 if (deleteBtn != null) {
126 deleteBtn.click(function () {
127 var idArr = [];
128 var url = $(this).attr("url");
129
130 $("input:checkbox[name=id]:checked").each(function () {
131 var item = this;
132 idArr.push($(item).val());
133 });
134 if (idArr.length == 0) {
135 layer.msg("请至少选择一个选项", { icon: 2, time: 2000 });
136 }
137 else {
138 layer.confirm('确认要删除吗?', function (index) {
139 var loadIndex = layer.load();
140 $.ajax({
141 url: url,
142 type: "post",
143 data: { "idArrStr": idArr.toString() },
144 dataType: "json",
145 success: function (data) {
146 if (data.Pass) {
147 layer.close(loadIndex);
148 layer.msg(data.Msg, { icon: 1, time: 2000 });
149 table1.ajax.reload(null, false);
150 } else {
151 layer.msg(data.Msg, { icon: 1, time: 2000 });
152 }
153 },
154 error: function (msg) {
155 layer.msg(msg.status);
156 }
157 });
158 });
159 }
160 });
161 }
162 if (editBtn != null) {
163 editBtn.click(function () {
164 var idArr = [];
165 var title = $(this).text().substring(1).trim();
166 var url = $(this).attr("url");
167
168 $("input:checkbox[name=id]:checked").each(function () {
169 var item = this;
170 idArr.push($(item).val());
171 });
172 if (idArr.length != 1) {
173 layer.msg("请选择一个选项", { icon: 2, time: 2000 });
174 }
175 else {
176 url += "?id=" + idArr[0];
177 layer_show(title, url, 600, 360);
178 }
179 });
180 }
181 if (viewBtn != null) {
182 viewBtn.click(function () {
183 var idArr = [];
184 var title = $(this).text().substring(1).trim();
185 var url = $(this).attr("url");
186
187 $("input:checkbox[name=id]:checked").each(function () {
188 var item = this;
189 idArr.push($(item).val());
190 });
191 if (idArr.length != 1) {
192 layer.msg("请选择一个选项", { icon: 2, time: 2000 });
193 }
194 else {
195 url += "?id=" + idArr[0];
196 layer_show(title, url, 600, 360);
197 }
198 });
199 }
200
201 }
202
203 /*初始化table*/
204 function initializeTable() {
205 var table = $("#table1").DataTable({
206 /****************************************表格数据加载****************************************************/
207 "serverSide": true,
208 "ajax": {//ajax请求数据源
209 "url": "/Power/Manager/Search",
210 "type": "post",
211 "data": function (data) {//添加额外的数据给服务器
212 }
213 },
214 "columns": [//列绑定
215 { "defaultContent": "" },
216 { "data": "PowerName" },
217 { "data": "Url" },
218 { "data": "Description" },
219 { "data": "AddTime" },
220 { "data": "ModifyTime" }
221 ],
222 "columnDefs": [//列定义
223 {
224 "targets": [0],
225 "data": "PowerId",
226 "render": function (data, type, full) {//全部列值可以通过full.列名获取,一般单个列值用data PS:这里的render是有多少列就执行多少次方法。。。不知道为啥
227 return "<input type='checkbox' value='" + data + "' name='id'>";
228 }
229 },
230 {
231 "targets": [4],
232 "data": "AddTime",
233 "render": function (data, type, full) {//全部列值可以通过full.列名获取,一般单个列值用data PS:这里的render是有多少列就执行多少次方法。。。不知道为啥
234 if (data == null || data.trim() == "") { return "/"; }
235 else {
236 var dateTime = new Date(parseInt(data.replace("/Date(", "").replace(")/", ""), 10));
237 var month = dateTime.getMonth() + 1 < 10 ? "0" + (dateTime.getMonth() + 1) : dateTime.getMonth() + 1;
238 var date = dateTime.getDate() < 10 ? "0" + dateTime.getDate() : dateTime.getDate();
239 return dateTime.getFullYear() + "/" + month + "/" + date;
240 }
241 }
242 },
243 {
244 "targets": [5],
245 "data": "ModifyTime",
246 "render": function (data, type, full) {//全部列值可以通过full.列名获取,一般单个列值用data PS:这里的render是有多少列就执行多少次方法。。。不知道为啥
247 if (data == null || data.trim() == "") { return "/"; }
248 else {
249 var dateTime = new Date(parseInt(data.replace("/Date(", "").replace(")/", ""), 10));
250 var month = dateTime.getMonth() + 1 < 10 ? "0" + (dateTime.getMonth() + 1) : dateTime.getMonth() + 1;
251 var date = dateTime.getDate() < 10 ? "0" + dateTime.getDate() : dateTime.getDate();
252 return dateTime.getFullYear() + "/" + month + "/" + date;
253 }
254 }
255 },
256 ],
257 "rowCallback": function (row, data, displayIndex) {//行定义
258 if (data.ParentId != "0") {
259 $(row).attr("class", "text-c treegrid-" + data.PowerId + " treegrid-parent-" + data.ParentId);
260 } else {
261 $(row).attr("class", "text-c treegrid-" + data.PowerId);
262 }
263 },
264 "initComplete": function (settings, json) { //表格初始化完成后调用
265 $("#table1").treegrid({
266 "initialState": 'collapsed',
267 });
268 },
269 /****************************************表格数据加载****************************************************/
270 /****************************************表格样式控制****************************************************/
271 "dom": "t<'dataTables_info'il>p",//表格布局
272 "processing": true,//等待加载效果
273 "language": {//语言国际化
274 "lengthMenu": "每页 _MENU_ 条",
275 "zeroRecords": "没有找到记录",
276 "info": "当前显示 _START_ 到 _END_ 条,共 _TOTAL_条",
277 "infoEmpty": "无记录",
278 "paginate":
279 {
280 "first": "首页",
281 "previous": "前一页",
282 "next": "后一页",
283 "last": "末页"
284 },
285 "processing": "表格在努力渲染中......",
286 "loadingRecords": "加载记录中...",//注意该参数在从服务器加载的时候无效,只有Ajax和客户端处理的时候有效
287 },
288 "paging": false,//分页功能
289 "ordering": false,//排序功能
290 "autoWidth": false,//自动宽度(这里关闭后,可以随着左侧的隐藏而扩展页面一起100%宽度)
291 /****************************************表格样式控制****************************************************/
292 });
293 return table;
294 }
295
296 </script>
View Code
后台:
1 public ActionResult Search(DataTable dt)
2 {
3 int total;
4
5 IQueryable<Model.Power> powerIq = CurrentBllSession.PowerBll.GetIQueryable();
6 total = powerIq.Count();
7 List<Model.Power> powerList = powerIq.ToList();
8 powerList = TreeGridList(powerList);
9 dt.recordsTotal = total;
10 dt.recordsFiltered = total;
11 dt.data = powerList;
12
13 return Json(dt);
14 }
15
16 /// <summary>
17 /// 将List转换为TreeGrid格式的List
18 /// </summary>
19 private List<Model.Power> TreeGridList(List<Model.Power> powerList)
20 {
21 List<Model.Power> treegridList=new List<Model.Power>();
22
23 foreach (var powerOne in powerList.Where(a => a.ParentId == "0" || a.PowerId.Length == 4).OrderBy(a => a.Sort))//一级菜单
24 {
25 treegridList.Add(powerOne);
26 foreach (var powerTwo in powerList.Where(a => a.ParentId != "0" && a.PowerId.Length == 8 && a.ParentId == powerOne.PowerId).OrderBy(a=>a.Sort))//二级菜单
27 {
28 treegridList.Add(powerTwo);
29 foreach (var powerBtn in powerList.Where(a => a.ParentId != "0" && a.PowerId.Length == 8 && a.ParentId == powerTwo.PowerId).OrderBy(a => a.Sort))//按钮
30 {
31 treegridList.Add(powerBtn);
32 }
33 }
34 }
35
36 return treegridList;
37 }
View Code
解释说明:
treegrid是通过tr标签上的class内容和tr的位置关系来组织表格中行之间的父子关系和位置关系的,
DT中的配置项:
"rowCallback": function (row, data, displayIndex) {//行定义
if (data.ParentId != "0") {
$(row).attr("class", "text-c treegrid-" + data.PowerId + " treegrid-parent-" + data.ParentId);
} else {
$(row).attr("class", "text-c treegrid-" + data.PowerId);
}
},
就是来控制父子关系的。
而后台的List顺序转换,是为了调整好输出的顺序,从而来控制tr之间的位置关系。
通过DT初始化好表格之后,调用
$("#table1").treegrid({
"initialState": 'collapsed',
});
即可,绘制好树状表格。
效果图: