当前位置:   article > 正文

layui treeTable

layui treetable

layui table结构不能很直观的展示层级信息,所以参考"https://fly.layui.com/extend/treeTable/"组件(layui版本为v2.5.6),修改为树形展示,修改了treeTable.js,保留了一些原table定义;

修改如下:支持reload,post方式拉取数据,参考table配置(操作列支持toolbar,cols结构,checkStatus),check_mode(0上下级联勾选默认,1单选,2多选[不级联]),open_all(默认展开全部),level_key(层级字段),level_start(实际层级最小值,默认为0,第一级展示的时候保证没有左边距)

id,elem必须一致,不过elem加了"#"

缺点:一次拉取所有数据,数据量大的时候不能动态刷新子节点(待改进)

departList.cshtml

  1. @model Web.Admin.Models.DepartListViewModel
  2. @{
  3. Layout = null;
  4. }
  5. <!DOCTYPE html>
  6. <html>
  7. <head>
  8. <title>部门管理</title>
  9. <meta name="referrer" content="no-referrer" />
  10. <link href="/components/layui/css/layui.css" rel="stylesheet" type="text/css" />
  11. </head>
  12. <body>
  13. <div class="layui-row" id="pic-search">
  14. <div class="layui-col-md12">
  15. <div class="layui-card">
  16. <div class="layui-card-body">
  17. <form class="layui-form" lay-filter="searchForm">
  18. <div class="layui-input-inline layui-col-md6">
  19. @Html.TextBoxFor(x => x.keyword, new { placeholder = "关键字", @class = "layui-input" })
  20. </div>
  21. <div class="layui-input-inline layui-col-md3">
  22. <button type="button" id="btnSearch" class="layui-btn">查询</button>
  23. @if (Model.edit)
  24. {
  25. <button type="button" id="btnAdd" class="layui-btn">新增</button>
  26. }
  27. </div>
  28. </form>
  29. </div>
  30. </div>
  31. </div>
  32. </div>
  33. <div id="data-list" style="margin:10px 10px 0px;">
  34. <table class="layui-table layui-form" id="departTable" lay-filter="table"></table>
  35. </div>
  36. <div id="dlg-edit" style="display:none;padding:20px 30px 0 0;">
  37. <form class="layui-form" lay-filter="editForm">
  38. <div class="layui-form-item">
  39. <label class="layui-form-label">名称</label>
  40. <div class="layui-input-block">
  41. <input type="text" name="dpname" lay-verify="required" autocomplete="off" placeholder="机构名称不能为空" class="layui-input">
  42. </div>
  43. </div>
  44. <div class="layui-form-item">
  45. <label class="layui-form-label">院校</label>
  46. <div class="layui-input-block">
  47. <select name="parentid"></select>
  48. </div>
  49. </div>
  50. <div class="layui-form-item">
  51. <label class="layui-form-label">排序</label>
  52. <div class="layui-input-block">
  53. <input type="number" value="0" min="0" name="displayorder" autocomplete="off" lay-verify="required|number" class="layui-input">
  54. </div>
  55. </div>
  56. <div class="layui-form-item">
  57. <label class="layui-form-label">备注</label>
  58. <div class="layui-input-block">
  59. <textarea name="remark" placeholder="请输入内容" class="layui-textarea"></textarea>
  60. </div>
  61. </div>
  62. </form>
  63. </div>
  64. <script type="text/html" id="toobar">
  65. <a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="detail">查看</a>
  66. @if (Model.edit)
  67. {
  68. <a class="layui-btn layui-btn-xs" lay-event="update">修改</a>
  69. <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
  70. }
  71. </script>
  72. <script src="/scripts/jquery.js"></script>
  73. <script src="/components/layui/layui.js"></script>
  74. <script>
  75. layui.config({
  76. base: "../../../components/layui/"//基于当前页面,查找treeTable.js文件所在目录
  77. });
  78. //获取选择的项
  79. function getChecked() {
  80. return layui.treeTable.checkStatus("departTable");
  81. }
  82. function getQueryParas() {
  83. return layui.form.getValue("searchForm");
  84. }
  85. function search() {
  86. var index = layui.layer.load(1);//开启进度条
  87. layui.treeTable.reload('departTable', {
  88. where: getQueryParas(),
  89. done: function (res) {
  90. layer.close(index);
  91. }
  92. });
  93. }
  94. function openDetail(data) {
  95. showEditDlg({
  96. title: "查看",
  97. btn: ["关闭"],
  98. success: function () {
  99. layui.form.val("editForm", data);
  100. },
  101. yes: function (index) {
  102. layui.layer.close(index);
  103. }
  104. }, 2);
  105. }
  106. function showEditDlg(option, m) {
  107. var index = layui.layer.load(1);
  108. $.get("/admin/user/GetTopDepartList", function (data) {
  109. var dd = $("#dlg-edit select[name='parentid']").empty();
  110. if (m == 2) {
  111. //查看
  112. $("#dlg-edit").addClass("layui-disabled");
  113. }
  114. else {
  115. $("#dlg-edit").removeClass("layui-disabled");
  116. if (m == 0) {
  117. //重置表单
  118. layui.form.val("editForm", $("#dlg-edit").data("default"));
  119. //新增
  120. dd.prop("disabled", false);
  121. }
  122. else if (m == 1) {
  123. //编辑
  124. dd.prop("disabled", true);
  125. }
  126. }
  127. dd.append("<option value=\"0\">顶级单位</option>");
  128. if (data && data.length) {
  129. $.each(data, function (i, o) {
  130. dd.append($("<option>").attr("value", o.dpid).text(" " + o.dpname));
  131. });
  132. dd.val(data[0].dpid);
  133. }
  134. layui.form.render("select", "editForm");
  135. layui.layer.close(index);
  136. var opt = $.extend({
  137. type: 1,
  138. shadeClose: false,
  139. btnAlign: 'c',
  140. shade: 0.3,
  141. maxmin: false,
  142. area: ['600px', '400px'],
  143. content: $("#dlg-edit")
  144. }, option);
  145. layui.layer.open(opt);
  146. });
  147. }
  148. @if(Model.edit)
  149. {
  150. <text>
  151. function addDepart() {
  152. showEditDlg({
  153. title: "新增机构",
  154. btn: ["确定", "取消"],
  155. yes: function (index) {
  156. data = layui.form.getValue("editForm");
  157. $.post("/admin/user/saveDepart", data, function (rsp) {
  158. if (rsp.success) {
  159. layui.layer.close(index);
  160. layui.layer.msg("保存成功!", { time: 1500}, function () {
  161. search();
  162. });
  163. }
  164. else {
  165. layui.layer.alert(rsp.message);
  166. }
  167. });
  168. }
  169. },0);
  170. }
  171. function updateDepart(data) {
  172. showEditDlg({
  173. title: "修改机构",
  174. btn: ["确定", "取消"],
  175. success: function () {
  176. layui.form.val("editForm", data);
  177. },
  178. yes: function (index) {
  179. data = $.extend(data, layui.form.getValue("editForm"));
  180. $.post("/admin/user/saveDepart", data, function (rsp) {
  181. if (rsp.success) {
  182. layui.layer.close(index);
  183. layui.layer.msg("保存成功!", { time: 1500 }, function () {
  184. search();
  185. });
  186. }
  187. else {
  188. layui.layer.alert(rsp.message);
  189. }
  190. });
  191. }
  192. },1);
  193. }
  194. function delDepart(dp) {
  195. layui.layer.confirm("确定要删除" + dp.dpname + "吗?", function (idx) {
  196. $.get("/admin/user/DelDepart", { dpid: dp.dpid }, function (rsp) {
  197. if (rsp.success) {
  198. layui.layer.close(index);
  199. layui.layer.msg("操作成功!", { time:1500}, function () {
  200. search();
  201. });
  202. }
  203. else {
  204. layui.layer.alert(rsp.message);
  205. }
  206. });
  207. });
  208. }</text>
  209. }
  210. layui.use(["treeTable", "form", "layer", "laytpl", "upload"], function () {
  211. var layer = layui.layer;
  212. var index = layer.load(1);//开启进度条
  213. layui.treeTable.render({
  214. elem: '#departTable',//table id
  215. url: '/admin/user/SearchDepartList',
  216. method: 'POST', //方式
  217. cellMinWidth: 120,
  218. even: true, //开启隔行背景
  219. id: 'departTable',
  220. top_value: "0",
  221. primary_key: "dpid",
  222. parent_key: 'parentid',
  223. level_key: 'layer',
  224. level_start: 1,
  225. height: 'full-200',
  226. icon_key: 'dpname',
  227. is_checkbox: true,
  228. check_mode:@Model.checkMode,
  229. checked: {
  230. key: 'dpid',
  231. },
  232. open_all: true,
  233. done: function (res, curr, count) {
  234. layer.close(index);//关闭
  235. },
  236. cols: [[
  237. {
  238. key: 'dpname',
  239. title: '名称',
  240. width: "200px"
  241. },
  242. {
  243. key: 'addtime',
  244. title: '创建时间',
  245. align: 'center',
  246. width: "150px"
  247. },
  248. {
  249. key: 'remark',
  250. title: '备注',
  251. width: "200px"
  252. },
  253. {
  254. title: '操作',
  255. align: 'center',
  256. toolbar: '#toobar',
  257. width: "200px"
  258. }]]
  259. });
  260. layui.treeTable.on('tool(table)', function (obj) {
  261. var data = obj.data, layEvent = obj.event;
  262. if (layEvent === 'detail') {
  263. openDetail(data);
  264. }
  265. @if (Model.edit)
  266. {
  267. <text>if (layEvent === 'update') {
  268. updateDepart(data);
  269. }
  270. if (layEvent === 'del') {
  271. delDepart(data);
  272. }</text>
  273. }
  274. });
  275. $("#dlg-edit").data("default", layui.form.getValue("editForm"));
  276. search();
  277. });
  278. $(function () {
  279. $("#btnSearch").click(search);
  280. @if (Model.edit)
  281. {
  282. <text>$("#btnAdd").click(addDepart);</text>
  283. }
  284. });
  285. </script>
  286. </body>
  287. </html>

controller

  1. namespace Web.Admin.Controllers
  2. {
  3. /// <summary>
  4. /// 后台用户控制器类
  5. /// </summary>
  6. public partial class UserController : BaseAdminController
  7. {
  8. /// <summary>
  9. /// 部门管理
  10. /// </summary>
  11. /// <returns></returns>
  12. public ActionResult DepartList(string keyword,bool edit = true,int mode = 0)
  13. {
  14. DepartListViewModel model = new DepartListViewModel();
  15. model.keyword = keyword;
  16. model.edit = edit;
  17. model.checkMode = mode;
  18. return View(model);
  19. }
  20. /// <summary>
  21. /// 查询单位,属性结构显示
  22. /// </summary>
  23. /// <param name="keyword"></param>
  24. /// <returns></returns>
  25. public JsonResult SearchDepartList(string keyword)
  26. {
  27. return ToJson(Users.SearchDepartment(keyword), JsonRequestBehavior.AllowGet);
  28. }
  29. /// <summary>
  30. /// 获取顶级单位信息
  31. /// </summary>
  32. /// <returns></returns>
  33. public JsonResult GetTopDepartList()
  34. {
  35. return ToJson(Users.SearchDepartment(null,0), JsonRequestBehavior.AllowGet);
  36. }
  37. public JsonResult SaveDepart(SmartPig_Depart depart)
  38. {
  39. depart.addtime = DateTime.Now;
  40. depart.adduid = WorkContext.Uid;
  41. int result = Users.SaveDepart(depart);
  42. if (result == -1)
  43. {
  44. return Json(JsonResponse.Fail("父级不存在,请重新选择!"));
  45. }
  46. else if (result == -2)
  47. {
  48. return Json(JsonResponse.Fail("机构名称已存在!"));
  49. }
  50. else
  51. {
  52. return Json(JsonResponse.OK(null));
  53. }
  54. }
  55. public JsonResult DelDepart(int dpid)
  56. {
  57. int result = Users.DeleteDepart(dpid);
  58. if (result == -1)
  59. {
  60. return Json(JsonResponse.Fail("部门中有成员,不能执行删除操作!"), JsonRequestBehavior.AllowGet);
  61. }
  62. else if (result == -2)
  63. {
  64. return Json(JsonResponse.Fail("部门仓库不为空!"), JsonRequestBehavior.AllowGet);
  65. }
  66. else
  67. {
  68. return Json(JsonResponse.OK(null), JsonRequestBehavior.AllowGet);
  69. }
  70. }
  71. /// <summary>
  72. /// 输出Json格式
  73. /// </summary>
  74. /// <param name="data"></param>
  75. /// <param name="jsonRequestBehavior"></param>
  76. /// <returns></returns>
  77. protected JsonResult ToJson(object data,JsonRequestBehavior jsonRequestBehavior)
  78. {
  79. return new JsonNetResult(data, jsonRequestBehavior, CommonHelper._jsonSettings);
  80. }
  81. }
  82. }

JsonNetResult.cs(日期转换)

  1. public class JsonNetResult : JsonResult
  2. {
  3. const string JsonType = "application/json";
  4. private JsonSerializerSettings _settings = null;
  5. public JsonNetResult()
  6. {
  7. this.ContentType = "application/json";
  8. }
  9. public JsonNetResult(object data,
  10. JsonRequestBehavior jsonRequestBehavior = JsonRequestBehavior.AllowGet,
  11. JsonSerializerSettings settings = null,
  12. Encoding contentEncoding = null,
  13. string contentType = JsonType)
  14. {
  15. this.Data = data;
  16. _settings = settings;
  17. this.JsonRequestBehavior = jsonRequestBehavior;
  18. if (contentEncoding != null)
  19. {
  20. this.ContentEncoding = contentEncoding;
  21. }
  22. this.ContentType = string.IsNullOrWhiteSpace(contentType) ? JsonType : contentType;
  23. }
  24. public override void ExecuteResult(ControllerContext context)
  25. {
  26. if (context == null)
  27. throw new ArgumentNullException("context");
  28. var response = context.HttpContext.Response;
  29. response.ContentType = string.IsNullOrEmpty(ContentType) ? ContentType : JsonType;
  30. if (ContentEncoding != null)
  31. response.ContentEncoding = ContentEncoding;
  32. if (Data == null)
  33. return;
  34. // If you need special handling, you can call another form of SerializeObject below
  35. var serializedObject = JsonConvert.SerializeObject(Data, Formatting.None, _settings);
  36. response.Write(serializedObject);
  37. }
  38. }

CommonHelper.cs

  1. public static JsonSerializerSettings _jsonSettings;
  2. public static readonly System.Web.Script.Serialization.JavaScriptSerializer serializer = null;
  3. public static readonly DateTime EpochTime = new DateTime(1970,1,1);
  4. public static readonly char[] splitor = new char[] { (char)31};
  5. public static readonly char[] spaceSplitor = new char[] { ' ' };
  6. public const string Success = "SUCCESS";
  7. static CommonHelper()
  8. {
  9. IsoDateTimeConverter datetimeConverter = new IsoDateTimeConverter();
  10. datetimeConverter.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
  11. _jsonSettings = new JsonSerializerSettings();
  12. _jsonSettings.MissingMemberHandling = MissingMemberHandling.Ignore;
  13. _jsonSettings.NullValueHandling = NullValueHandling.Ignore;
  14. _jsonSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
  15. _jsonSettings.Converters.Add(datetimeConverter);
  16. serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
  17. }

treeTable.js

  1. layui.define(['jquery'], function(exports) {
  2. var MOD_NAME = 'treeTable',
  3. o = layui.jquery,
  4. tree = function() {};
  5. tree.prototype.config = function() {
  6. return {
  7. top_value: 0,
  8. primary_key: 'id',
  9. parent_key: 'pid',
  10. level_key: 'level',
  11. level_start:0,
  12. hide_class: 'layui-hide',
  13. icon: {
  14. open: 'layui-icon layui-icon-triangle-d',
  15. close: 'layui-icon layui-icon-triangle-r',
  16. left: 16,
  17. },
  18. cols: [[]],
  19. checked: {},
  20. check_mode:0,
  21. is_click_icon: false,
  22. is_checkbox: false,
  23. is_head:true
  24. };
  25. }
  26. /**
  27. * 设置列的样式
  28. * @param {object} col
  29. */
  30. function _setColStyle(col) {
  31. var style = "";
  32. col.width && (style += 'width:' + col.width + ';'), col.align && (style += 'text-align:' + col.align + ';'), style && (style = 'style="' + style + '"');
  33. col._style = style;
  34. }
  35. tree.prototype.template = function (e) {
  36. var t = this, tbody = '',
  37. is_table = o('table' + e.elem).length || !(e.is_click_icon = true),
  38. checkbox = e.is_checkbox ? '<div class="layui-unselect layui-form-checkbox cbx" lay-skin="primary"><i class="layui-icon layui-icon-ok"></i></div>' : '',
  39. checked = checkbox ? checkbox.replace('cbx', 'cbx layui-form-checked') : '',
  40. thead = checkbox && '<th style="width:28px;">' + (e.check_mode === 0 ? (o.inArray(e.top_value, e.checked.data) > -1 ? checked : checkbox) : "") + '</th>';
  41. //表头
  42. e.is_head && o.each(e.cols[0], function (index, obj) {
  43. obj._style === undefined && _setColStyle(obj);
  44. thead += '<th ' + obj._style + '>' + obj.title + '</th>';
  45. });
  46. o.each(this.data(e, e.data), function (idx, item) {
  47. var tr = '',
  48. is_checked = false,
  49. hide_class = (item[e.parent_key] == e.top_value) || (item[e.parent_key] == t.cache(e, item[e.parent_key])) ? '' : e.hide_class;
  50. // 设置每行数据层级
  51. // 设置是否为最后一级
  52. item.is_end = !e.childs[item[e.primary_key]];
  53. o.each(e.cols[0], function (index, obj) {
  54. obj._style === undefined && _setColStyle(obj);
  55. // 标记设置行checkbox选中
  56. if (e.is_checkbox && e.checked && o.inArray(item[e.checked.key], e.checked.data) > -1) {
  57. is_checked = true;
  58. }
  59. // 指定列加入开启、关闭小图标
  60. var icon = (obj.key == e.icon_key && !item.is_end) ? '<i class="' + (t.cache(e, item[e.primary_key]) ? e.icon.open : e.icon.close) + '"></i>' : '<span></span>';
  61. // 指定列小图标按照层级向后位移
  62. var left = (obj.key == e.icon_key ? (item[e.level_key] - e.level_start) * e.icon.left + 'px' : '');
  63. if (left) {
  64. icon = icon.replace('>', ' style="margin-left:' + left + ';">');
  65. }
  66. // 拼接行
  67. tr += '<td ' + obj._style + (left ? 'data-down' : '') + '>' + icon + (is_table ? '' : (is_checked ? checked : checkbox)) + (obj.template ? obj.template(item) : (obj.toolbar ? $(obj.toolbar).html() : (item[obj.key] || ""))) + '</td>';
  68. });
  69. var box = is_table ? o(is_checked ? checked : checkbox).wrap('<td style="width:28px;">').parent().prop('outerHTML') : '';
  70. tbody += '<tr class="' + hide_class + '" data-id="' + item[e.primary_key] + '" data-pid="' + item[e.parent_key] + '">' + box + tr + '</tr>';
  71. });
  72. // 处理表树和树的赋值模板
  73. var table = is_table ? '<thead><tr data-id="' + e.top_value + '">' + thead + '</tr></thead><tbody>' + tbody + '</tbody>' : tbody.replace(/<tr/g, '<ul').replace(/tr>/g, 'ul>').replace(/<td/g, '<li').replace(/td>/g, 'li>');
  74. // 确认点击图标或点击列触发展开关闭
  75. var click_btn = e.is_click_icon ? '[data-down] i:not(.layui-icon-ok)' : '[data-down]';
  76. // 模板渲染并处理点击展开收起等功能
  77. o(e.elem).html(table).off('click', click_btn).on('click', click_btn, function () {
  78. var tr = o(this).parents('[data-id]'),
  79. td = tr.find('[data-down]'),
  80. id = tr.data('id'),
  81. pid = tr.data('pid'),
  82. is_open = (td.find('i:not(.layui-icon-ok)').attr('class') == e.icon.close);
  83. if (is_open) {
  84. // 展开子级(子级出现、更改图标)
  85. td.find('i:not(.layui-icon-ok)').attr('class', e.icon.open);
  86. td.parents(e.elem).find('[data-pid=' + id + ']').removeClass(e.hide_class);
  87. t.cache(e, id, true);
  88. } else {
  89. // 关闭子级(更改图标、隐藏所有子孙级)
  90. td.find('i:not(.layui-icon-ok)').attr('class', e.icon.close);
  91. t.childs_hide(e, id);
  92. }
  93. // 设置监听展开关闭
  94. layui.event.call(this, MOD_NAME, 'tree(flex)', {
  95. elem: this,
  96. data: e.childs[pid][id],
  97. table: e.elem,
  98. is_open: is_open,
  99. })
  100. }).off('click', '.cbx').on('click', '.cbx', function () {
  101. var is_checked = o(this).toggleClass('layui-form-checked').hasClass('layui-form-checked'),
  102. tr = o(this).parents('[data-id]'),
  103. id = tr.data('id'),
  104. pid = tr.data('pid');
  105. if (e.check_mode == 0) {
  106. //默认
  107. t.childs_checkbox(e, id, is_checked);
  108. t.parents_checkbox(e, pid);
  109. }
  110. else if (e.check_mode == 1 && is_checked) {
  111. //单选
  112. o(e.elem).find(".cbx.layui-form-checked").removeClass('layui-form-checked');
  113. o(this).addClass("layui-form-checked");
  114. }
  115. // 设置监听checkbox选择
  116. layui.event.call(this, MOD_NAME, 'tree(box)', {
  117. elem: this,
  118. item: pid === undefined ? {} : e.childs[pid][id],
  119. table: e.elem,
  120. is_checked: is_checked,
  121. })
  122. }).off('click', '[lay-filter]').on('click', '[lay-filter]', function () {
  123. var tr = o(this).parents('[data-id]'),
  124. id = tr.data('id'),
  125. pid = tr.data('pid'),
  126. filter = o(this).attr("lay-filter");
  127. return layui.event.call(this, MOD_NAME, 'tree(' + filter + ')', {
  128. elem: this,
  129. data: e.childs[pid][id],
  130. })
  131. }).off('click', '[lay-event]').on('click', '[lay-event]', function () {
  132. var tr = o(this).parents('[data-id]'),
  133. filter = o(e.elem).attr("lay-filter"),
  134. id = tr.data('id'),
  135. pid = tr.data('pid'),
  136. event = o(this).attr("lay-event");
  137. return layui.event.call(this, MOD_NAME, 'tool(' + filter + ')', {
  138. elem: this,
  139. event: event,
  140. data: e.childs[pid][id],
  141. })
  142. });
  143. e.done && e.done(e);
  144. };
  145. // 同级全部选中父级选中/同级全部取消取消父级
  146. tree.prototype.parents_checkbox = function(e, pid) {
  147. var po = o(e.elem).find('[data-pid=' + pid + ']'),
  148. co = o(e.elem).find('[data-id=' + pid + ']'),
  149. len = o(e.elem).find('[data-pid=' + pid + '] .cbx.layui-form-checked').length;
  150. if(po.length == len || len == 0) {
  151. var pid = co.data('pid');
  152. len ? co.find('.cbx').addClass('layui-form-checked') : co.find('.cbx').removeClass('layui-form-checked');
  153. pid === undefined || this.parents_checkbox(e, pid);
  154. }
  155. };
  156. // 子级反选
  157. tree.prototype.childs_checkbox = function(e, id, is_checked) {
  158. var t = this;
  159. o(e.elem).find('[data-pid=' + id + ']').each(function() {
  160. var checkbox = o(this).find('.cbx');
  161. is_checked ? checkbox.addClass('layui-form-checked') : checkbox.removeClass('layui-form-checked');
  162. t.childs_checkbox(e, o(this).data('id'), is_checked);
  163. })
  164. };
  165. // 点击收起循环隐藏子级元素
  166. tree.prototype.childs_hide = function(e, id) {
  167. var t = this;
  168. this.cache(e, id, false);
  169. o(e.elem).find('[data-pid=' + id + ']:not(.' + e.hide_class + ')').each(function() {
  170. var td = o(this).find('[data-down]'),
  171. i = td.find('i:not(.layui-icon-ok)');
  172. // 关闭更换小图标
  173. i.length && i.attr('class', e.icon.close);
  174. // 隐藏子级
  175. td.parents(e.elem).find('[data-pid=' + id + ']').addClass(e.hide_class);
  176. t.childs_hide(e, o(this).data('id'))
  177. });
  178. };
  179. // 重新组合数据,父子级关系跟随
  180. tree.prototype.data = function(e) {
  181. var lists = [],
  182. childs = [];
  183. o.each(e.data, function(idx, item) {
  184. lists[item[e.primary_key]] = item;
  185. if(!childs[item[e.parent_key]]) {
  186. childs[item[e.parent_key]] = [];
  187. }
  188. childs[item[e.parent_key]][item[e.primary_key]] = item;
  189. });
  190. e.childs = childs;
  191. return this.tree_data(e, lists, e.top_value, []);
  192. };
  193. tree.prototype.tree_data = function(e, lists, pid, data) {
  194. if(lists[pid]) {
  195. data.push(lists[pid]);
  196. delete lists[pid]
  197. }
  198. var t = this;
  199. o.each(e.data, function(index, item) {
  200. if(item[e.parent_key] == pid) {
  201. data.concat(t.tree_data(e, lists, item[e.primary_key], data))
  202. }
  203. });
  204. return data;
  205. };
  206. tree.prototype.render = function(e) {
  207. var treeObj = o(e.elem).data("tree"),option = null;
  208. if(!treeObj) {
  209. treeObj = new tree();
  210. option = this.config();
  211. o(e.elem).data("tree",treeObj);
  212. }
  213. else
  214. {
  215. option = treeObj.option;
  216. }
  217. e = o.extend(option, e);
  218. treeObj.option = e;
  219. if(e.url) {
  220. if (e.method && e.method.toLowerCase() == "post") {
  221. o.post(e.url, e.where, function (res) {
  222. e.data = res;
  223. treeObj.template(e);
  224. })
  225. } else {
  226. o.get(e.url, e.where, function (res) {
  227. e.data = res;
  228. treeObj.template(e);
  229. })
  230. }
  231. } else {
  232. treeObj.template(e);
  233. }
  234. return treeObj;
  235. };
  236. // 获取已选值集合
  237. tree.prototype.checked = function(e) {
  238. var items = [];
  239. o(e.elem).find('.cbx.layui-form-checked').each(function() {
  240. var tr = o(this).parents('[data-id]'),
  241. id = tr.data('id'),
  242. pid = tr.data('pid');
  243. items.push(e.childs[pid][id]);
  244. });
  245. return items;
  246. };
  247. // 全部展开
  248. tree.prototype.openAll = function(e) {
  249. var t = this;
  250. o.each(e.data, function(idx, item) {
  251. item[e.primary_key] && t.cache(e, item[e.primary_key], true);
  252. })
  253. this.render(e);
  254. }
  255. // 全部关闭
  256. tree.prototype.closeAll = function(e) {
  257. localStorage.setItem(e.elem.substr(1), '');
  258. this.render(e);
  259. }
  260. tree.prototype.on = function(events, callback) {
  261. return layui.onevent.call(this, MOD_NAME, events, callback)
  262. };
  263. // 存储折叠状态
  264. tree.prototype.cache = function (e, val, option) {
  265. if (e.open_all) {
  266. return true;
  267. }
  268. var name = e.elem.substr(1),
  269. val = val.toString(),
  270. cache = localStorage.getItem(name) ? localStorage.getItem(name).split(',') : [],
  271. index = o.inArray(val, cache);
  272. if (option === undefined) {
  273. return index > -1;
  274. }
  275. if ((option && index > -1) || (!option && index === -1)) {
  276. return;
  277. }
  278. if(option && index == -1) {
  279. cache.push(val)
  280. }
  281. else if(!option && index > -1) {
  282. cache.splice(index, 1)
  283. }
  284. localStorage.setItem(name, cache.join(','));
  285. };
  286. tree.prototype.reload = function(id,option) {
  287. option = option || {};
  288. option.elem = "#"+id;
  289. return this.render(option);
  290. };
  291. tree.prototype.checkStatus = function(id) {
  292. var treeObj = o("#" + id).data("tree"),result = {data:[]};
  293. if(!treeObj)
  294. {
  295. return result;
  296. }
  297. return {
  298. data: treeObj.checked(treeObj.option)
  299. };
  300. };
  301. exports(MOD_NAME, new tree())
  302. });

效果:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/368692
推荐阅读
相关标签
  

闽ICP备14008679号