123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494 |
- /**
- * 树形表格 2.x
- * date:2019-11-08 License By http://easyweb.vip
- */
- layui.define(['layer', 'laytpl', 'form'], function (exports) {
- var $ = layui.jquery;
- var layer = layui.layer;
- var laytpl = layui.laytpl;
- var form = layui.form;
- var device = layui.device();
- var MOD_NAME = 'treeTable'; // 绑定事件的模块名
- // 改为同步加载css,避免滚动条补丁首次进入无效
- $.ajax({
- url: layui.cache.base + 'treetable/treeTable.css',
- async: false,
- success: function (res) {
- $('head').append('<style id="ew-tree-table-css">' + res + '</style>');
- }
- });
-
- /** TreeTable类构造方法 */
- var TreeTable = function (options) {
- // 表格默认参数
- var defaultOption = {
- elem: undefined, // table容器
- data: [], // 数据
- cols: [], // 列配置
- reqData: undefined, // 异步加载数据的方法
- width: undefined, // 容器宽度
- height: undefined, // 容器高度
- cellMinWidth: 100, // 单元格最小宽度
- skin: undefined, // 表格风格
- size: undefined, // 表格尺寸
- even: undefined, // 是否开启隔行变色
- style: undefined, // 容器样式
- getThead: function () { // 获取表头
- return getThead(this);
- },
- getAllChooseBox: function () { // 获取全选按钮
- return getAllChooseBox(this);
- },
- getColgroup: function () { // 获取colgroup
- return getColgroup(this);
- },
- getTbWidth: function () { // 计算table的宽度
- return getTbWidth(this);
- },
- tree: {},
- text: {}
- };
- // 默认tree参数
- var treeDefaultOption = {
- idName: 'id', // id的字段名
- pidName: 'pid', // pid的字段名
- childName: 'children', // children的字段名
- haveChildName: 'haveChild', // 是否有children标识的字段名
- openName: 'open', // 是否默认展开的字段名
- isPidData: false, // 是否是pid形式的数据
- iconIndex: 0, // 图标列的索引
- arrowType: undefined, // 箭头类型
- onlyIconControl: false, // 仅允许点击图标折叠
- getIcon: function (d) { // 自定义图标
- return getIcon(d, this);
- }
- };
- // 默认提示文本
- var textDefaultOption = {
- none: '<div style="padding: 18px 0;">暂无数据</div>' // 空文本提示文字
- };
- this.options = $.extend(defaultOption, options);
- this.options.tree = $.extend(treeDefaultOption, options.tree);
- this.options.text = $.extend(textDefaultOption, options.text);
- for (var i = 0; i < options.cols.length; i++) {
- // 列默认参数
- var colDefaultOption = {
- field: undefined, // 字段名
- title: undefined, // 标题
- align: undefined, // 对齐方式
- templet: undefined, // 自定义模板
- toolbar: undefined, // 工具列
- width: undefined, // 宽度
- minWidth: undefined, // 最小宽度
- type: undefined, // 列类型
- style: undefined, // 单元格样式
- class: '', // 单元格class
- singleLine: true, // 一行显示
- fixed: undefined, // 固定列
- unresize: false // 关闭拖拽列宽
- };
- this.options.cols[i] = $.extend(colDefaultOption, options.cols[i]);
- }
- this.init(); // 初始化表格
- this.bindEvents(); // 绑定事件
- };
-
- /** 初始化表格 */
- TreeTable.prototype.init = function () {
- var options = this.options;
- var tbFilter = options.elem.substring(1); // 树表格的filter
- var $elem = $(options.elem); // 原始表格
-
- // 生成树表格dom
- $elem.removeAttr('lay-filter');
- $elem.next('.ew-tree-table').remove();
- var viewHtml = '<div class="layui-form ew-tree-table" style="' + (options.style || '') + '">';
- viewHtml += ' <div class="ew-tree-table-group">';
- viewHtml += ' <div class="ew-tree-table-head">';
- viewHtml += ' <table class="layui-table"></table>';
- viewHtml += ' <div class="ew-tree-table-border bottom"></div>';
- viewHtml += ' </div>';
- viewHtml += ' <div class="ew-tree-table-box">';
- viewHtml += ' <table class="layui-table"></table>';
- viewHtml += ' <div class="ew-tree-table-loading"><i class="layui-icon layui-anim layui-anim-rotate layui-anim-loop"></i></div>';
- viewHtml += ' <div class="ew-tree-table-empty" style="display: none;">' + (options.text.none || '') + '</div>';
- viewHtml += ' </div>';
- viewHtml += ' </div>';
- viewHtml += ' <div class="ew-tree-table-border top"></div><div class="ew-tree-table-border left"></div>';
- viewHtml += ' <div class="ew-tree-table-border right"></div><div class="ew-tree-table-border bottom"></div>';
- viewHtml += ' </div>';
- $elem.after(viewHtml);
-
- // 获取各个组件
- var components = this.getComponents();
- var $view = components.$view; // 容器
- $view.attr('lay-filter', tbFilter);
- var $group = components.$group; // 表格容器
- var $tbBox = components.$tbBox; // 表格主体部分容器
- var $table = components.$table; // 主体表格
- var $headTb = components.$headTb; // 表头表格
- var $tbEmpty = components.$tbEmpty; // 空视图
- var $tbLoading = components.$tbLoading; // 空视图
-
- // 基础参数设置
- options.skin && $table.attr('lay-skin', options.skin);
- options.size && $table.attr('lay-size', options.size);
- options.even && $table.attr('lay-even', options.even);
-
- // 容器边框调整
- if (device.ie) {
- $view.find('.ew-tree-table-border.bottom').css('height', '1px');
- $view.find('.ew-tree-table-border.right').css('width', '1px');
- }
-
- // 固定宽度
- if (options.width) {
- $view.css('width', options.width);
- $headTb.parent().css('width', options.width);
- $tbBox.css('width', options.width);
- }
- // col最小宽度
- var tbWidth = options.getTbWidth();
- if (tbWidth.setWidth) {
- $table.css('width', tbWidth.minWidth);
- $headTb.css('width', tbWidth.minWidth);
- } else {
- $table.css('min-width', tbWidth.minWidth);
- $headTb.css('min-width', tbWidth.minWidth);
- }
-
- // 渲染表结构及表头
- var colgroupHtmlStr = options.getColgroup();
- var headHtmlStr = colgroupHtmlStr + '<thead>' + options.getThead() + '</thead>';
- if (options.height) { // 固定表头
- $table.html(colgroupHtmlStr + '<tbody></tbody>');
- $headTb.html(headHtmlStr);
- $table.css('margin-top', '-1px');
- if (options.height.indexOf('full-') == 0) { // 差值高度
- var h = parseFloat(options.height.substring(5));
- var cssStr = '<style>.ew-tree-table > .ew-tree-table-group > .ew-tree-table-box {';
- cssStr += ' height: ' + (getPageHeight() - h) + 'px;';
- cssStr += ' height: -moz-calc(100vh - ' + h + 'px);';
- cssStr += ' height: -webkit-calc(100vh - ' + h + 'px);';
- cssStr += ' height: calc(100vh - ' + h + 'px);';
- cssStr += ' }</style>';
- $tbBox.after(cssStr);
- $tbBox.attr('ew-tree-full', h);
- } else { // 固定高度
- $tbBox.css('height', options.height);
- }
- } else {
- $table.html(headHtmlStr + '<tbody></tbody>');
- }
- form.render('checkbox', tbFilter); // 渲染表头的表单元素
-
- // 渲染数据
- if (options.reqData) { // 异步加载
- this.renderBodyAsync();
- } else { // 一次性渲染
- if (options.data && options.data.length > 0) {
- // 处理数据
- if (options.tree.isPidData) { // pid形式数据
- options.data = treeTb.pidToChildren(options.data, options.tree.idName, options.tree.pidName, options.tree.childName);
- } else { // children形式数据
- addPidField(options.data, options.tree);
- }
- $table.children('tbody').html(this.renderBody(options.data));
- $tbLoading.hide();
- this.renderNumberCol(); // 渲染序号列
- form.render(null, tbFilter); // 渲染表单元素
- this.checkChooseAllCB(); // 联动全选框
- updateFixedTbHead($view);
- } else {
- $tbLoading.hide();
- $tbEmpty.show();
- }
- }
- };
-
- /** 绑定各项事件 */
- TreeTable.prototype.bindEvents = function () {
- var that = this;
- var options = this.options;
- var components = this.getComponents();
- var $view = components.$view;
- var $table = components.$table;
- var $tbEmpty = components.$tbEmpty;
- var tbFilter = components.tbFilter;
- var checkboxFilter = components.checkboxFilter;
- var radioFilter = components.radioFilter;
- var cbAllFilter = components.cbAllFilter;
- var $tbody = $table.children('tbody');
-
- /** 行事件公共返回对象 */
- var commonMember = function (ext) {
- var $tr = $(this);
- if (!$tr.is('tr')) {
- var $td_tr = $tr.parent('tr[data-id]');
- if ($td_tr.length > 0) {
- $tr = $td_tr;
- } else {
- $tr = $tr.parentsUntil('tr[data-id]').last().parent();
- }
- }
- var id = $tr.data('id');
- var data = getDataById(options.data, id, options.tree);
- var obj = {
- tr: $tr, // 当前行
- data: data, //当前行数据
- del: function () { // 删除行
- var indent = parseInt(this.tr.data('indent'));
- this.tr.nextAll('tr').each(function () {
- if (parseInt($(this).data('indent')) <= indent) {
- return false;
- }
- $(this).remove();
- });
- var $parentTr = this.tr.prevAll('tr');
- this.tr.remove();
- delDataById(options.data, id, options.tree);
- if (!options.data || options.data.length <= 0) {
- $tbEmpty.show();
- }
- that.renderNumberCol(); // 渲染序号列
- // 联动父级
- $parentTr.each(function () {
- var tInd = parseInt($(this).data('indent'));
- if (tInd < indent) {
- that.checkParentCB($(this));
- indent = tInd;
- }
- });
- that.checkChooseAllCB(); // 联动全选框
- },
- update: function (fields) { // 修改行
- data = $.extend(data, fields);
- var indent = parseInt(this.tr.data('indent'));
- that.renderBodyTr(data, indent, undefined, this.tr);
- form.render(null, tbFilter); // 渲染表单元素
- that.checkIndeterminateCB(); // 恢复半选框状态
- that.checkChooseAllCB(); // 联动全选框
- }
- };
- return $.extend(obj, ext);
- };
-
- // 绑定折叠展开事件
- $tbody.off('click.fold').on('click.fold', '.ew-tree-pack', function (e) {
- layui.stope(e);
- var $tr = $(this).parentsUntil('tr').last().parent();
- if ($tr.hasClass('ew-tree-table-loading')) { // 已是加载中
- return;
- }
- var haveChild = $tr.data('have-child');
- if (haveChild != true && haveChild != 'true') { // 子节点
- return;
- }
- var id = $tr.data('id');
- var isOpen = $tr.hasClass('ew-tree-table-open');
- var data = getDataById(options.data, id, options.tree);
- if (!isOpen && (!data[options.tree.childName] || data[options.tree.childName].length <= 0)) {
- that.renderBodyAsync(data, $tr);
- } else {
- toggleRow($tr);
- }
- });
-
- // 绑定lay-event事件
- $tbody.off('click.tool').on('click.tool', '*[lay-event]', function (e) {
- layui.stope(e);
- var $this = $(this);
- layui.event.call(this, MOD_NAME, 'tool(' + tbFilter + ')', commonMember.call(this, {
- event: $this.attr('lay-event')
- }));
- });
-
- // 绑定单选框事件
- form.on('radio(' + radioFilter + ')', function (data) {
- var d = getDataById(options.data, data.value, options.tree);
- that.removeAllChecked();
- d.LAY_CHECKED = true; // 同时更新数据
- layui.event.call(this, MOD_NAME, 'checkbox(' + tbFilter + ')', {checked: true, data: d, type: 'one'});
- });
-
- // 绑定复选框事件
- form.on('checkbox(' + checkboxFilter + ')', function (data) {
- var checked = data.elem.checked;
- var $cb = $(data.elem);
- var $layCb = $cb.next('.layui-form-checkbox');
- // 如果是半选状态,点击全选
- if (!checked && $layCb.hasClass('ew-form-indeterminate')) {
- checked = true;
- $cb.prop('checked', checked);
- $cb.data('indeterminate', 'false');
- $layCb.addClass('layui-form-checked');
- $layCb.removeClass('ew-form-indeterminate');
- }
- var d = getDataById(options.data, data.value, options.tree);
- d.LAY_CHECKED = checked; // 同时更新数据
- // 联动操作
- var $tr = $cb.parentsUntil('tr').last().parent();
- if (d[options.tree.childName] && d[options.tree.childName].length > 0) {
- that.checkSubCB($tr, checked); // 联动子级
- }
- var indent = parseInt($tr.data('indent'));
- $tr.prevAll('tr').each(function () {
- var tInd = parseInt($(this).data('indent'));
- if (tInd < indent) {
- that.checkParentCB($(this)); // 联动父级
- indent = tInd;
- }
- });
- that.checkChooseAllCB(); // 联动全选框
- // 回调事件
- layui.event.call(this, MOD_NAME, 'checkbox(' + tbFilter + ')', {
- checked: checked,
- data: d,
- type: 'one'
- });
- });
-
- // 绑定全选复选框事件
- form.on('checkbox(' + cbAllFilter + ')', function (data) {
- var checked = data.elem.checked;
- var $cb = $(data.elem);
- var $layCb = $cb.next('.layui-form-checkbox');
- if (!options.data || options.data.length <= 0) { // 如果数据为空
- $cb.prop('checked', false);
- $cb.data('indeterminate', 'false');
- $layCb.removeClass('layui-form-checked ew-form-indeterminate');
- return;
- }
- // 如果是半选状态,点击全选
- if (!checked && $layCb.hasClass('ew-form-indeterminate')) {
- checked = true;
- $cb.prop('checked', checked);
- $cb.data('indeterminate', 'false');
- $layCb.addClass('layui-form-checked');
- $layCb.removeClass('ew-form-indeterminate');
- }
- layui.event.call(this, MOD_NAME, 'checkbox(' + tbFilter + ')', {
- checked: checked,
- data: undefined,
- type: 'all'
- });
- that.checkSubCB($table.children('tbody'), checked); // 联动操作
- });
-
- // 绑定行单击事件
- $tbody.off('click.row').on('click.row', 'tr', function () {
- layui.event.call(this, MOD_NAME, 'row(' + tbFilter + ')', commonMember.call(this, {}));
- });
-
- // 绑定行双击事件
- $tbody.off('dblclick.rowDouble').on('dblclick.rowDouble', 'tr', function () {
- layui.event.call(this, MOD_NAME, 'rowDouble(' + tbFilter + ')', commonMember.call(this, {}));
- });
-
- // 绑定单元格点击事件
- $tbody.off('click.cell').on('click.cell', 'td', function (e) {
- var $td = $(this);
- var type = $td.data('type');
- // 判断是否是复选框、单选框列
- if (type == 'checkbox' || type == 'radio') {
- layui.stope(e);
- return;
- }
- var edit = $td.data('edit');
- var field = $td.data('field');
- if (edit) { // 开启了单元格编辑
- layui.stope(e);
- if ($tbody.find('.ew-tree-table-edit').length > 0) {
- return;
- }
- var index = $td.data('index');
- var indentSize = $td.children('.ew-tree-table-indent').length;
- var id = $td.parent().data('id');
- var d = getDataById(options.data, id, options.tree);
- if ('text' == edit || 'number' == edit) { // 文本框
- var $input = $('<input type="' + edit + '" class="layui-input ew-tree-table-edit"/>');
- $input[0].value = d[field];
- $td.append($input);
- $input.focus();
- $input.blur(function () {
- var value = $(this).val();
- if (value == d[field]) {
- $(this).remove();
- return;
- }
- var rs = layui.event.call(this, MOD_NAME, 'edit(' + tbFilter + ')', commonMember.call(this, {
- value: value,
- field: field
- }));
- if (rs == false) {
- $(this).addClass('layui-form-danger');
- $(this).focus();
- } else {
- d[field] = value; // 同步更新数据
- that.renderBodyTd(d, indentSize, index, $td); // 更新单元格
- }
- });
- } else {
- console.error('不支持的单元格编辑类型:' + edit);
- }
- } else { // 回调单元格点击事件
- var rs = layui.event.call(this, MOD_NAME, 'cell(' + tbFilter + ')', commonMember.call(this, {
- td: $td,
- field: field
- }));
- if (rs == false) {
- layui.stope(e);
- }
- }
- });
-
- // 绑定单元格双击事件
- $tbody.off('dblclick.cellDouble').on('dblclick.cellDouble', 'td', function (e) {
- var $td = $(this);
- var type = $td.data('type');
- // 判断是否是复选框、单选框列
- if (type == 'checkbox' || type == 'radio') {
- layui.stope(e);
- return;
- }
- var edit = $td.data('edit');
- var field = $td.data('field');
- if (edit) { // 开启了单元格编辑
- layui.stope(e);
- } else { // 回调单元格双击事件
- var rs = layui.event.call(this, MOD_NAME, 'cellDouble(' + tbFilter + ')', commonMember.call(this, {
- td: $td,
- field: field
- }));
- if (rs == false) {
- layui.stope(e);
- }
- }
- });
-
- // 同步滚动条
- components.$tbBox.on('scroll', function () {
- var $this = $(this);
- var scrollLeft = $this.scrollLeft();
- var scrollTop = $this.scrollTop();
- components.$headTb.parent().scrollLeft(scrollLeft);
- // $headGroup.scrollTop(scrollTop);
- });
-
- // 列宽拖拽调整
- /*$view.off('mousedown.resize').on('mousedown.resize', '.ew-tb-resize', function (e) {
- layui.stope(e);
- var index = $(this).parent().data('index');
- $(this).data('move', 'true');
- $(this).data('x', e.clientX);
- var w = $(this).parent().parent().parent().parent().children('colgroup').children('col').eq(index).attr('width');
- $(this).data('width', w);
- });
- $view.off('mousemove.resize').on('mousemove.resize', '.ew-tb-resize', function (e) {
- layui.stope(e);
- var move = $(this).data('move');
- if ('true' == move) {
- var x = $(this).data('x');
- var w = $(this).data('width');
- var index = $(this).parent().data('index');
- var nw = parseFloat(w) + e.clientX - parseFloat(x);
- $(this).parent().parent().parent().parent().children('colgroup').children('col').eq(index).attr('width', nw);
- }
- });
- $view.off('mouseup.resize').on('mouseup.resize', '.ew-tb-resize', function (e) {
- layui.stope(e);
- $(this).data('move', 'false');
- });
- $view.off('mouseleave.resize').on('mouseleave.resize', '.ew-tb-resize', function (e) {
- layui.stope(e);
- $(this).data('move', 'false');
- });*/
-
- };
-
- /** 获取各个组件 */
- TreeTable.prototype.getComponents = function () {
- var $view = $(this.options.elem).next(); // 容器
- var $group = $view.children('.ew-tree-table-group'); // 表格容器
- var $tbBox = $group.children('.ew-tree-table-box'); // 表格主体部分容器
- var $table = $tbBox.children('.layui-table'); // 主体表格
- var $headTb = $group.children('.ew-tree-table-head').children('.layui-table'); // 表头表格
- var $tbEmpty = $tbBox.children('.ew-tree-table-empty'); // 空视图
- var $tbLoading = $tbBox.children('.ew-tree-table-loading'); // 加载视图
- var tbFilter = $view.attr('lay-filter'); // 容器filter
- var checkboxFilter = 'ew_tb_checkbox_' + tbFilter; // 复选框filter
- var radioFilter = 'ew_tb_radio_' + tbFilter; // 单选框filter
- var cbAllFilter = 'ew_tb_choose_all_' + tbFilter; // 全选按钮filter
- return {
- $view: $view,
- $group: $group,
- $tbBox: $tbBox,
- $table: $table,
- $headTb: $headTb,
- $tbEmpty: $tbEmpty,
- $tbLoading: $tbLoading,
- tbFilter: tbFilter,
- checkboxFilter: checkboxFilter,
- radioFilter: radioFilter,
- cbAllFilter: cbAllFilter
- };
- };
-
- /**
- * 递归渲染表格主体部分
- * @param data 数据列表
- * @param indentSize 缩进大小
- * @param isHide 是否默认隐藏
- * @returns {string}
- */
- TreeTable.prototype.renderBody = function (data, indentSize, isHide) {
- var options = this.options;
- var treeOption = options.tree;
- indentSize || (indentSize = 0);
- var htmlStr = '';
- for (var i = 0; i < data.length; i++) {
- var d = data[i];
- htmlStr += this.renderBodyTr(d, indentSize, isHide);
- // 递归渲染子集
- var children = d[treeOption.childName];
- if (children && children.length > 0) {
- htmlStr += this.renderBody(children, indentSize + 1, !d[treeOption.openName]);
- }
- }
- return htmlStr;
- };
-
- /**
- * 渲染一行数据
- * @param d 行数据
- * @param option 配置
- * @param indentSize 缩进大小
- * @param isHide 是否隐藏
- * @param $tr
- * @returns {string}
- */
- TreeTable.prototype.renderBodyTr = function (d, indentSize, isHide, $tr) {
- var options = this.options;
- var cols = options.cols;
- var treeOption = options.tree;
- indentSize || (indentSize = 0);
- var htmlStr = '';
- var haveChild = getHaveChild(d, treeOption);
- if ($tr) {
- $tr.data('pid', d[treeOption.pidName] || '');
- $tr.data('have-child', haveChild);
- $tr.data('indent', indentSize);
- $tr.removeClass('ew-tree-table-loading');
- } else {
- var classNames = '';
- if (haveChild && d[treeOption.openName]) {
- classNames += 'ew-tree-table-open';
- }
- if (isHide) {
- classNames += 'ew-tree-tb-hide';
- }
- htmlStr += '<tr class="' + classNames + '" data-id="' + d[treeOption.idName] + '"';
- htmlStr += ' data-pid="' + (d[treeOption.pidName] || '') + '" data-have-child="' + haveChild + '"';
- htmlStr += ' data-indent="' + indentSize + '">';
- }
- for (var j = 0; j < cols.length; j++) {
- var $td;
- if ($tr) {
- $td = $tr.children('td').eq(j);
- }
- htmlStr += this.renderBodyTd(d, indentSize, j, $td);
- }
- htmlStr += '</tr>';
- return htmlStr;
- };
-
- /**
- * 渲染每一个单元格数据
- * @param d 行数据
- * @param indentSize 缩进大小
- * @param index 第几列
- * @param $td
- * @returns {string}
- */
- TreeTable.prototype.renderBodyTd = function (d, indentSize, index, $td) {
- var options = this.options;
- var col = options.cols[index];
- var treeOption = options.tree;
- var components = this.getComponents();
- var checkboxFilter = components.checkboxFilter;
- var radioFilter = components.radioFilter;
- indentSize || (indentSize = 0);
- // 内容填充
- var fieldStr = '';
- if (col.type == 'numbers') { // 序号列
- fieldStr += '<span class="ew-tree-table-numbers"></span>';
- col.singleLine = false;
- } else if (col.type == 'checkbox') { // 复选框列
- var attrStr = 'name="' + checkboxFilter + '" lay-filter="' + checkboxFilter + '" value="' + d[treeOption.idName] + '"';
- attrStr += d.LAY_CHECKED ? ' checked="checked"' : '';
- fieldStr += '<input type="checkbox" lay-skin="primary" ' + attrStr + ' class="ew-tree-table-checkbox" />';
- col.singleLine = false;
- } else if (col.type == 'radio') { // 单选框列
- var attrStr = 'name="' + radioFilter + '" lay-filter="' + radioFilter + '" value="' + d[treeOption.idName] + '"';
- attrStr += d.LAY_CHECKED ? ' checked="checked"' : '';
- fieldStr += '<input type="radio" ' + attrStr + ' class="ew-tree-table-radio" />';
- col.singleLine = false;
- } else if (col.templet) { // 自定义模板
- if (typeof col.templet == 'function') {
- fieldStr += col.templet(d);
- } else if (typeof col.templet == 'string') {
- laytpl($(col.templet).html()).render(d, function (html) {
- fieldStr += html;
- });
- }
- } else if (col.toolbar) { // 工具列
- laytpl($(col.toolbar).html()).render(d, function (html) {
- fieldStr += html;
- });
- } else if (col.field && d[col.field] != undefined && d[col.field] != null) { // 普通字段
- fieldStr += d[col.field];
- }
- var tdStr = '';
- // 图标列处理
- if (index == treeOption.iconIndex) {
- // 缩进
- for (var k = 0; k < indentSize; k++) {
- tdStr += '<span class="ew-tree-table-indent"></span>';
- }
- tdStr += '<span class="ew-tree-pack">';
- // 加箭头
- var haveChild = getHaveChild(d, treeOption);
- tdStr += ('<i class="layui-icon ew-tree-table-arrow ' + (haveChild ? '' : 'ew-tree-table-arrow-hide') + ' ' + (options.tree.arrowType || '') + '"></i>');
- // 加图标
- tdStr += treeOption.getIcon(d);
- if (options.tree.onlyIconControl) {
- tdStr += '</span>';
- tdStr += ('<span>' + fieldStr + '</span>');
- } else {
- tdStr += ('<span>' + fieldStr + '</span>');
- tdStr += '</span>';
- }
- } else {
- tdStr += fieldStr;
- }
- if ($td && col.type != 'numbers') {
- $td.html(tdStr);
- }
- var htmlStr = '<td data-index="' + index + '" ';
- col.field && (htmlStr += (' data-field="' + col.field + '"'));
- col.edit && (htmlStr += (' data-edit="' + col.edit + '"'));
- col.type && (htmlStr += (' data-type="' + col.type + '"'));
- col.align && (htmlStr += (' align="' + col.align + '"')); // 对齐方式
- col.style && (htmlStr += (' style="' + col.style + '"')); // 单元格样式
- col.class && (htmlStr += (' class="' + col.class + '"')); // 单元格样式
- htmlStr += '>';
- if (col.singleLine) {
- htmlStr += ('<div class="ew-tree-table-td-single"><i class="layui-icon layui-icon-close ew-tree-tips-c"></i><div class="ew-tree-tips">' + tdStr + '</div></div>');
- } else {
- htmlStr += tdStr;
- }
- htmlStr += '</td>';
- return htmlStr;
- };
-
- /**
- * 异步加载渲染
- * @param data 父级数据
- * @param $tr 父级dom
- */
- TreeTable.prototype.renderBodyAsync = function (d, $tr) {
- var that = this;
- var options = this.options;
- var components = this.getComponents();
- var $tbEmpty = components.$tbEmpty;
- var $tbLoading = components.$tbLoading;
- // 显示loading
- if ($tr) {
- $tr.addClass('ew-tree-table-loading');
- $tr.children('td').find('.ew-tree-pack').children('.ew-tree-table-arrow').addClass('layui-anim layui-anim-rotate layui-anim-loop');
- } else {
- if (options.data && options.data.length > 0) {
- $tbLoading.addClass('ew-loading-float');
- }
- $tbLoading.show();
- $tbEmpty.hide();
- }
- // 请求数据
- options.reqData(d, function (res) {
- if (options.tree.isPidData) {
- res = treeTb.pidToChildren(res, options.tree.idName, options.tree.pidName, options.tree.childName);
- }
- that.renderBodyData(res, d, $tr); // 渲染内容
- // 移除loading
- if ($tr) {
- $tr.removeClass('ew-tree-table-loading');
- $tr.children('td').find('.ew-tree-pack').children('.ew-tree-table-arrow').removeClass('layui-anim layui-anim-rotate layui-anim-loop');
- } else {
- $tbLoading.hide();
- $tbLoading.removeClass('ew-loading-float');
- // 是否为空
- if (!res || res.length == 0) {
- $tbEmpty.show();
- } else {
- $tbEmpty.hide();
- }
- }
- });
- };
-
- /**
- * 根据数据渲染body
- * @param data 数据集合
- * @param option 配置项
- * @param d 父级数据
- * @param $tr 父级dom
- */
- TreeTable.prototype.renderBodyData = function (data, d, $tr) {
- var that = this;
- var options = this.options;
- var components = this.getComponents();
- var $view = components.$view;
- var $table = components.$table;
- var tbFilter = components.tbFilter;
- addPidField(data, options.tree, d); // 补充pid字段
- // 更新到数据
- if (d == undefined) {
- options.data = data;
- } else {
- d[options.tree.childName] = data;
- }
- var indent;
- if ($tr) {
- indent = parseInt($tr.data('indent')) + 1;
- }
- var htmlStr = this.renderBody(data, indent);
- if ($tr) {
- // 移除旧dom
- $tr.nextAll('tr').each(function () {
- if (parseInt($(this).data('indent')) <= (indent - 1)) {
- return false;
- }
- $(this).remove();
- });
- // 渲染新dom
- $tr.after(htmlStr);
- $tr.addClass('ew-tree-table-open');
- } else {
- $table.children('tbody').html(htmlStr);
- }
- form.render(null, tbFilter); // 渲染表单元素
- this.renderNumberCol(); // 渲染序号列
- this.checkIndeterminateCB(); // 恢复复选框半选状态
- if ($tr) {
- // 更新父级复选框状态
- this.checkParentCB($tr);
- $tr.prevAll('tr').each(function () {
- var tInd = parseInt($(this).data('indent'));
- if (tInd < (indent - 1)) {
- that.checkParentCB($(this));
- indent = tInd + 1;
- }
- });
- }
- this.checkChooseAllCB(); // 联动全选框
- updateFixedTbHead($view);
- };
-
- /**
- * 联动子级复选框状态
- * @param $tr 当前tr的dom
- * @param checked
- */
- TreeTable.prototype.checkSubCB = function ($tr, checked) {
- var that = this;
- var components = this.getComponents();
- var cbFilter = components.checkboxFilter;
- var indent = -1, $trList;
- if ($tr.is('tbody')) {
- $trList = $tr.children('tr');
- } else {
- indent = parseInt($tr.data('indent'));
- $trList = $tr.nextAll('tr')
- }
- $trList.each(function () {
- if (parseInt($(this).data('indent')) <= indent) {
- return false;
- }
- var $cb = $(this).children('td').find('input[name="' + cbFilter + '"]');
- $cb.prop('checked', checked);
- if (checked) {
- $cb.data('indeterminate', 'false');
- $cb.next('.layui-form-checkbox').addClass('layui-form-checked');
- $cb.next('.layui-form-checkbox').removeClass('ew-form-indeterminate');
- } else {
- $cb.data('indeterminate', 'false');
- $cb.next('.layui-form-checkbox').removeClass('layui-form-checked ew-form-indeterminate');
- }
- that.update($(this).data('id'), {LAY_CHECKED: checked}); // 同步更新数据
- });
- };
-
- /**
- * 联动父级复选框状态
- * @param $tr 父级的dom
- */
- TreeTable.prototype.checkParentCB = function ($tr) {
- var that = this;
- var components = this.getComponents();
- var cbFilter = components.checkboxFilter;
- var indent = parseInt($tr.data('indent'));
- var ckNum = 0, unCkNum = 0;
- $tr.nextAll('tr').each(function () {
- if (parseInt($(this).data('indent')) <= indent) {
- return false;
- }
- var $cb = $(this).children('td').find('input[name="' + cbFilter + '"]');
- if ($cb.prop('checked')) {
- ckNum++;
- } else {
- unCkNum++;
- }
- });
- var $cb = $tr.children('td').find('input[name="' + cbFilter + '"]');
- if (ckNum > 0 && unCkNum == 0) { // 全选
- $cb.prop('checked', true);
- $cb.data('indeterminate', 'false');
- $cb.next('.layui-form-checkbox').addClass('layui-form-checked');
- $cb.next('.layui-form-checkbox').removeClass('ew-form-indeterminate');
- that.update($tr.data('id'), {LAY_CHECKED: true}); // 同步更新数据
- } else if (ckNum == 0 && unCkNum > 0) { // 全不选
- $cb.prop('checked', false);
- $cb.data('indeterminate', 'false');
- $cb.next('.layui-form-checkbox').removeClass('layui-form-checked ew-form-indeterminate');
- that.update($tr.data('id'), {LAY_CHECKED: false}); // 同步更新数据
- } else if (ckNum > 0 && unCkNum > 0) { // 半选
- $cb.prop('checked', true);
- $cb.data('indeterminate', 'true');
- $cb.next('.layui-form-checkbox').addClass('layui-form-checked ew-form-indeterminate');
- that.update($tr.data('id'), {LAY_CHECKED: true}); // 同步更新数据
- }
- };
-
- /** 联动全选复选框 */
- TreeTable.prototype.checkChooseAllCB = function () {
- var components = this.getComponents();
- var cbAllFilter = components.cbAllFilter;
- var cbFilter = components.checkboxFilter;
- var $tbody = components.$table.children('tbody');
- var ckNum = 0, unCkNum = 0;
- $tbody.children('tr').each(function () {
- var $cb = $(this).children('td').find('input[name="' + cbFilter + '"]');
- if ($cb.prop('checked')) {
- ckNum++;
- } else {
- unCkNum++;
- }
- });
- var $cb = $('input[lay-filter="' + cbAllFilter + '"]');
- if (ckNum > 0 && unCkNum == 0) { // 全选
- $cb.prop('checked', true);
- $cb.data('indeterminate', 'false');
- $cb.next('.layui-form-checkbox').addClass('layui-form-checked');
- $cb.next('.layui-form-checkbox').removeClass('ew-form-indeterminate');
- } else if ((ckNum == 0 && unCkNum > 0) || (ckNum == 0 && unCkNum == 0)) { // 全不选
- $cb.prop('checked', false);
- $cb.data('indeterminate', 'false');
- $cb.next('.layui-form-checkbox').removeClass('layui-form-checked ew-form-indeterminate');
- } else if (ckNum > 0 && unCkNum > 0) { // 半选
- $cb.prop('checked', true);
- $cb.data('indeterminate', 'true');
- $cb.next('.layui-form-checkbox').addClass('layui-form-checked ew-form-indeterminate');
- }
- };
-
- /** 填充序号列 */
- TreeTable.prototype.renderNumberCol = function () {
- var components = this.getComponents();
- var $tbody = components.$table.children('tbody');
- $tbody.children('tr').each(function (index) {
- $(this).children('td').find('.ew-tree-table-numbers').text(index + 1);
- });
- };
-
- /* 解决form.render之后半选框被重置的问题 */
- TreeTable.prototype.checkIndeterminateCB = function () {
- var components = this.getComponents();
- var cbFilter = components.checkboxFilter;
- $('input[lay-filter="' + cbFilter + '"]').each(function () {
- var $cb = $(this);
- if ($cb.data('indeterminate') == 'true' && $cb.prop('checked')) {
- $cb.next('.layui-form-checkbox').addClass('ew-form-indeterminate');
- }
- });
- };
-
- /**
- * 搜索数据
- * @param ids 关键字或数据id集合
- */
- TreeTable.prototype.filterData = function (ids) {
- var components = this.getComponents();
- var $trList = components.$table.children('tbody').children('tr');
- if (typeof ids == 'string') { // 关键字
- var keyword = ids;
- ids = [];
- $trList.each(function () {
- var id = $(this).data('id');
- $(this).children('td').each(function () {
- if ($(this).text().indexOf(keyword) != -1) {
- ids.push(id);
- return false;
- }
- });
- });
- }
- $trList.addClass('ew-tree-table-filter-hide');
- for (var i = 0; i < ids.length; i++) {
- var $tr = $trList.filter('[data-id="' + ids[i] + '"]');
- $tr.removeClass('ew-tree-table-filter-hide');
- // 联动父级
- var indent = parseInt($tr.data('indent'));
- $tr.prevAll('tr').each(function () {
- var tInd = parseInt($(this).data('indent'));
- if (tInd < indent) {
- $(this).removeClass('ew-tree-table-filter-hide'); // 联动父级
- if (!$(this).hasClass('ew-tree-table-open')) {
- toggleRow($(this));
- }
- indent = tInd;
- }
- });
- }
- };
-
- /** 重置搜索 */
- TreeTable.prototype.clearFilter = function () {
- var components = this.getComponents();
- var $trList = components.$table.children('tbody').children('tr');
- $trList.removeClass('ew-tree-table-filter-hide');
- };
-
- /** 展开指定行 */
- TreeTable.prototype.expand = function (id, cascade) {
- var components = this.getComponents();
- var $tr = components.$table.children('tbody').children('tr[data-id="' + id + '"]');
- if (!$tr.hasClass('ew-tree-table-open')) {
- $tr.children('td').find('.ew-tree-pack').trigger('click');
- }
- if (cascade == false) {
- return;
- }
- // 联动父级
- var indent = parseInt($tr.data('indent'));
- $tr.prevAll('tr').each(function () {
- var tInd = parseInt($(this).data('indent'));
- if (tInd < indent) {
- if (!$(this).hasClass('ew-tree-table-open')) {
- $(this).children('td').find('.ew-tree-pack').trigger('click');
- }
- indent = tInd;
- }
- });
- };
-
- /** 折叠指定行 */
- TreeTable.prototype.fold = function (id, cascade) {
- var components = this.getComponents();
- var $tr = components.$table.children('tbody').children('tr[data-id="' + id + '"]');
- if ($tr.hasClass('ew-tree-table-open')) {
- $tr.children('td').find('.ew-tree-pack').trigger('click');
- }
- if (cascade == false) {
- return;
- }
- // 联动父级
- var indent = parseInt($tr.data('indent'));
- $tr.prevAll('tr').each(function () {
- var tInd = parseInt($(this).data('indent'));
- if (tInd < indent) {
- if ($(this).hasClass('ew-tree-table-open')) {
- $(this).children('td').find('.ew-tree-pack').trigger('click');
- }
- indent = tInd;
- }
- });
- };
-
- /** 全部展开 */
- TreeTable.prototype.expandAll = function () {
- var that = this;
- var components = this.getComponents();
- var $trList = components.$table.children('tbody').children('tr');
- $trList.each(function () {
- that.expand($(this).data('id'), false);
- });
- };
-
- /** 全部折叠 */
- TreeTable.prototype.foldAll = function () {
- var that = this;
- var components = this.getComponents();
- var $trList = components.$table.children('tbody').children('tr');
- $trList.each(function () {
- that.fold($(this).data('id'), false);
- });
- };
-
- /** 获取当前数据 */
- TreeTable.prototype.getData = function () {
- return this.options.data;
- };
-
- /** 重载表格 */
- TreeTable.prototype.reload = function (opt) {
- treeTb.render($.extend(this.options, opt));
- };
-
- /** 根据id更新数据 */
- TreeTable.prototype.update = function (id, fields) {
- var data = getDataById(this.getData(), id, this.options.tree);
- $.extend(data, fields);
- };
-
- /** 根据id删除数据 */
- TreeTable.prototype.del = function (id) {
- delDataById(this.getData(), id, this.options.tree);
- };
-
- /** 获取当前选中行 */
- TreeTable.prototype.checkStatus = function (needIndeterminate) {
- (needIndeterminate == undefined) && (needIndeterminate = true);
- var that = this;
- var components = this.getComponents();
- var $table = components.$table;
- var checkboxFilter = components.checkboxFilter;
- var radioFilter = components.radioFilter;
- var list = [];
- // 获取单选框选中数据
- var $radio = $table.find('input[name="' + radioFilter + '"]');
- if ($radio.length > 0) {
- var id = $radio.filter(':checked').val();
- var d = getDataById(this.getData(), id, this.options.tree);
- if (d) {
- list.push(d);
- }
- } else { // 获取复选框数据
- $table.find('input[name="' + checkboxFilter + '"]:checked').each(function () {
- var id = $(this).val();
- var isIndeterminate = $(this).next('.layui-form-checkbox').hasClass('ew-form-indeterminate');
- if (needIndeterminate || !isIndeterminate) {
- var d = getDataById(that.getData(), id, that.options.tree);
- if (d) {
- d.isIndeterminate = isIndeterminate;
- list.push(d);
- }
- }
- });
- }
- return list;
- };
-
- /** 设置复/单选框选中 */
- TreeTable.prototype.setChecked = function (ids) {
- var components = this.getComponents();
- var $table = components.$table;
- var checkboxFilter = components.checkboxFilter;
- var radioFilter = components.radioFilter;
- var $radio = $table.find('input[name="' + radioFilter + '"]');
- if ($radio.length > 0) { // 开启了单选框
- $radio.each(function () {
- if (ids[ids.length - 1] == $(this).val()) {
- $(this).next('.layui-form-radio').trigger('click');
- return false;
- }
- });
- } else { // 开启了复选框
- $table.find('input[name="' + checkboxFilter + '"]').each(function () {
- var $cb = $(this);
- var value = $cb.val();
- var $layCb = $cb.next('.layui-form-checkbox');
- for (var i = 0; i < ids.length; i++) {
- if (value == ids[i]) {
- var checked = $cb.prop('checked');
- var indeterminate = $layCb.hasClass('ew-form-indeterminate');
- if (!checked || indeterminate) {
- $layCb.trigger('click');
- }
- }
- }
- });
- }
- };
-
- /** 移除全部选中 */
- TreeTable.prototype.removeAllChecked = function () {
- var components = this.getComponents();
- var $table = components.$table;
- var checkboxFilter = components.checkboxFilter;
- this.checkSubCB($table.children('tbody'), false);
- };
-
- /**
- * 刷新指定父级下的节点
- * @param id 父级id,空则全部刷新
- * @param data 非异步模式替换的数据
- */
- TreeTable.prototype.refresh = function (id, data) {
- if (isClass(id) == 'Array') {
- data = id;
- id = undefined;
- }
- var components = this.getComponents();
- var $table = components.$table;
- var d, $tr;
- if (id != undefined) {
- d = getDataById(this.getData(), id, this.options.tree);
- $tr = $table.children('tbody').children('tr[data-id="' + id + '"]');
- }
- if (data) { // 数据模式
- components.$tbLoading.addClass('ew-loading-float');
- components.$tbLoading.show();
- this.renderBodyData(data, d, $tr);
- components.$tbLoading.hide();
- components.$tbLoading.removeClass('ew-loading-float');
- if (data && data.length > 0) {
- components.$tbEmpty.hide();
- } else {
- components.$tbEmpty.show();
- }
- } else { // 异步模式
- this.renderBodyAsync(d, $tr);
- }
- };
-
- /** 生成表头 */
- function getThead(options) {
- var htmlStr = '<tr>';
- for (var i = 0; i < options.cols.length; i++) {
- var col = options.cols[i];
- htmlStr += '<td data-index="' + i + '" ';
- col.align && (htmlStr += ' align="' + col.align + '"'); // 对齐方式
- htmlStr += ' >';
- if (col.singleLine && col.type != 'checkbox') { // 单行显示
- htmlStr += '<div class="ew-tree-table-td-single"><i class="layui-icon layui-icon-close ew-tree-tips-c"></i><div class="ew-tree-tips">';
- }
- // 标题
- if (col.type == 'checkbox') {
- htmlStr += options.getAllChooseBox();
- } else {
- htmlStr += (col.title || '');
- }
- // 列宽拖拽
- if (!col.unresize && 'checkbox' != col.type && 'radio' != col.type && 'numbers' != col.type && 'space' != col.type) {
- htmlStr += '<span class="ew-tb-resize"></span>';
- }
- if (col.singleLine) { // 单行显示
- htmlStr += '</div></div>';
- }
- htmlStr += '</td>';
- }
- htmlStr += '</tr>';
- return htmlStr;
- }
-
- /** 生成colgroup */
- function getColgroup(options) {
- var htmlStr = '<colgroup>';
- for (var i = 0; i < options.cols.length; i++) {
- var col = options.cols[i];
- htmlStr += '<col ';
- // 设置宽度
- if (col.width) {
- htmlStr += 'width="' + col.width + '"'
- } else if (col.type == 'space') { // 空列
- htmlStr += 'width="15"'
- } else if (col.type == 'numbers') { // 序号列
- htmlStr += 'width="40"'
- } else if (col.type == 'checkbox' || col.type == 'radio') { // 复/单选框列
- htmlStr += 'width="48"'
- }
- htmlStr += ' />';
- }
- htmlStr += '</colgroup>';
- return htmlStr;
- }
-
- /** 计算table宽度 */
- function getTbWidth(options) {
- var minWidth = 0, setWidth = true;
- for (var i = 0; i < options.cols.length; i++) {
- var col = options.cols[i];
- if (col.type == 'space') { // 空列
- minWidth += 15;
- } else if (col.type == 'numbers') { // 序号列
- minWidth += 40;
- } else if (col.type == 'checkbox' || col.type == 'radio') { // 复/单选框列
- minWidth += 48;
- } else if (!col.width || /\d+%$/.test(col.width)) { // 列未固定宽度
- setWidth = false;
- if (col.minWidth) {
- minWidth += col.minWidth;
- } else if (options.cellMinWidth) {
- minWidth += options.cellMinWidth;
- }
- } else { // 列固定宽度
- minWidth += col.width;
- }
- }
- return {minWidth: minWidth, setWidth: setWidth};
- }
-
- /** 生成全选按钮 */
- function getAllChooseBox(options) {
- var tbFilter = $(options.elem).next().attr('lay-filter');
- var cbAllFilter = 'ew_tb_choose_all_' + tbFilter;
- return '<input type="checkbox" lay-filter="' + cbAllFilter + '" lay-skin="primary" class="ew-tree-table-checkbox"/>';
- }
-
- /** 获取列图标 */
- function getIcon(d, treeOption) {
- if (getHaveChild(d, treeOption)) {
- return '<i class="ew-tree-icon layui-icon layui-icon-layer"></i>';
- } else {
- return '<i class="ew-tree-icon layui-icon layui-icon-file"></i>';
- }
- }
-
- /** 折叠/展开行 */
- function toggleRow($tr) {
- var indent = parseInt($tr.data('indent'));
- var isOpen = $tr.hasClass('ew-tree-table-open');
- if (isOpen) { // 折叠
- $tr.removeClass('ew-tree-table-open');
- $tr.nextAll('tr').each(function () {
- if (parseInt($(this).data('indent')) <= indent) {
- return false;
- }
- $(this).addClass('ew-tree-tb-hide');
- });
- } else { // 展开
- $tr.addClass('ew-tree-table-open');
- var hideInd;
- $tr.nextAll('tr').each(function () {
- var ind = parseInt($(this).data('indent'));
- if (ind <= indent) {
- return false;
- }
- if (hideInd != undefined && ind > hideInd) {
- return true;
- }
- $(this).removeClass('ew-tree-tb-hide');
- if (!$(this).hasClass('ew-tree-table-open')) {
- hideInd = parseInt($(this).data('indent'));
- } else {
- hideInd = undefined;
- }
- });
- }
- updateFixedTbHead($tr.parent().parent().parent().parent().parent());
- }
-
- /** 固定表头滚动条补丁 */
- function updateFixedTbHead($view) {
- var $group = $view.children('.ew-tree-table-group');
- var $headBox = $group.children('.ew-tree-table-head');
- var $tbBox = $group.children('.ew-tree-table-box');
- var sWidth = $tbBox.width() - $tbBox.prop('clientWidth');
- if (sWidth > 0) {
- $headBox.css('border-right', sWidth + 'px solid #f2f2f2');
- } else {
- $headBox.css('border-right', 'none');
- }
- }
-
- // 监听窗口大小改变
- $(window).resize(function () {
- $('.ew-tree-table').each(function () {
- updateFixedTbHead($(this));
- var $tbBox = $(this).children('.ew-tree-table-group').children('.ew-tree-table-box');
- var full = $tbBox.attr('ew-tree-full');
- if (full && device.ie && device.ie < 10) {
- $tbBox.css('height', getPageHeight() - full);
- }
- });
- });
-
- // 表格溢出点击展开功能
- $(document).on('mouseenter', '.ew-tree-table td', function () {
- var $tdSingle = $(this).children('.ew-tree-table-td-single');
- var $content = $tdSingle.children('.ew-tree-tips');
- if ($tdSingle.length > 0 && $content.prop('scrollWidth') > $content.outerWidth()) {
- $(this).append('<div class="layui-table-grid-down"><i class="layui-icon layui-icon-down"></i></div>');
- }
- }).on('mouseleave', '.ew-tree-table td', function () {
- $(this).children('.layui-table-grid-down').remove();
- });
- // 点击箭头展开
- $(document).on('click', '.ew-tree-table td>.layui-table-grid-down', function (e) {
- hideAllTdTips();
- var $tdSingle = $(this).parent().children('.ew-tree-table-td-single');
- $tdSingle.addClass('ew-tree-tips-open');
- var $box = $tdSingle.parents().filter('.ew-tree-table-box');
- if ($box.length <= 0) {
- $box = $tdSingle.parents().filter('.ew-tree-table-head');
- }
- if (($tdSingle.outerWidth() + $tdSingle.parent().offset().left) > $box.offset().left + $box.outerWidth()) {
- $tdSingle.addClass('ew-show-left');
- }
- if (($tdSingle.outerHeight() + $tdSingle.parent().offset().top) > $box.offset().top + $box.outerHeight()) {
- $tdSingle.addClass('ew-show-bottom');
- }
- e.stopPropagation();
- });
- // 点击关闭按钮关闭
- $(document).on('click', '.ew-tree-table .ew-tree-tips-c', function (e) {
- hideAllTdTips();
- });
- // 点击空白部分关闭
- $(document).on('click', function () {
- hideAllTdTips();
- });
- $(document).on('click', '.ew-tree-table-td-single.ew-tree-tips-open', function (e) {
- e.stopPropagation();
- });
-
- /* 关闭所有单元格溢出提示框 */
- function hideAllTdTips() {
- var $single = $('.ew-tree-table-td-single');
- $single.removeClass('ew-tree-tips-open');
- $single.removeClass('ew-show-left');
- }
-
- /** 判断是否还有子节点 */
- function getHaveChild(d, treeOption) {
- var haveChild = false;
- if (d[treeOption.haveChildName] != undefined) {
- haveChild = d[treeOption.haveChildName];
- haveChild = haveChild == true || haveChild == 'true';
- } else if (d[treeOption.childName]) {
- haveChild = d[treeOption.childName].length > 0;
- }
- return haveChild;
- }
-
- /** 补充pid字段 */
- function addPidField(data, treeOption, parent) {
- for (var i = 0; i < data.length; i++) {
- if (parent) {
- data[i][treeOption.pidName] = parent[treeOption.idName];
- }
- if (data[i][treeOption.childName] && data[i][treeOption.childName].length > 0) {
- addPidField(data[i][treeOption.childName], treeOption, data[i]);
- }
- }
- }
-
- /** 根据id获取数据 */
- function getDataById(data, id, treeOption) {
- for (var i = 0; i < data.length; i++) {
- if (data[i][treeOption.idName] == id) {
- return data[i];
- }
- if (data[i][treeOption.childName] && data[i][treeOption.childName].length > 0) {
- var d = getDataById(data[i][treeOption.childName], id, treeOption);
- if (d != undefined) {
- return d;
- }
- }
- }
- }
-
- /** 根据id删除数据 */
- function delDataById(data, id, treeOption) {
- for (var i = 0; i < data.length; i++) {
- if (data[i][treeOption.idName] == id) {
- data.splice(i, 1);
- return true;
- }
- if (data[i][treeOption.childName] && data[i][treeOption.childName].length > 0) {
- var rs = delDataById(data[i][treeOption.childName], id, treeOption);
- if (rs) {
- return true;
- }
- }
- }
- }
-
- /** 获取顶级的pId */
- function getPids(list, idName, pidName) {
- var pids = [];
- for (var i = 0; i < list.length; i++) {
- var hasPid = false;
- for (var j = 0; j < list.length; j++) {
- if (i != j && list[j][idName] == list[i][pidName]) {
- hasPid = true;
- }
- }
- if (!hasPid) {
- pids.push(list[i][pidName]);
- }
- }
- return pids;
- }
-
- /** 判断pId是否相等 */
- function pidEquals(pId, pIds) {
- if (isClass(pIds) == 'Array') {
- for (var i = 0; i < pIds.length; i++) {
- if (pId == pIds[i]) {
- return true;
- }
- }
- } else {
- return pId == pIds;
- }
- return false;
- }
-
- /** 获取变量类型 */
- function isClass(o) {
- if (o === null)
- return 'Null';
- if (o === undefined)
- return 'Undefined';
- return Object.prototype.toString.call(o).slice(8, -1);
- }
-
- /* 获取浏览器高度 */
- function getPageHeight() {
- return document.documentElement.clientHeight || document.body.clientHeight;
- }
-
- /* 获取浏览器宽度 */
- function getPageWidth() {
- return document.documentElement.clientWidth || document.body.clientWidth;
- }
-
- /** 对外提供的方法 */
- var treeTb = {
- /* 渲染 */
- render: function (options) {
- return new TreeTable(options);
- },
- /* 事件监听 */
- on: function (events, callback) {
- return layui.onevent.call(this, MOD_NAME, events, callback);
- },
- /* pid转children形式 */
- pidToChildren: function (data, idName, pidName, childName, pId) {
- childName || (childName = 'children');
- var newList = [];
- for (var i = 0; i < data.length; i++) {
- (pId == undefined) && (pId = getPids(data, idName, pidName));
- if (pidEquals(data[i][pidName], pId)) {
- var children = this.pidToChildren(data, idName, pidName, childName, data[i][idName]);
- (children.length > 0) && (data[i][childName] = children);
- newList.push(data[i]);
- }
- }
- return newList;
- }
- };
-
- exports('treeTable', treeTb);
- });
|