')
- } else if (child.show === 3) {
- //不限制宽度
- tables.push('">')
- } else {
- if (child.childWidth === 'full') {
- //不限制宽度
- tables.push('">')
- } else {
- // 如果有滚动条
- if ($tableMain.prop('scrollHeight') + (children.length > 0 ? children[0].height : 0) > $tableMain.height()) {
- scrollWidth = this.getScrollWidth();
- }
- var maxWidth = $tableMain.width() - 1 - scrollWidth;
- tables.push('max-width: ' + (maxWidth > $tableHead.width() ? $tableHead.width() : maxWidth) + 'px">')
- }
- }
- if (isTpl) {
- tables.push(tplContent)
- } else {
- if (child.show !== 3 && (typeof child.childTitle === 'undefined' || child.childTitle)) {
- tables.push('
')
- }
- if (child.show === 3) {
- tables.push('
');
- return tables.join('')
- },
- /**
- * 渲染子表
- * @param _this
- * @param data 父表当前行数据
- * @param child 子表列
- * @param myTable 父表配置
- * @param children 子表配置
- * @param icon 自定义图标
- */
- renderTable: function (_this, data, child, myTable, children, icon) {
- var tables = []
- , _that = this
- , tableId = myTable.id
- , rowTableId = tableId + $(_this).parents('tr:eq(0)').data('index');
-
- if (child.lazy) {
- tables.push(renderChildTable(_that, _this, data, child, myTable, 0, children, icon));
- } else {
- for (var i = 0; i < children.length; i++) {
- tables.push(renderChildTable(_that, _this, data, child, myTable, i, children, icon));
- }
- }
- tableChildren[rowTableId] = tables;
-
-
- layui.element.on('tab(table-child-tab-' + rowTableId + ')', function (tabData) {
- if (child.lazy) {
- var isRender = false; // 是否已经渲染
- for (i = 0; i < tableChildren[rowTableId].length; i++) {
- if (tableChildren[rowTableId][i].config.id === (rowTableId + tabData.index)) {
- isRender = true;
- break;
- }
- }
- if (!isRender) {
- tableChildren[rowTableId].push(renderChildTable(_that, _this, data, child, myTable, tabData.index, children))
- }
- }
-
- var rowIndex = $(_this).parents('tr:eq(0)').data('index'),
- height = $(tabData.elem).height();
-
- $(_this).parents('.layui-table-box:eq(0)').children('.layui-table-body').children('table').children('tbody').children('tr[data-index=' + rowIndex + ']').next().children().children('.soul-table-child-patch').css('height', height)
- $(_this).parents('.layui-table-box:eq(0)').children('.layui-table-fixed').children('.layui-table-body').children('table').children('tbody').children('tr[data-index=' + rowIndex + ']').next().children().children('.soul-table-child-patch').css('height', height)
- table.resize(tableId)
-
- });
-
-
- function renderChildTable(_that, _this, data, child, myTable, i, children, icon) {
- var param = _that.deepClone(children[i]), thisTableChild,
- tableId = myTable.id,
- rowIndex = $(_this).parents('tr:eq(0)').data('index'),
- childTableId = tableId + rowIndex + i,
- $table = $(myTable.elem),
- $tableBox = $table.next().children('.layui-table-box'),
- $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table')),
- tr = $tableBody.children('tbody').children('tr[data-index="' + rowIndex + '"]'),
- row = table.cache[tableId][rowIndex],
- // 父表当前行对象
- pobj = {
- data: row,
- tr: tr,
- del: function () {
- table.cache[tableId][rowIndex] = [];
- _that.destroyChildren(rowIndex, myTable, icon)
- tr.remove();
- table.resize(tableId);
- },
- update: function (fields) {
- fields = fields || {};
- layui.each(fields, function (key, value) {
- if (key in row) {
- var templet, td = tr.children('td[data-field="' + key + '"]');
- row[key] = value;
- table.eachCols(tableId, function (i, item2) {
- if (item2.field == key && item2.templet) {
- templet = item2.templet;
- }
- });
- td.children('.layui-table-cell').html(function () {
- return templet ? function () {
- return typeof templet === 'function'
- ? templet(row)
- : laytpl($(templet).html() || value).render(row)
- }() : value;
- }());
- td.data('content', value);
- }
- });
- },
- close: function () {
- _that.destroyChildren(rowIndex, myTable, icon)
- table.resize(tableId);
- }
-
- };
- param.id = childTableId;
- param.elem = '#' + childTableId;
- typeof param.where === 'function' && (param.where = param.where(data));
- typeof param.data === 'function' && (param.data = param.data(data));
- typeof param.url === 'function' && (param.url = param.url(data));
- thisTableChild = table.render(param);
- if (!child.lazy && i !== 0) {
- $('#' + childTableId).parents('.layui-tab-item:eq(0)').removeClass('layui-show'); //解决隐藏时计算表格高度有问题
- }
- // 绑定 checkbox 事件
- if (typeof param.checkboxEvent === 'function') {
- table.on('checkbox(' + childTableId + ')', function (obj) {
- param.checkboxEvent(_that.commonMember.call(this, _that, param, obj), pobj)
- })
- }
- // 绑定 edit 事件
- if (typeof param.editEvent === 'function') {
- table.on('edit(' + childTableId + ')', function (obj) {
- param.editEvent(_that.commonMember.call(this, _that, param, obj), pobj)
- })
- }
- // 绑定 tool 事件
- if (typeof param.toolEvent === 'function') {
- table.on('tool(' + childTableId + ')', function (obj) {
- param.toolEvent(_that.commonMember.call(this, _that, param, obj), pobj)
- })
- }
- // 绑定 toolbar 事件
- if (typeof param.toolbarEvent === 'function') {
- table.on('toolbar(' + childTableId + ')', function (obj) {
- param.toolbarEvent(_that.commonMember.call(this, _that, param, obj), pobj)
- })
- }
- // 绑定单击行事件
- if (typeof param.rowEvent === 'function') {
- table.on('row(' + childTableId + ')', function (obj) {
- param.rowEvent(_that.commonMember.call(this, _that, param, obj), pobj)
- })
- }
- // 绑定双击行事件
- if (typeof param.rowDoubleEvent === 'function') {
- table.on('rowDouble(' + childTableId + ')', function (obj) {
- param.rowDoubleEvent(_that.commonMember.call(this, _that, param, obj), pobj)
- })
- }
- return thisTableChild;
- }
- },
- destroyChildren: function (rowIndex, myTable, icon) {
- var tableId = myTable.id,
- $table = $(myTable.elem),
- $tableBox = $table.next().children('.layui-table-box'),
- $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table'),
- $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody),
- $tr = $tableBody.children('tbody').children('tr[data-index="' + rowIndex + '"]'),
- isTpl = $tr.next().data('tpl');
-
- $tr.find('.childTable').removeClass(icon[1]).addClass(icon[0]);
-
- // 暂时不处理 rowspan 情况
- // var rowspanIndex = $this.parents('td:eq(0)').attr("rowspan");
- // if(rowspanIndex){
- // var index=$this.parents('tr:eq(0)').index()+parseInt(rowspanIndex);
- // $this.parents('table:eq(0)').children().children('tr:eq('+index+')').remove()
- // }else{
- // $this.parents('tr:eq(0)').next().remove();
- // }
- $tr.next().remove()
- if (isTpl === 'false') {
- var tables = tableChildren[tableId + rowIndex];
- if (layui.tableFilter) { //如果使用了筛选功能,同时清理筛选渲染的数据
- layui.tableFilter.destroy(tables);
- }
- if (layui.soulTable) { // 清除记忆
- for (var i = 0; i < tableChildren[tableId + rowIndex].length; i++) {
- layui.soulTable.clearOriginCols(tableChildren[tableId + rowIndex][i].config.id)
- }
- }
- }
- delete tableChildren[tableId + rowIndex]
-
- },
- cloneJSON: function (obj) {
- var JSON_SERIALIZE_FIX = {
- PREFIX: "[[JSON_FUN_PREFIX_",
- SUFFIX: "_JSON_FUN_SUFFIX]]"
- };
- var sobj = JSON.stringify(obj, function (key, value) {
- if (typeof value === 'function') {
- return JSON_SERIALIZE_FIX.PREFIX + value.toString() + JSON_SERIALIZE_FIX.SUFFIX;
- }
- return value;
- });
- return JSON.parse(sobj, function (key, value) {
- if (typeof value === 'string' &&
- value.indexOf(JSON_SERIALIZE_FIX.SUFFIX) > 0 && value.indexOf(JSON_SERIALIZE_FIX.PREFIX) === 0) {
- return eval("(" + value.replace(JSON_SERIALIZE_FIX.PREFIX, "").replace(JSON_SERIALIZE_FIX.SUFFIX, "") + ")");
- }
- return value;
- }) || {};
- },
- fixHoverStyle: function (myTable) {
- var $table = $(myTable.elem)
- , $tableBody = $table.next().children('.layui-table-box').children('.layui-table-body').children('table')
- ,
- $tableFixed = $table.next().children('.layui-table-box').children('.layui-table-fixed').children('.layui-table-body').children('table')
- , style = $table.next().find('style')[0],
- sheet = style.sheet || style.styleSheet || {};
- // 屏蔽掉layui原生 hover 样式
- this.addCSSRule(sheet, '.layui-table-hover', 'background-color: inherit');
- this.addCSSRule(sheet, '.layui-table-hover.soul-table-hover', 'background-color: #F2F2F2');
- $.merge($tableFixed.children('tbody').children('tr'), $tableBody.children('tbody').children('tr'))
- .on('mouseenter', function () {
- var othis = $(this)
- , index = $(this).data('index');
- if (othis.data('off')) return;
- $tableFixed.children('tbody').children('tr[data-index=' + index + ']').addClass(ELEM_HOVER);
- $tableBody.children('tbody').children('tr[data-index=' + index + ']').addClass(ELEM_HOVER);
- }).on('mouseleave', function () {
- var othis = $(this)
- , index = $(this).data('index');
- if (othis.data('off')) return;
- $tableFixed.children('tbody').children('tr[data-index=' + index + ']').removeClass(ELEM_HOVER);
- $tableBody.children('tbody').children('tr[data-index=' + index + ']').removeClass(ELEM_HOVER);
- })
- },
- addCSSRule: function (sheet, selector, rules, index) {
- if ('insertRule' in sheet) {
- sheet.insertRule(selector + '{' + rules + '}', index)
- } else if ('addRule' in sheet) {
- sheet.addRule(selector, rules, index)
- }
- },
- // 深度克隆-不丢失方法
- deepClone: function (obj) {
- var newObj = Array.isArray(obj) ? [] : {}
- if (obj && typeof obj === "object") {
- for (var key in obj) {
- if (obj.hasOwnProperty(key)) {
- newObj[key] = (obj && typeof obj[key] === 'object') ? this.deepClone(obj[key]) : obj[key];
- }
- }
- }
- return newObj
- },
- getCompleteCols: function (origin) {
- var cols = this.deepClone(origin);
- var i, j, k, cloneCol;
- for (i = 0; i < cols.length; i++) {
- for (j = 0; j < cols[i].length; j++) {
- if (!cols[i][j].exportHandled) {
- if (cols[i][j].rowspan > 1) {
- cloneCol = this.deepClone(cols[i][j])
- cloneCol.exportHandled = true;
- k = i + 1;
- while (k < cols.length) {
- cols[k].splice(j, 0, cloneCol)
- k++
- }
- }
- if (cols[i][j].colspan > 1) {
- cloneCol = this.deepClone(cols[i][j])
- cloneCol.exportHandled = true;
- for (k = 1; k < cols[i][j].colspan; k++) {
- cols[i].splice(j, 0, cloneCol)
- }
- j = j + parseInt(cols[i][j].colspan) - 1
- }
- }
- }
- }
- return cols[cols.length - 1];
- },
- getScrollWidth: function (elem) {
- var width = 0;
- if (elem) {
- width = elem.offsetWidth - elem.clientWidth;
- } else {
- elem = document.createElement('div');
- elem.style.width = '100px';
- elem.style.height = '100px';
- elem.style.overflowY = 'scroll';
-
- document.body.appendChild(elem);
- width = elem.offsetWidth - elem.clientWidth;
- document.body.removeChild(elem);
- }
- return width;
- },
- //解析自定义模板数据
- parseTempData: function (item3, content, tplData, text) { //表头数据、原始内容、表体数据、是否只返回文本
- var str = item3.children ? function () {
- return typeof item3.children === 'function'
- ? item3.children(tplData)
- : laytpl($(item3.children).html() || String(content)).render(tplData)
- }() : content;
- return text ? $('
').text() : str;
- },
- commonMember: function (_this, myTable, sets) {
- var othis = $(this)
- , tableId = myTable.id
- , $table = $(myTable.elem)
- , $tableBox = $table.next().children('.layui-table-box')
- , $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table')
- , $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody)
- , index = othis[0].tagName === 'TR' ? $(this).data('index') : othis.parents('tr:eq(0)').data('index')
- , tr = $tableBody.children('tbody').children('tr[data-index="' + index + '"]')
- , data = table.cache[tableId] || [];
-
-
- data = data[index] || {};
-
- return $.extend(sets, {
- tr: tr //行元素
- , oldValue: othis.prev() ? othis.prev().text() : null
- , del: function () { //删除行数据
- table.cache[tableId][index] = [];
- tr.remove();
- _this.scrollPatch(myTable);
- }
- , update: function (fields) { //修改行数据
- fields = fields || {};
- layui.each(fields, function (key, value) {
- if (key in data) {
- var templet, td = tr.children('td[data-field="' + key + '"]');
- data[key] = value;
- table.eachCols(tableId, function (i, item2) {
- if (item2.field == key && item2.templet) {
- templet = item2.templet;
- }
- });
- td.children('.layui-table-cell').html(_this.parseTempData({
- templet: templet
- }, value, data));
- td.data('content', value);
- }
- });
- }
- });
- },
- scrollPatch: function (myTable) {
- var $table = $(myTable.elem),
- layHeader = $table.next().children('.layui-table-box').children('.layui-table-header'),
- layTotal = $table.next().children('.layui-table-total'),
- layMain = $table.next().children('.layui-table-box').children('.layui-table-main'),
- layFixed = $table.next().children('.layui-table-box').children('.layui-table-fixed'),
- layFixRight = $table.next().children('.layui-table-box').children('.layui-table-fixed-r'),
- layMainTable = layMain.children('table'),
- scollWidth = layMain.width() - layMain.prop('clientWidth'),
- scollHeight = layMain.height() - layMain.prop('clientHeight'),
- outWidth = layMainTable.outerWidth() - layMain.width() //表格内容器的超出宽度
-
- //添加补丁
- , addPatch = function (elem) {
- if (scollWidth && scollHeight) {
- elem = elem.eq(0);
- if (!elem.find('.layui-table-patch')[0]) {
- var patchElem = $('
'); //补丁元素
- patchElem.find('div').css({
- width: scollWidth
- });
- elem.find('tr').append(patchElem);
- }
- } else {
- elem.find('.layui-table-patch').remove();
- }
- }
-
- addPatch(layHeader);
- addPatch(layTotal);
-
- //固定列区域高度
- var mainHeight = layMain.height()
- , fixHeight = mainHeight - scollHeight;
- layFixed.find('.layui-table-body').css('height', layMainTable.height() >= fixHeight ? fixHeight : 'auto');
-
- //表格宽度小于容器宽度时,隐藏固定列
- layFixRight[outWidth > 0 ? 'removeClass' : 'addClass'](HIDE);
-
- //操作栏
- layFixRight.css('right', scollWidth - 1);
+ // 修复hover样式
+ _this.fixHoverStyle(myTable)
+ // 获取子表配置信息
+ for (i = 0; i < columns.length; i++) {
+ if (columns[i].children && columns[i].children.length > 0) {
+ childIndex.push(i);
}
- };
+ }
+ if (typeof $table.attr('lay-filter') === 'undefined') {
+ $table.attr('lay-filter', tableId);
+ }
+ // 绑定一下主表事件
+ if ($table.parents('.childTr').length === 0) {
+ // 行单击事件
+ if (typeof myTable.rowEvent === 'function') {
+ table.on('row(' + $table.attr('lay-filter') + ')', function (obj) {
+ myTable.rowEvent(_this.commonMember.call(this, _this, myTable, obj));
+ })
+ }
+ // 行双击事件
+ if (typeof myTable.rowDoubleEvent === 'function') {
+ table.on('rowDouble(' + $table.attr('lay-filter') + ')', function (obj) {
+ myTable.rowDoubleEvent(_this.commonMember.call(this, _this, myTable, obj));
+ })
+ }
+ // 绑定 checkbox 事件
+ if (typeof myTable.checkboxEvent === 'function') {
+ table.on('checkbox(' + $table.attr('lay-filter') + ')', function (obj) {
+ myTable.checkboxEvent(_this.commonMember.call(this, _this, myTable, obj));
+ })
+ }
+ // 绑定 edit 事件
+ if (typeof myTable.editEvent === 'function') {
+ table.on('edit(' + $table.attr('lay-filter') + ')', function (obj) {
+ myTable.editEvent(_this.commonMember.call(this, _this, myTable, obj));
+ })
+ }
+ // 绑定 tool 事件
+ if (typeof myTable.toolEvent === 'function') {
+ table.on('tool(' + $table.attr('lay-filter') + ')', function (obj) {
+ myTable.toolEvent(_this.commonMember.call(this, _this, myTable, obj));
+ })
+ }
+ // 绑定 toolbar 事件
+ if (typeof myTable.toolbarEvent === 'function') {
+ table.on('toolbar(' + $table.attr('lay-filter') + ')', function (obj) {
+ myTable.toolbarEvent(_this.commonMember.call(this, _this, myTable, obj));
+ })
+ }
+ }
- // 输出
- exports('tableChild', mod);
+ if (childIndex.length > 0) {
+ for (i = 0; i < childIndex.length; i++) {
+ (function f() {
+ var child = columns[childIndex[i]]
+ , curIndex = childIndex[i]
+ , icon = child.icon || ['layui-icon layui-icon-right', 'layui-icon layui-icon-down'];
+
+ if (soulSort && !(myTable.url && myTable.page)) {
+ // 前台排序
+ table.on('sort(' + $table.attr('lay-filter') + ')', function () {
+ _this.render(myTable)
+ });
+ }
+
+ if (child.isChild && typeof child.isChild === 'function') {
+ $tableBody.find('tr').find('td[data-key$="' + child.key + '"]>div').each(function () {
+ if (child.isChild(layui.table.cache[tableId][$(this).parents('tr:eq(0)').data('index')])) {
+ if (child.field) {
+ $(this).prepend('
');
+ }
+ }
+ })
+ } else {
+ if (child.field) {
+ $tableBody.find('tr').find('td[data-key$="' + child.key + '"]>div').prepend('
');
+ } else {
+ $tableBody.find('tr').find('td[data-key$="' + child.key + '"]>div').html('
');
+ }
+ }
+
+ $tableBody.children('tbody').children('tr').each(function () {
+ $(this).children('td:eq(' + curIndex + ')').find('.childTable').on('click', function (e) {
+ layui.stope(e)
+ var rowIndex = $(this).parents('tr:eq(0)').data('index'),
+ tableId = myTable.id,
+ key = $(this).parents('td:eq(0)').data('key'),
+ $this = $noFixedBody.children('tbody').children('tr[data-index=' + rowIndex + ']').children('td[data-key="' + key + '"]').find('.childTable:eq(0)'),
+ $fixedThis = $fixedBody.find('tr[data-index=' + rowIndex + ']').children('td[data-key="' + key + '"]').find('.childTable:eq(0)'),
+ data = table.cache[tableId][rowIndex],
+ children = child.children,
+ isTpl = false,
+ tplContent = '',
+ tr = $tableBody.children('tbody').children('tr[data-index="' + rowIndex + '"]'),
+ obj = {
+ data: data,
+ tr: tr,
+ del: function () {
+ table.cache[tableId][rowIndex] = [];
+ _this.destroyChildren(rowIndex, myTable, icon)
+ tr.remove();
+ table.resize(tableId);
+ },
+ update: function (fields) {
+ fields = fields || {};
+ layui.each(fields, function (key, value) {
+ if (key in data) {
+ var templet, td = tr.children('td[data-field="' + key + '"]');
+ data[key] = value;
+ table.eachCols(tableId, function (i, item2) {
+ if (item2.field == key && item2.templet) {
+ templet = item2.templet;
+ }
+ });
+ td.children('.layui-table-cell').html(function () {
+ return templet ? function () {
+ return typeof templet === 'function'
+ ? templet(data)
+ : laytpl($(templet).html() || value).render(data)
+ }() : value;
+ }());
+ td.data('content', value);
+ }
+ });
+ },
+ close: function () {
+ _this.destroyChildren(rowIndex, myTable, icon)
+ table.resize(tableId);
+ }
+
+ };
+ if ($this.hasClass(icon[1])) {
+ if (typeof child.childClose === 'function') {
+ if (child.childClose(obj) === false) {
+ return;
+ }
+ }
+ } else {
+ // 展开事件
+ if (typeof child.childOpen === 'function') {
+ if (child.childOpen(obj) === false) {
+ return;
+ }
+ }
+ }
+
+ if (typeof children === 'function') {
+ children = children(data)
+ }
+ // 如果是 templet 自定义内容
+ if (typeof children === 'string') {
+ isTpl = true
+ tplContent = _this.parseTempData(child, child.field ? data[child.field] : null, data)
+ }
+ if (child.show === 2) { // 弹窗模式
+
+ child.layerOption ? (typeof child.layerOption.title === 'function' ? (child.layerOption.title = child.layerOption.title(data)) : null) : null;
+ layer.open($.extend({
+ type: 1,
+ title: '子表',
+ maxmin: true,
+ content: _this.getTables(this, data, child, myTable, children, isTpl, tplContent),
+ area: '1000px',
+ offset: '100px',
+ cancel: function () {
+ if (typeof child.childClose === 'function') {
+ if (child.childClose(obj) === false) {
+ return;
+ }
+ }
+ }
+ }, child.layerOption || {}));
+
+ if (!isTpl) {
+ _this.renderTable(this, data, child, myTable, children, icon);
+ }
+
+ } else { // 展开模式
+
+ // 开启手风琴模式
+ if (!$this.hasClass(icon[1]) && child.collapse) {
+ $tableBody.children('tbody').children('tr').children('td').find('.childTable').each(function () {
+ if ($(this).hasClass(icon[1])) {
+ _this.destroyChildren($(this).parents('tr:eq(0)').data('index'), myTable, icon)
+ }
+ })
+ }
+
+ // 多个入口时,关闭其他入口
+ if (!$this.hasClass(icon[1])) {
+ $this.parents('tr:eq(0)').children('td').find('.childTable').each(function () {
+ if ($(this).hasClass(icon[1])) {
+ $(this).removeClass(icon[1]).addClass(icon[0])
+ _this.destroyChildren($(this).parents('tr:eq(0)').data('index'), myTable, icon)
+ }
+ })
+ }
+
+ if ($this.hasClass(icon[1])) {
+ $this.removeClass(icon[1]).addClass(icon[0])
+ $fixedThis.removeClass(icon[1]).addClass(icon[0])
+ } else {
+ $this.removeClass(icon[0]).addClass(icon[1])
+ $fixedThis.removeClass(icon[0]).addClass(icon[1])
+ }
+ var rowspanIndex = $this.parents('td:eq(0)').attr("rowspan");
+
+ if ($this.hasClass(icon[1])) {
+ var newTr = [];
+ newTr.push('
');
+
+ if (rowspanIndex) {
+ var index = parseInt($this.parents('tr:eq(0)').data("index")) + parseInt(rowspanIndex) - 1;
+ $this.parents('table:eq(0)').children().children("[data-index='" + index + "']").after(newTr.join(''));
+ } else {
+ $this.parents('tr:eq(0)').after(newTr.join(''));
+ }
+ layui.element.init('tab')
+ if (!isTpl) {
+ _this.renderTable(this, data, child, myTable, children, icon);
+ // 阻止事件冒泡
+ $this.parents('tr:eq(0)').next().children('td').children('.layui-tab').children('.layui-tab-content').on('click', function (e) {
+ // 不阻止 tab 切换点击事件
+ if (!$(e.target.parentElement).hasClass('layui-tab-title')) {
+ e.stopPropagation()
+ }
+ }).off('dblclick').on('dblclick', function (e) {
+ e.stopPropagation()
+ }).on('mouseenter', 'td', function (e) {
+ e.stopPropagation()
+ }).on('change', function (e) {
+ layui.stope(e)
+ })
+ }
+ if ($fixedBody.length > 0) {
+ var $tr = $this.parents('tr:eq(0)').next(),
+ height = $tr.children('td').height(),
+ $patchDiv = '
';
+ $tr.children('td').children('.soul-table-child-wrapper').css({
+ position: 'absolute',
+ top: 0,
+ width: '100%',
+ background: 'white',
+ 'z-index': 200
+ })
+ $tr.children('td').append($patchDiv);
+ $fixedBody.find('tr[data-index="' + rowIndex + '"]').each(function () {
+ $(this).after('
')
+ })
+ table.resize(tableId)
+ }
+ if (child.show === 3) {
+ $this.parents('tr:eq(0)').next().find('.layui-table-view').css({margin: 0, 'border-width': 0});
+ $this.parents('tr:eq(0)').next().find('.layui-table-header').css('display', 'none');
+ }
+
+ } else {
+ _this.destroyChildren(rowIndex, myTable, icon);
+ table.resize(tableId)
+ }
+
+ }
+ })
+
+ })
+
+ if (child.spread && child.show !== 2) {
+ $tableBody.children('tbody').children('tr').children('td').find('.childTable').trigger('click');
+ }
+ })()
+
+ }
+ }
+ },
+ /**
+ * 生成子表内容
+ * @param _this
+ * @param data
+ * @param child
+ * @param myTable
+ * @param children 子表配置
+ * @param isTpl 是否是自定义模版
+ * @param tplContent 自定义模版内容
+ * @returns {string}
+ */
+ getTables: function (_this, data, child, myTable, children, isTpl, tplContent) {
+ var tables = [],
+ $table = $(myTable.elem),
+ $tableBox = $table.next().children('.layui-table-box'),
+ tableId = myTable.id,
+ rowTableId = tableId + $(_this).parents('tr:eq(0)').data('index'),
+ $tableHead = $tableBox.children('.layui-table-header').children('table'),
+ $tableMain = $table.next().children('.layui-table-box').children('.layui-table-body'),
+ $tableBody = $tableMain.children('table'),
+ scrollWidth = 0,
+ i;
+ if (isTpl) {
+ tables.push('
')
+ } else if (child.show === 3) {
+ //不限制宽度
+ tables.push('">')
+ } else {
+ if (child.childWidth === 'full') {
+ //不限制宽度
+ tables.push('">')
+ } else {
+ // 如果有滚动条
+ if ($tableMain.prop('scrollHeight') + (children.length > 0 ? children[0].height : 0) > $tableMain.height()) {
+ scrollWidth = this.getScrollWidth();
+ }
+ var maxWidth = $tableMain.width() - 1 - scrollWidth;
+ tables.push('max-width: ' + (maxWidth > $tableHead.width() ? $tableHead.width() : maxWidth) + 'px">')
+ }
+ }
+ if (isTpl) {
+ tables.push(tplContent)
+ } else {
+ if (child.show !== 3 && (typeof child.childTitle === 'undefined' || child.childTitle)) {
+ tables.push('
')
+ for (i = 0; i < children.length; i++) {
+ tables.push('' + (typeof children[i].title === 'function' ? children[i].title(data) : children[i].title) + ' ');
+ }
+ tables.push(' ')
+ }
+ if (child.show === 3) {
+ tables.push('
');
+ } else {
+ tables.push('
');
+ }
+ for (i = 0; i < children.length; i++) {
+ var childTableId = rowTableId + i;
+ tables.push('
');
+ }
+ tables.push('
');
+ }
+ tables.push('
');
+ return tables.join('')
+ },
+ /**
+ * 渲染子表
+ * @param _this
+ * @param data 父表当前行数据
+ * @param child 子表列
+ * @param myTable 父表配置
+ * @param children 子表配置
+ * @param icon 自定义图标
+ */
+ renderTable: function (_this, data, child, myTable, children, icon) {
+ var tables = []
+ , _that = this
+ , tableId = myTable.id
+ , rowTableId = tableId + $(_this).parents('tr:eq(0)').data('index');
+
+ if (child.lazy) {
+ tables.push(renderChildTable(_that, _this, data, child, myTable, 0, children, icon));
+ } else {
+ for (var i = 0; i < children.length; i++) {
+ tables.push(renderChildTable(_that, _this, data, child, myTable, i, children, icon));
+ }
+ }
+ tableChildren[rowTableId] = tables;
+
+
+ layui.element.on('tab(table-child-tab-' + rowTableId + ')', function (tabData) {
+ if (child.lazy) {
+ var isRender = false; // 是否已经渲染
+ for (i = 0; i < tableChildren[rowTableId].length; i++) {
+ if (tableChildren[rowTableId][i].config.id === (rowTableId + tabData.index)) {
+ isRender = true;
+ break;
+ }
+ }
+ if (!isRender) {
+ tableChildren[rowTableId].push(renderChildTable(_that, _this, data, child, myTable, tabData.index, children))
+ }
+ }
+
+ var rowIndex = $(_this).parents('tr:eq(0)').data('index'),
+ height = $(tabData.elem).height();
+
+ $(_this).parents('.layui-table-box:eq(0)').children('.layui-table-body').children('table').children('tbody').children('tr[data-index=' + rowIndex + ']').next().children().children('.soul-table-child-patch').css('height', height)
+ $(_this).parents('.layui-table-box:eq(0)').children('.layui-table-fixed').children('.layui-table-body').children('table').children('tbody').children('tr[data-index=' + rowIndex + ']').next().children().children('.soul-table-child-patch').css('height', height)
+ table.resize(tableId)
+
+ });
+
+
+ function renderChildTable(_that, _this, data, child, myTable, i, children, icon) {
+ var param = _that.deepClone(children[i]), thisTableChild,
+ tableId = myTable.id,
+ rowIndex = $(_this).parents('tr:eq(0)').data('index'),
+ childTableId = tableId + rowIndex + i,
+ $table = $(myTable.elem),
+ $tableBox = $table.next().children('.layui-table-box'),
+ $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table')),
+ tr = $tableBody.children('tbody').children('tr[data-index="' + rowIndex + '"]'),
+ row = table.cache[tableId][rowIndex],
+ // 父表当前行对象
+ pobj = {
+ data: row,
+ tr: tr,
+ del: function () {
+ table.cache[tableId][rowIndex] = [];
+ _that.destroyChildren(rowIndex, myTable, icon)
+ tr.remove();
+ table.resize(tableId);
+ },
+ update: function (fields) {
+ fields = fields || {};
+ layui.each(fields, function (key, value) {
+ if (key in row) {
+ var templet, td = tr.children('td[data-field="' + key + '"]');
+ row[key] = value;
+ table.eachCols(tableId, function (i, item2) {
+ if (item2.field == key && item2.templet) {
+ templet = item2.templet;
+ }
+ });
+ td.children('.layui-table-cell').html(function () {
+ return templet ? function () {
+ return typeof templet === 'function'
+ ? templet(row)
+ : laytpl($(templet).html() || value).render(row)
+ }() : value;
+ }());
+ td.data('content', value);
+ }
+ });
+ },
+ close: function () {
+ _that.destroyChildren(rowIndex, myTable, icon)
+ table.resize(tableId);
+ }
+
+ };
+ param.id = childTableId;
+ param.elem = '#' + childTableId;
+ typeof param.where === 'function' && (param.where = param.where(data));
+ typeof param.data === 'function' && (param.data = param.data(data));
+ typeof param.url === 'function' && (param.url = param.url(data));
+ thisTableChild = table.render(param);
+ if (!child.lazy && i !== 0) {
+ $('#' + childTableId).parents('.layui-tab-item:eq(0)').removeClass('layui-show'); //解决隐藏时计算表格高度有问题
+ }
+ // 绑定 checkbox 事件
+ if (typeof param.checkboxEvent === 'function') {
+ table.on('checkbox(' + childTableId + ')', function (obj) {
+ param.checkboxEvent(_that.commonMember.call(this, _that, param, obj), pobj)
+ })
+ }
+ // 绑定 edit 事件
+ if (typeof param.editEvent === 'function') {
+ table.on('edit(' + childTableId + ')', function (obj) {
+ param.editEvent(_that.commonMember.call(this, _that, param, obj), pobj)
+ })
+ }
+ // 绑定 tool 事件
+ if (typeof param.toolEvent === 'function') {
+ table.on('tool(' + childTableId + ')', function (obj) {
+ param.toolEvent(_that.commonMember.call(this, _that, param, obj), pobj)
+ })
+ }
+ // 绑定 toolbar 事件
+ if (typeof param.toolbarEvent === 'function') {
+ table.on('toolbar(' + childTableId + ')', function (obj) {
+ param.toolbarEvent(_that.commonMember.call(this, _that, param, obj), pobj)
+ })
+ }
+ // 绑定单击行事件
+ if (typeof param.rowEvent === 'function') {
+ table.on('row(' + childTableId + ')', function (obj) {
+ param.rowEvent(_that.commonMember.call(this, _that, param, obj), pobj)
+ })
+ }
+ // 绑定双击行事件
+ if (typeof param.rowDoubleEvent === 'function') {
+ table.on('rowDouble(' + childTableId + ')', function (obj) {
+ param.rowDoubleEvent(_that.commonMember.call(this, _that, param, obj), pobj)
+ })
+ }
+ return thisTableChild;
+ }
+ },
+ destroyChildren: function (rowIndex, myTable, icon) {
+ var tableId = myTable.id,
+ $table = $(myTable.elem),
+ $tableBox = $table.next().children('.layui-table-box'),
+ $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table'),
+ $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody),
+ $tr = $tableBody.children('tbody').children('tr[data-index="' + rowIndex + '"]'),
+ isTpl = $tr.next().data('tpl');
+
+ $tr.find('.childTable').removeClass(icon[1]).addClass(icon[0]);
+
+ // 暂时不处理 rowspan 情况
+ // var rowspanIndex = $this.parents('td:eq(0)').attr("rowspan");
+ // if(rowspanIndex){
+ // var index=$this.parents('tr:eq(0)').index()+parseInt(rowspanIndex);
+ // $this.parents('table:eq(0)').children().children('tr:eq('+index+')').remove()
+ // }else{
+ // $this.parents('tr:eq(0)').next().remove();
+ // }
+ $tr.next().remove()
+ if (isTpl === 'false') {
+ var tables = tableChildren[tableId + rowIndex];
+ if (layui.tableFilter) { //如果使用了筛选功能,同时清理筛选渲染的数据
+ layui.tableFilter.destroy(tables);
+ }
+ if (layui.soulTable) { // 清除记忆
+ for (var i = 0; i < tableChildren[tableId + rowIndex].length; i++) {
+ layui.soulTable.clearOriginCols(tableChildren[tableId + rowIndex][i].config.id)
+ }
+ }
+ }
+ delete tableChildren[tableId + rowIndex]
+
+ },
+ cloneJSON: function (obj) {
+ var JSON_SERIALIZE_FIX = {
+ PREFIX: "[[JSON_FUN_PREFIX_",
+ SUFFIX: "_JSON_FUN_SUFFIX]]"
+ };
+ var sobj = JSON.stringify(obj, function (key, value) {
+ if (typeof value === 'function') {
+ return JSON_SERIALIZE_FIX.PREFIX + value.toString() + JSON_SERIALIZE_FIX.SUFFIX;
+ }
+ return value;
+ });
+ return JSON.parse(sobj, function (key, value) {
+ if (typeof value === 'string' &&
+ value.indexOf(JSON_SERIALIZE_FIX.SUFFIX) > 0 && value.indexOf(JSON_SERIALIZE_FIX.PREFIX) === 0) {
+ return eval("(" + value.replace(JSON_SERIALIZE_FIX.PREFIX, "").replace(JSON_SERIALIZE_FIX.SUFFIX, "") + ")");
+ }
+ return value;
+ }) || {};
+ },
+ fixHoverStyle: function (myTable) {
+ var $table = $(myTable.elem)
+ , $tableBody = $table.next().children('.layui-table-box').children('.layui-table-body').children('table')
+ ,
+ $tableFixed = $table.next().children('.layui-table-box').children('.layui-table-fixed').children('.layui-table-body').children('table')
+ , style = $table.next().find('style')[0],
+ sheet = style.sheet || style.styleSheet || {};
+ // 屏蔽掉layui原生 hover 样式
+ this.addCSSRule(sheet, '.layui-table-hover', 'background-color: inherit');
+ this.addCSSRule(sheet, '.layui-table-hover.soul-table-hover', 'background-color: #F2F2F2');
+ $.merge($tableFixed.children('tbody').children('tr'), $tableBody.children('tbody').children('tr'))
+ .on('mouseenter', function () {
+ var othis = $(this)
+ , index = $(this).data('index');
+ if (othis.data('off')) return;
+ $tableFixed.children('tbody').children('tr[data-index=' + index + ']').addClass(ELEM_HOVER);
+ $tableBody.children('tbody').children('tr[data-index=' + index + ']').addClass(ELEM_HOVER);
+ }).on('mouseleave', function () {
+ var othis = $(this)
+ , index = $(this).data('index');
+ if (othis.data('off')) return;
+ $tableFixed.children('tbody').children('tr[data-index=' + index + ']').removeClass(ELEM_HOVER);
+ $tableBody.children('tbody').children('tr[data-index=' + index + ']').removeClass(ELEM_HOVER);
+ })
+ },
+ addCSSRule: function (sheet, selector, rules, index) {
+ if ('insertRule' in sheet) {
+ sheet.insertRule(selector + '{' + rules + '}', index)
+ } else if ('addRule' in sheet) {
+ sheet.addRule(selector, rules, index)
+ }
+ },
+ // 深度克隆-不丢失方法
+ deepClone: function (obj) {
+ var newObj = Array.isArray(obj) ? [] : {}
+ if (obj && typeof obj === "object") {
+ for (var key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ newObj[key] = (obj && typeof obj[key] === 'object') ? this.deepClone(obj[key]) : obj[key];
+ }
+ }
+ }
+ return newObj
+ },
+ getCompleteCols: function (origin) {
+ var cols = this.deepClone(origin);
+ var i, j, k, cloneCol;
+ for (i = 0; i < cols.length; i++) {
+ for (j = 0; j < cols[i].length; j++) {
+ if (!cols[i][j].exportHandled) {
+ if (cols[i][j].rowspan > 1) {
+ cloneCol = this.deepClone(cols[i][j])
+ cloneCol.exportHandled = true;
+ k = i + 1;
+ while (k < cols.length) {
+ cols[k].splice(j, 0, cloneCol)
+ k++
+ }
+ }
+ if (cols[i][j].colspan > 1) {
+ cloneCol = this.deepClone(cols[i][j])
+ cloneCol.exportHandled = true;
+ for (k = 1; k < cols[i][j].colspan; k++) {
+ cols[i].splice(j, 0, cloneCol)
+ }
+ j = j + parseInt(cols[i][j].colspan) - 1
+ }
+ }
+ }
+ }
+ return cols[cols.length - 1];
+ },
+ getScrollWidth: function (elem) {
+ var width = 0;
+ if (elem) {
+ width = elem.offsetWidth - elem.clientWidth;
+ } else {
+ elem = document.createElement('div');
+ elem.style.width = '100px';
+ elem.style.height = '100px';
+ elem.style.overflowY = 'scroll';
+
+ document.body.appendChild(elem);
+ width = elem.offsetWidth - elem.clientWidth;
+ document.body.removeChild(elem);
+ }
+ return width;
+ },
+ //解析自定义模板数据
+ parseTempData: function (item3, content, tplData, text) { //表头数据、原始内容、表体数据、是否只返回文本
+ var str = item3.children ? function () {
+ return typeof item3.children === 'function'
+ ? item3.children(tplData)
+ : laytpl($(item3.children).html() || String(content)).render(tplData)
+ }() : content;
+ return text ? $('
' + str + '
').text() : str;
+ },
+ commonMember: function (_this, myTable, sets) {
+ var othis = $(this)
+ , tableId = myTable.id
+ , $table = $(myTable.elem)
+ , $tableBox = $table.next().children('.layui-table-box')
+ , $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table')
+ , $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody)
+ , index = othis[0].tagName === 'TR' ? $(this).data('index') : othis.parents('tr:eq(0)').data('index')
+ , tr = $tableBody.children('tbody').children('tr[data-index="' + index + '"]')
+ , data = table.cache[tableId] || [];
+
+
+ data = data[index] || {};
+
+ return $.extend(sets, {
+ tr: tr //行元素
+ , oldValue: othis.prev() ? othis.prev().text() : null
+ , del: function () { //删除行数据
+ table.cache[tableId][index] = [];
+ tr.remove();
+ _this.scrollPatch(myTable);
+ }
+ , update: function (fields) { //修改行数据
+ fields = fields || {};
+ layui.each(fields, function (key, value) {
+ if (key in data) {
+ var templet, td = tr.children('td[data-field="' + key + '"]');
+ data[key] = value;
+ table.eachCols(tableId, function (i, item2) {
+ if (item2.field == key && item2.templet) {
+ templet = item2.templet;
+ }
+ });
+ td.children('.layui-table-cell').html(_this.parseTempData({
+ templet: templet
+ }, value, data));
+ td.data('content', value);
+ }
+ });
+ }
+ });
+ },
+ scrollPatch: function (myTable) {
+ var $table = $(myTable.elem),
+ layHeader = $table.next().children('.layui-table-box').children('.layui-table-header'),
+ layTotal = $table.next().children('.layui-table-total'),
+ layMain = $table.next().children('.layui-table-box').children('.layui-table-main'),
+ layFixed = $table.next().children('.layui-table-box').children('.layui-table-fixed'),
+ layFixRight = $table.next().children('.layui-table-box').children('.layui-table-fixed-r'),
+ layMainTable = layMain.children('table'),
+ scollWidth = layMain.width() - layMain.prop('clientWidth'),
+ scollHeight = layMain.height() - layMain.prop('clientHeight'),
+ outWidth = layMainTable.outerWidth() - layMain.width() //表格内容器的超出宽度
+
+ //添加补丁
+ , addPatch = function (elem) {
+ if (scollWidth && scollHeight) {
+ elem = elem.eq(0);
+ if (!elem.find('.layui-table-patch')[0]) {
+ var patchElem = $('
'); //补丁元素
+ patchElem.find('div').css({
+ width: scollWidth
+ });
+ elem.find('tr').append(patchElem);
+ }
+ } else {
+ elem.find('.layui-table-patch').remove();
+ }
+ }
+
+ addPatch(layHeader);
+ addPatch(layTotal);
+
+ //固定列区域高度
+ var mainHeight = layMain.height()
+ , fixHeight = mainHeight - scollHeight;
+ layFixed.find('.layui-table-body').css('height', layMainTable.height() >= fixHeight ? fixHeight : 'auto');
+
+ //表格宽度小于容器宽度时,隐藏固定列
+ layFixRight[outWidth > 0 ? 'removeClass' : 'addClass'](HIDE);
+
+ //操作栏
+ layFixRight.css('right', scollWidth - 1);
+ }
+ };
+
+ // 输出
+ exports('tableChild', mod);
});
diff --git a/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/tableFilter.js b/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/tableFilter.js
index 7c1666d..122f8f5 100644
--- a/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/tableFilter.js
+++ b/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/tableFilter.js
@@ -4,3273 +4,3221 @@
* @author: yelog
* @link: https://github.com/yelog/layui-soul-table
* @license: MIT
- * @version: v1.6.1
+ * @version: v1.9.0
*/
layui.define(['table', 'form', 'laydate', 'util', 'excel', 'laytpl'], function (exports) {
- var $ = layui.jquery,
- table = layui.table,
- form = layui.form,
- laydate = layui.laydate,
- laytpl = layui.laytpl,
- util = layui.util,
- excel = layui.excel,
- columnsTimeOut,
- dorpListTimeOut,
- conditionTimeOut,
- bfColumnTimeOut,
- bfCond1TimeOut,
- isFilterReload = {},
- SOUL_ROW_INDEX = 'SOUL_ROW_INDEX',
- cache = {},
- HIDE = 'layui-hide',
- maxId = 1,
- UNHANDLED_VALUES = [undefined, '', null],
- where_cache = {},
- isFilterCache = {},
- table_cache = {},
- conditionChangeItems = {
- 'eq': '等于',
- 'ne': '≠ 不等于',
- 'gt': '> 大于',
- 'ge': '≥ 大于等于',
- 'lt': '< 小于',
- 'le': '≤ 小于等于',
- 'contain': '包含',
- 'notContain': '不包含',
- 'start': '以...开头',
- 'end': '以...结尾',
- 'null': '为空',
- 'notNull': '不为空'
- },
- dateTimeItems = {
- 'all': '全部',
- 'yesterday': '昨天',
- 'thisWeek': '本周',
- 'lastWeek': '上周',
- 'thisMonth': '本月',
- 'thisYear': '今年'
- },
- defaultFilterItems = ['column', 'data', 'condition', 'editCondition', 'excel'],
- itemsMap = {
- 'column': 'soul-column',
- 'data': 'soul-dropList',
- 'condition': 'soul-condition',
- 'editCondition': 'soul-edit-condition',
- 'excel': 'soul-export',
- 'clearCache': 'soul-clear-cache',
- },
- modeMapItems = {
- 'in': 'data',
- 'condition': 'condition',
- 'date': 'condition',
- },
- revertMode = {
- 'data': {
- 'mode': 'condition',
- 'type': 'eq',
- 'value': '',
- },
- 'condition': {
- 'mode': 'in',
- 'values': [],
- },
- };
-
- // 封装方法
- var mod = {
- /**
- * 摧毁render数据
- * @param myTables
- */
- destroy: function (myTables) {
- if (myTables) {
- if (Array.isArray(myTables)) {
- for (var i = 0; i < myTables.length; i++) {
- deleteRender(myTables[i])
- }
- } else {
- deleteRender(myTables);
- }
- }
-
- function deleteRender(myTable) {
- if (!myTable) {
- return;
- }
- var tableId = myTable.config.id;
- $('#soul-filter-list' + tableId).remove();
- $('#soulCondition' + tableId).remove();
- $('#soulDropList' + tableId).remove();
-
- delete isFilterReload[tableId];
- delete where_cache[tableId];
- delete table_cache[tableId];
- }
- },
- clearFilter: function (myTable) {
- if (typeof myTable === 'string') {
- myTable = table_cache[myTable]
- }
- if (!where_cache[myTable.id] || !where_cache[myTable.id].filterSos || where_cache[myTable.id].filterSos === "[]") {
- return;
- }
- where_cache[myTable.id].filterSos = "[]"
- this.soulReload(myTable, true)
- if (table_cache[myTable.id].where && table_cache[myTable.id].where.filterSos && table_cache[myTable.id].where.filterSos !== "[]") {
- table_cache[myTable.id].where.filterSos = "[]"
- }
- },
- render: function (myTable) {
- var _this = this,
- $table = $(myTable.elem),
- $tableMain = $table.next().children('.layui-table-box').children('.layui-table-main'),
- $tableHead = $table.next().children('.layui-table-box').children('.layui-table-header').children('table'),
- $fixedLeftTableHead = $table.next().children('.layui-table-box').children('.layui-table-fixed-l').children('.layui-table-header').children('table'),
- $fixedRigthTableHead = $table.next().children('.layui-table-box').children('.layui-table-fixed-r').children('.layui-table-header').children('table'),
- tableId = myTable.id,
- columns = _this.getCompleteCols(myTable.cols),
- filterItems = myTable.filter ? myTable.filter.items || defaultFilterItems : defaultFilterItems,
- needFilter = false, // 是否存在筛选列需要进行初始化
- initFilter = false, // 是否为第一次筛选
- mainExcel = typeof myTable.excel === 'undefined' || ((myTable.excel && (typeof myTable.excel.on === 'undefined' || myTable.excel.on)) ? myTable.excel : false),
- i, j;
-
- for (i = 0; i < columns.length; i++) {
- if (columns[i].field && columns[i].filter) {
- needFilter = true;
- if ($tableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.soul-table-filter').length === 0) {
- initFilter = true;
- if ($tableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.layui-table-sort').length > 0) {
- $tableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.layui-table-sort').hide()
- $tableHead.find('th[data-field="' + columns[i].field + '"]').children().append('
')
- } else {
- $tableHead.find('th[data-field="' + columns[i].field + '"]').children().append('
')
- }
- if ($fixedLeftTableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.layui-table-sort').length > 0) {
- $fixedLeftTableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.layui-table-sort').hide()
- $fixedLeftTableHead.find('th[data-field="' + columns[i].field + '"]').children().append('
')
- } else {
- $fixedLeftTableHead.find('th[data-field="' + columns[i].field + '"]').children().append('
')
- }
- if ($fixedRigthTableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.layui-table-sort').length > 0) {
- $fixedRigthTableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.layui-table-sort').hide()
- $fixedRigthTableHead.find('th[data-field="' + columns[i].field + '"]').children().append('
')
- } else {
- $fixedRigthTableHead.find('th[data-field="' + columns[i].field + '"]').children().append('
')
- }
- }
- }
- }
- table_cache[myTable.id] = myTable // 缓存table配置
- isFilterCache[myTable.id] = needFilter;
- if (!needFilter) {
- // 缓存所有数据
- if (myTable.url && !myTable.page) {
- // 修复不分页时,前端筛选后,data不为空,造成所有数据丢失的问题
- cache[myTable.id] = layui.table.cache[myTable.id]
- } else {
- cache[myTable.id] = myTable.data || layui.table.cache[myTable.id]
- }
- table.on('sort(' + $table.attr('lay-filter') + ')', function (obj) {
-
- // 同步分页信息
- myTable.limit = cache[myTable.id].limit
-
- if (myTable.url && myTable.page && !myTable.autoSort) {
- // 后台分页
- where_cache[myTable.id] = myTable.where || {}
- where_cache[myTable.id].field = obj.field;
- where_cache[myTable.id].order = obj.type;
- isFilterReload[myTable.id] = false;
- myTable.page = $.extend(myTable.page, {
- curr: 1 //重新从第 1 页开始
- });
- table.render($.extend(myTable, {
- initSort: obj
- , where: where_cache[myTable.id]
- }));
- } else if ((!myTable.url && myTable.page) || myTable.autoSort) {
- // 前台分页
- if (obj.type === 'asc') { //升序
- cache[myTable.id] = layui.sort(cache[myTable.id], obj.field)
- } else if (obj.type === 'desc') { //降序
- cache[myTable.id] = layui.sort(cache[myTable.id], obj.field, true)
- } else { //清除排序
- cache[myTable.id] = layui.sort(cache[myTable.id], myTable.indexName)
- }
- //排序后及时更新row[SOUL_ROW_INDEX]
- cache[myTable.id].forEach(function (item, index) {
- item[SOUL_ROW_INDEX] = index
- })
- myTable.initSort = obj;
- myTable.page = $.extend(myTable.page, {
- curr: 1 //重新从第 1 页开始
- });
- _this.soulReload(myTable, false)
- }
- });
- return;
- } //如果没筛选列,直接退出
-
- // 渲染底部筛选条件
- if (!(myTable.filter && typeof myTable.filter.bottom !== 'undefined' && !myTable.filter.bottom) && $table.next().children('.soul-bottom-contion').length === 0) {
- $table.next().children('.layui-table-box').after('
')
- var changeHeight = $table.next().children('.layui-table-box').children('.layui-table-body').outerHeight() - $table.next().children('.soul-bottom-contion').outerHeight();
- if (myTable.page && $table.next().children('.layui-table-page').hasClass('layui-hide')) {
- changeHeight += $table.next().children('.layui-table-page').outerHeight()
- }
- $table.next().children('.layui-table-box').children('.layui-table-body').css('height', changeHeight)
- var fixHeight = changeHeight - _this.getScrollWidth($tableMain[0]),
- layMainTableHeight = $tableMain.children('table').height()
- $table.next().children('.layui-table-box').children('.layui-table-fixed').children('.layui-table-body').css('height', layMainTableHeight >= fixHeight ? fixHeight : 'auto')
- $table.next().children('.soul-bottom-contion').children('.condition-items').css('width', ($table.next().children('.soul-bottom-contion').width() - $table.next().children('.soul-bottom-contion').children('.editCondtion').width()) + 'px');
- $table.next().children('.soul-bottom-contion').children('.editCondtion').children('a').on('click', function () {
- _this.showConditionBoard(myTable);
- })
- }
-
- /**
- * 不重载表头数据,重新绑定事件后结束
- */
- if (!initFilter || isFilterReload[myTable.id] || myTable.isSoulFrontFilter) {
- isFilterReload[myTable.id] = false
- myTable['isSoulFrontFilter'] = false
- // 同步选中状态
- if (!myTable.url && myTable.page && myTable.data) {
- myTable.data.forEach(function (row) {
- cache[myTable.id][row[SOUL_ROW_INDEX]] = row
- })
- }
- this.bindFilterClick(myTable);
- return;
- } else {
- if (!myTable.url && myTable.page && myTable.data && myTable.data.length > myTable.limit) {
- // 前端分页大于一页,修复 index (用于排序恢复时需要通过这个排序)
- layui.each(myTable.data, function (index, item) {
- item[myTable.indexName] = index;
- })
- }
- /**
- * 缓存所有数据
- */
- if (myTable.url && !myTable.page) {
- // 修复不分页时,前端筛选后,data不为空,造成所有数据丢失的问题
- cache[myTable.id] = layui.table.cache[myTable.id]
- } else {
- cache[myTable.id] = myTable.data || layui.table.cache[myTable.id]
- }
- // 给表格数据添加位置标志
- cache[myTable.id].forEach(function (item, index) {
- item[SOUL_ROW_INDEX] = index
- })
-
- if (myTable.filter && myTable.filter.clearFilter) {
- if (myTable.where && myTable.where.filterSos && JSON.parse(myTable.where.filterSos).length > 0) {
- // 重新查询新数据
- myTable.where.filterSos = '[]';
- where_cache[myTable.id] = myTable.where || {}
- _this.soulReload(myTable, false);
- return;
- } else {
- where_cache[myTable.id] = myTable.where || {}
- }
- } else if ((typeof myTable.url !== 'undefined' && !!myTable.url && myTable.page ? typeof myTable.where.filterSos === 'undefined' : true) && where_cache[myTable.id] && JSON.parse(where_cache[myTable.id].filterSos || '[]').length > 0) {
- myTable.where['filterSos'] = where_cache[myTable.id].filterSos
- where_cache[myTable.id] = myTable.where;
- _this.soulReload(myTable, false);
- return;
- } else {
- where_cache[myTable.id] = myTable.where || {}
- }
- }
-
- // 第一次渲染时,追加数据
- if ($('#soul-filter-list' + tableId).length === 0) {
-
- if (typeof myTable.soulSort === 'undefined' || myTable.soulSort) {
- if (typeof $table.attr('lay-filter') === 'undefined') {
- $table.attr('lay-filter', tableId);
- }
- table.on('sort(' + $table.attr('lay-filter') + ')', function (obj) {
-
- // 同步分页信息
- myTable.limit = table_cache[myTable.id].limit
-
- if (myTable.url && myTable.page) {
- // 后台分页
- where_cache[myTable.id].field = obj.field;
- where_cache[myTable.id].order = obj.type;
- isFilterReload[myTable.id] = true;
- myTable.page = $.extend(myTable.page, {
- curr: 1 //重新从第 1 页开始
- });
- table.render($.extend(myTable, {
- initSort: obj
- , where: where_cache[myTable.id]
- }));
- } else if (!myTable.url && myTable.page) {
- // 前台分页
- if (obj.type === 'asc') { //升序
- cache[myTable.id] = layui.sort(cache[myTable.id], obj.field)
- } else if (obj.type === 'desc') { //降序
- cache[myTable.id] = layui.sort(cache[myTable.id], obj.field, true)
- } else { //清除排序
- cache[myTable.id] = layui.sort(cache[myTable.id], myTable.indexName)
- }
- //排序后及时更新row[SOUL_ROW_INDEX]
- cache[myTable.id].forEach(function (item, index) {
- item[SOUL_ROW_INDEX] = index
- })
- myTable.initSort = obj;
- myTable.page = $.extend(myTable.page, {
- curr: 1 //重新从第 1 页开始
- });
- _this.soulReload(myTable, false)
- }
- });
- }
-
- var soulFilterList = [],
- filterItemsHtml = {
- column: '
表格列 ',
- data: '
筛选数据 ',
- condition: '
筛选条件 ',
- editCondition: '
编辑筛选条件 ',
- excel: '
导出excel ',
- clearCache: '
清除缓存 '
- };
- soulFilterList.push('
');
- $('body').append(soulFilterList.join(''));
-
-
- // 显示隐藏列
- var liClick = true;
- form.on('checkbox(changeColumns' + tableId + ')', function (data) {
- liClick = false;
- var columnkey = data.value
- if (data.elem.checked) {
- $table.next().find('[data-key=' + columnkey + ']').removeClass(HIDE);
- } else {
- $table.next().find('[data-key=' + columnkey + ']').addClass(HIDE);
- }
- // 同步配置
- for (i = 0; i < myTable.cols.length; i++) {
- for (j = 0; j < myTable.cols[i].length; j++) {
- if ((myTable.index + '-' + myTable.cols[i][j].key) === columnkey) {
- myTable.cols[i][j]['hide'] = !data.elem.checked
- }
- }
- }
- if (layui.soulTable) {
- layui.soulTable.fixTableRemember(myTable)
- }
- $table.next().children('.layui-table-box').children('.layui-table-body').children('table').children('tbody').children('tr.childTr').children('td').attr('colspan', $table.next().children('.layui-table-box').children('.layui-table-header').find('thead>tr>th:visible').length)
- table.resize(tableId)
- });
- $('#soul-columns' + tableId + '>li[data-value]').on('click', function () {
- if (!$(this).find(':checkbox').is(':disabled')) { //disabled禁止点击
- if (liClick) {
- $(this).find('div.layui-form-checkbox').trigger('click');
- }
- liClick = true;
- }
- });
-
- // 全选-反选事件
- $('#soul-dropList' + tableId + ' .check [data-type]').on('click', function () {
-
- switch ($(this).data('type')) {
- case 'all':
- $(this).parents('#soul-dropList' + tableId).find('input[type=checkbox]:not(:checked)').prop('checked', true);
- break;
- case 'reverse':
- $(this).parents('#soul-dropList' + tableId).find('input[type=checkbox]').each(function () {
- $(this).prop('checked', !$(this).prop('checked'))
- });
- break;
- case 'none':
- $(this).parents('#soul-dropList' + tableId).find('input[type=checkbox]:checked').prop('checked', false);
- break;
- }
- form.render('checkbox', 'orm');
- _this.updateDropList(myTable, $('#main-list' + tableId).data('field'));
- return false;
- });
-
- // 关键字搜索
- $('#soul-dropList' + tableId + ' .filter-search input').on('input', function () {
- var key = $(this).val();
- if (key === '') {
- $('#soul-dropList' + tableId + '>ul>li').show();
- } else {
- $('#soul-dropList' + tableId + '>ul>li').hide();
- $('#soul-dropList' + tableId + '>ul>li[data-value*="' + key.toLowerCase() + '"]').show();
- }
- })
-
- // 显示表格列
- $('#main-list' + tableId + ' .soul-column').on('mouseover', function (e) {
- _this.hideDropList(myTable);
- _this.hideCondition(myTable);
- e.stopPropagation();
- if (columnsTimeOut) {
- clearTimeout(columnsTimeOut)
- }
- columns = _this.getCompleteCols(myTable.cols)
- for (i = 0; i < columns.length; i++) {
- $('#soul-columns' + tableId).find('li[data-value="' + columns[i].field + '"]>input').prop('checked', !columns[i].hide);
- }
- form.render('checkbox', 'orm');
- $('#soul-columns' + tableId).show();
- var left, animate;
- if ($(this).parent().offset().left + $(this).parent().width() + $('#soul-columns' + tableId).width() < document.body.clientWidth) {
- left = $(this).parent().offset().left + $(this).parent().width();
- animate = 'fadeInLeft'
- } else {
- left = $(this).parent().offset().left - $('#soul-columns' + tableId).width();
- animate = 'fadeInRight'
- }
- $('#soul-columns' + tableId).css({ 'top': $(this).offset().top, 'left': left })
- .removeClass().addClass(animate + ' animated');
- });
- // 显示数据下拉
- $('#main-list' + tableId + ' .soul-dropList').on('mouseover', function (e) {
- if ($('#soul-dropList' + tableId).is(':visible') && !$('#soul-dropList' + tableId).hasClass('fadeOutLeft')) {
- return false;
- }
- _this.hideColumns(myTable);
- _this.hideCondition(myTable);
- e.stopPropagation();
- if (dorpListTimeOut) {
- clearTimeout(dorpListTimeOut);
- }
- $('#soul-dropList' + tableId + '>.filter-search>input').val('');
- $('#soul-dropList' + tableId).show();
- var left, animate, field = $('#main-list' + tableId).data('field');
- if ($('#main-list' + tableId).offset().left + $('#soul-dropList' + tableId).width() + $('#soul-dropList' + tableId).width() < document.body.clientWidth) {
- left = $('#main-list' + tableId).offset().left + $('#main-list' + tableId).width();
- animate = 'fadeInLeft';
- } else {
- left = $('#main-list' + tableId).offset().left - $('#soul-dropList' + tableId).width();
- animate = 'fadeInRight';
- }
-
- $('#soulDropList' + tableId).find('.' + field + 'DropList li input[type=checkbox]:checked').prop('checked', false);
- var where = where_cache[myTable.id] || {},
- filterSos = JSON.parse(where.filterSos ? where.filterSos : null),
- id = '', prefix = '';
- if (filterSos) {
- for (i = 0; i < filterSos.length; i++) {
- if (filterSos[i].head && filterSos[i].mode === "in" && filterSos[i].field === field) {
- id = filterSos[i].id;
- prefix = filterSos[i].prefix;
- for (j = 0; j < filterSos[i].values.length; j++) {
- $('#soulDropList' + tableId).find('.' + field + 'DropList li input[type=checkbox][value="' + filterSos[i].values[j] + '"]').prop('checked', true);
- }
- break;
- }
- }
- }
- $('#soul-dropList' + tableId + '>ul').data({
- head: true,
- 'id': id,
- prefix: prefix,
- refresh: true,
- split: $('#main-list' + tableId).data('split')
- }).html($('#soulDropList' + tableId).find('.' + field + 'DropList li').clone());
-
- $('#soul-dropList' + tableId).css({ 'top': $(this).offset().top, 'left': left })
- .show().removeClass().addClass(animate + ' animated');
- setTimeout(function () {
- $('#soul-dropList' + tableId + '>.filter-search>input').focus() // 聚焦搜索框
- form.render('checkbox', 'orm');
- }, 1);
-
- // 监听筛选数据
- var liClick = true;
- form.on('checkbox(soulDropList' + tableId + ')', function (data) {
- liClick = false;
- _this.updateDropList(myTable, field);
- });
-
- $('#soul-dropList' + tableId + '>ul>li[data-value]').on('click', function () {
- if (liClick) {
- $(this).find('div.layui-form-checkbox').trigger('click');
- }
- liClick = true;
- })
- });
-
- // 显示筛选条件
- $('#main-list' + tableId + ' .soul-condition').on('mouseover', function (e) {
- if ($('#soul-condition' + tableId).is(':visible') && !$('#soul-condition' + tableId).hasClass('fadeOutLeft')) {
- return false;
- }
- _this.hideColumns(myTable);
- _this.hideDropList(myTable);
- e.stopPropagation();
- if (conditionTimeOut) {
- clearTimeout(conditionTimeOut);
- }
- var documentWidth = document.body.clientWidth;
- $('#soul-condition' + tableId).show();
- var left, animate, field = $(this).parent().data('field');
- if ($(this).parent().offset().left + $(this).parent().width() + $('#soul-condition' + tableId).width() < documentWidth) {
- left = $(this).parent().offset().left + $(this).parent().width();
- animate = 'fadeInLeft'
- } else {
- left = $(this).parent().offset().left - $('#soul-condition' + tableId).width();
- animate = 'fadeInRight'
- }
-
- var filterSo, conditionHtml = [],
- where = where_cache[myTable.id] || {},
- filterSos = JSON.parse(where.filterSos ? where.filterSos : null);
- if (filterSos) {
- for (i = 0; i < filterSos.length; i++) {
- if (filterSos[i].head && filterSos[i].field === field && (filterSos[i].mode === "date" || filterSos[i].mode === 'group')) {
- filterSo = filterSos[i]
- break;
- }
- }
- }
-
- var filterType = $(this).parent().data('type');
- if (_this.startsWith(filterType, 'date')) {
- _this.showDate(myTable, field, filterSo, animate, $(this).offset().top, $(this).parent().offset().left + $(this).parent().width(), 'down', true);
- } else {
- /**
- * 筛选条件
- */
- var fieldMap = {};
- for (i = 0; i < columns.length; i++) {
- if (columns[i].field) {
- fieldMap[columns[i]['field']] = columns[i]
- }
- }
- // 查询条件
- var selectStr = "
";
- for (var key in conditionChangeItems) {
- selectStr += '' + conditionChangeItems[key] + ' ';
- }
- selectStr += " ";
- conditionHtml.push('
添加 查询
')
-
- $('#soul-condition' + tableId).data({ head: true, id: filterSo ? filterSo.id || '' : '' })
- .html(conditionHtml.join(''))
- .css({ 'top': $(this).offset().top, 'left': left })
- .show().removeClass().addClass(animate + ' animated');
-
- $('.condition-table').on('click', function () {
- return false;
- })
-
- // 新增与查询
- $('#soul-condition' + tableId + ' button[data-type]').on('click', function () {
- /**
- * 新增
- */
- if ($(this).data('type') === 'add') {
- var groupId = $('#soul-condition' + tableId).data('id'),
- head = $('#soul-condition' + tableId).data('head'),
- type = 'eq',
- filterSo,
- $tr1 = $('#soul-condition' + tableId).find('tr:eq(0)');
-
- if (groupId) {
- filterSo = {
- head: head,
- prefix: 'and',
- field: field,
- mode: 'condition',
- type: type,
- value: '',
- groupId: groupId
- }
- } else {
- filterSo = {
- head: head,
- prefix: head ? 'and' : 'and',
- mode: 'group',
- field: field,
- children: [{
- id: _this.getDifId(),
- prefix: 'and',
- field: field,
- mode: 'condition',
- type: $tr1.find('select').val(),
- value: $tr1.find('.value').val()
- }, {
- id: _this.getDifId(),
- prefix: 'and',
- field: field,
- mode: 'condition',
- type: type,
- value: ''
- }]
- }
- }
-
- _this.updateWhere(myTable, filterSo);
- if (!groupId) {
- $('#soul-condition' + tableId).data('id', filterSo.id);
- $tr1.data('id', filterSo.children[0].id);
- }
- // $tableHead.find('thead>tr>th[data-field="'+field+'"] .soul-table-filter').attr('soul-filter','true');
- var newId = groupId ? filterSo.id : filterSo.children[1].id;
- var newTr = '
' +
- ' ' +
- ' ' +
- '
' +
- ' '
- + '' + selectStr + '
'
- + '
'
- + '';
-
- $('#soul-condition' + tableId + ">table>tbody").append(newTr)
- $('#soul-condition' + tableId).find('.del:last').on('click', function () { //删除
- delCurrentTr(this)
- });
-
- // input同步筛选条件
- $('#soul-condition' + tableId + ' input.value:last').on('input', function () {
- updateTrWhere($(this).parents('tr:eq(0)'))
- });
- } else if ($(this).data('type') === 'search') {
- /**
- * 查询
- */
- _this.soulReload(myTable);
- }
- form.render('select', 'orm');
- form.render('checkbox', 'orm');
- return false;
- });
-
- // input同步筛选条件
- $('#soul-condition' + tableId + ' input.value').on('input', function () {
- updateTrWhere($(this).parents('tr:eq(0)'));
- });
-
- // 当前行改动时,同步where条件
- function updateTrWhere($tr) {
- var id = $tr.data('id'),
- groupId = $('#soul-condition' + tableId).data('id'),
- prefix = $tr.find('input[lay-filter="soul-coondition-switch"]:checked').prop('checked') ? 'and' : 'or',
- type = $tr.find('select').val(),
- value = $tr.find('.value').val(),
- head = $('#soul-condition' + tableId).data('head');
-
- if (groupId) {
- filterSo = {
- id: id,
- prefix: prefix,
- mode: 'condition',
- field: field,
- type: type,
- value: value,
- groupId: groupId
- }
- } else {
- filterSo = {
- head: head,
- prefix: head ? 'and' : 'and',
- mode: 'group',
- field: field,
- children: [{
- id: _this.getDifId(),
- prefix: prefix,
- mode: 'condition',
- field: field,
- type: type,
- value: value,
- groupId: groupId
- }]
- }
- }
- _this.updateWhere(myTable, filterSo)
- if (!groupId) {
- $('#soul-condition' + tableId).data('id', filterSo.id);
- $tr.data('id', filterSo.children[0].id)
- } else if (!id) {
- $tr.data('id', filterSo.id);
- }
- }
-
- // select同步筛选条件
- form.on('select(conditionChange)', function (data) {
- if (data.value === 'null' || data.value === 'notNull') {
- $(this).parents('tr').find('input.value').hide();
- } else {
- $(this).parents('tr').find('input.value').show();
- }
- updateTrWhere($(data.elem).parents('tr:eq(0)'));
- })
-
- // radio同步筛选条件
- form.on('switch(soul-coondition-switch)', function (data) {
- updateTrWhere($(this).parents('tr:eq(0)'));
- });
-
- // 删除当前行
- $('#soul-condition' + tableId + ' .del').on('click', function () {
- delCurrentTr(this)
- });
-
- function delCurrentTr(obj) {
-
- var id;
-
- if ($(obj).parents('table:eq(0)').find('tr').length === 1) {
- id = $('#soul-condition' + tableId).data('id');
- $('#soul-condition' + tableId).data('id', '');
- $(obj).parents('tr:eq(0)').find('select').val('eq')
- $(obj).parents('tr:eq(0)').find('.value').val('').show()
- form.render('select', 'orm');
- } else {
- id = $(obj).parents('tr:eq(0)').data('id');
- if ($(obj).parents('tr:eq(0)').index() === 0) {
- $(obj).parents('table:eq(0)').find('tr:eq(1)>td:eq(0)').html(fieldMap[field].title).addClass('soul-condition-title')
- }
- $(obj).parents('tr:eq(0)').remove()
- }
- if (id) {
- _this.updateWhere(myTable, {
- id: id,
- delete: true
- })
- }
- }
- }
- form.render('select', 'orm');
- form.render('checkbox', 'orm');
-
- });
-
- $('#soul-columns' + tableId + ', #soul-dropList' + tableId).on('mouseover', function (e) {
- e.stopPropagation();
- });
- $('#main-list' + tableId + ' .soul-edit-condition').on('mouseover', function (e) {
- _this.hideColumns(myTable)
- _this.hideDropList(myTable)
- _this.hideCondition(myTable)
- e.stopPropagation();
- }).on('click', function () {
- $('#main-list' + tableId).hide();
- _this.showConditionBoard(myTable)
- });
- $('#main-list' + tableId + ' .soul-export').on('mouseover', function (e) {
- _this.hideColumns(myTable)
- _this.hideDropList(myTable)
- _this.hideCondition(myTable)
- e.stopPropagation();
- }).on('click', function () {
- $('#main-list' + tableId).hide();
- _this.export(table_cache[myTable.id])
- });
-
- $('#main-list' + tableId + ' .soul-clear-cache').on('mouseover', function (e) {
- _this.hideColumns(myTable)
- _this.hideDropList(myTable)
- _this.hideCondition(myTable)
- e.stopPropagation();
- }).on('click', function () {
- $('#main-list' + tableId).hide();
- if (layui.soulTable) {
- layui.soulTable.clearCache(myTable)
- }
- layer.msg('已还原!', { icon: 1, time: 1000 })
- });
-
- $('#main-list' + tableId).on('mouseover', function (e) {
- var curX = e.pageX;
- var curY = e.pageY;
- var div = $(this);
- var y1 = div.offset().top; //div上面两个的点的y值
- var y2 = y1 + div.height();//div下面两个点的y值
- var x1 = div.offset().left; //div左边两个的点的x值
- var x2 = x1 + div.width(); //div右边两个点的x的值
- if (curX <= x1 || curX >= x2 || curY <= y1 || curY >= y2) {
- } else {
- _this.hideColumns(myTable);
- _this.hideDropList(myTable);
- _this.hideCondition(myTable);
- }
- });
- } else {
-
- types = {}; //存储过滤数据的类型
- // 根据表格列显示
- for (i = 0; i < columns.length; i++) {
- if (columns[i].type === 'checkbox' || !columns[i].field) {
- continue;
- }
- //存储过滤数据的类型
- if (columns[i].filter && columns[i].filter.type) {
- if (columns[i].filter.field) {
- types[columns[i].filter.field] = columns[i].filter.type;
- } else {
- types[columns[i].field] = columns[i].filter.type;
- }
- }
- }
- if (JSON.stringify(types).length !== 2) {
- myTable.where['tableFilterType'] = JSON.stringify(types);
- }
-
- }
-
- // 初始化下拉数据
- if ($('#soulDropList' + tableId).length === 0) {
- $('body').append('
');
- }
-
- if ($tableHead.find('.soul-table-filter').length > 0) {
- var columnField = [], mainDataSwitch = filterItems.indexOf('data') !== -1;
- $tableHead.find('.soul-table-filter').each(function (index, elem) {
- if ($(this).data('column') && (mainDataSwitch ? (!$(this).data('items') || $(this).data('items').split(',').indexOf('data') !== -1) : $(this).data('items').split(',').indexOf('data') !== -1)) {
- columnField.push($(this).data('column'));
- }
- });
- if (columnField.length > 0) {
- if (typeof myTable.url !== 'undefined' && !!myTable.url && myTable.page) {
- var datas = JSON.parse(JSON.stringify(myTable.where)), url = myTable.url;
- datas['columns'] = JSON.stringify(columnField);
- $.ajax({
- url: url,
- data: datas,
- dataType: 'json',
- method: 'post',
- headers: myTable.headers || {},
- contentType: myTable.contentType,
- success: function (result) {
-
- var uls = [];
- for (var key in result) {
- var list = result[key];
- if (!((list.length === 1 && list[0] === '') || list.length === 0)) {
- var ul = [];
- ul.push("
");
- uls.push(ul.join(''));
- } else {
- uls.push("
")
- }
- }
- $('#soulDropList' + tableId).html(uls.join(''));
- },
- error: function () {
- // layer.msg('列筛选数据查询失败!', {icon: 2, anim: 6})
- }
- })
- } else {
- var tableDatas = cache[myTable.id];
- var dropDatas = {};
- for (i = 0; i < tableDatas.length; i++) {
- for (j = 0; j < columnField.length; j++) {
- var value = typeof tableDatas[i][columnField[j]] === 'undefined' ? '' : tableDatas[i][columnField[j]];
- if (dropDatas[columnField[j]]) {
- if (dropDatas[columnField[j]].indexOf(value) === -1) {
- dropDatas[columnField[j]].push(value);
- }
- } else {
- dropDatas[columnField[j]] = [value]
- }
- }
- }
-
- var columnsConfigs = columns;
- var uls = [];
- for (j = 0; j < columnsConfigs.length; j++) {
- var key = columnsConfigs[j].field;
- var list = dropDatas[key];
- if (list && !(list.length === 1 && list[0] === '')) {
- if (columnsConfigs[j].filter && columnsConfigs[j].filter.split) {
- var tempList = []
- for (i = 0; i < list.length; i++) {
- var tempList2 = String(list[i]).split(columnsConfigs[j].filter.split);
- for (var k = 0; k < tempList2.length; k++) {
- if (tempList.indexOf(tempList2[k]) === -1) {
- tempList.push(tempList2[k])
- }
- }
- }
- list = tempList;
- }
- list.sort(function (a, b) {
- if (isNaN(a) || isNaN(b)) {
- return String(a) >= String(b)
- } else {
- return Number(a) - Number(b)
- }
- })
- var ul = [];
- ul.push("
");
- uls.push(ul.join(''));
- } else {
- uls.push("
")
- }
- }
- $('#soulDropList' + tableId).html(uls.join(''));
- }
- } else {
- _this.bindFilterClick(myTable);
- }
- }
-
- this.bindFilterClick(myTable);
- },
- showConditionBoard: function (myTable) {
- var _this = this,
- tableId = myTable.id,
- where = where_cache[myTable.id] || {},
- tableFilterTypes = where.tableFilterType ? JSON.parse(where.tableFilterType) : {},
- filterSos = where.filterSos ? JSON.parse(where.filterSos) : [],
- filterBoard = [], fieldMap = {}, firstColumn, curItems,
- filterItems = myTable.filter ? myTable.filter.items || defaultFilterItems : defaultFilterItems,
- columns = _this.getCompleteCols(myTable.cols),
- i;
- for (i = 0; i < columns.length; i++) {
- if (columns[i].field && columns[i].filter) {
- if (!firstColumn) {
- firstColumn = columns[i]
- }
- curItems = columns[i].filter.items || filterItems;
- fieldMap[columns[i]['field']] = {
- title: columns[i].title,
- items: curItems
- }
- }
- }
- filterBoard.push('
')
- filterBoard.push('
')
- filterBoard.push('
')
- var _width = document.body.clientWidth > parseInt('480') ? '480px' : document.body.clientWidth - 10 + 'px'
- var _height = document.body.clientHeight > parseInt('480') ? '480px' : document.body.clientHeight - 10 + 'px'
- layer.open({
- title: '编辑条件',
- type: 1,
- offset: 'auto',
- area: [_width, _height],
- content: filterBoard.join('')
- })
- form.render(null, 'soul-edit-out');
-
- form.on('checkbox(out_auto)', function (data) {
- if (data.elem.checked) {
- _this.soulReload(myTable);
- }
- })
-
- function groupHtml(filterSo, filterBoard, fieldMap, isFirst, isLast) {
- var id = filterSo.id,
- field = filterSo.field,
- mode = filterSo.mode,
- type = filterSo.type,
- isOr = filterSo.prefix === 'or';
- filterBoard.push('
');
- filterBoard.push('')
- // if (!isFirst) { //第一个隐藏 与或
- filterBoard.push('
')
- // }
- switch (mode) {
- case 'in':
- filterBoard.push('' + (fieldMap[field].title) + '
');
- filterBoard.push('筛选数据
');
- filterBoard.push('共' + (filterSo.values ? filterSo.values.length : 0) + '条数据
');
- filterBoard.push('
');
- break;
- case 'date':
- filterBoard.push('' + (fieldMap[field].title) + '
');
- filterBoard.push('选择日期
');
- filterBoard.push('' + (filterSo.type === 'specific' ? filterSo.value || '请选择' : dateTimeItems[filterSo.type]) + '
');
- filterBoard.push('
');
- break;
- case 'condition':
- filterBoard.push('' + (fieldMap[field].title) + '
');
- filterBoard.push('' + conditionChangeItems[filterSo.type] + '
');
- if (type !== 'null' && type !== 'notNull') {
- filterBoard.push('' + (typeof filterSo.value === 'undefined' || filterSo.value === '' ? '请输入...' : filterSo.value) + '
');
- }
- filterBoard.push('
');
- break;
- case 'group':
- filterBoard.push('分组
')
- filterBoard.push('')
- filterBoard.push('
');
- filterBoard.push('');
- if (filterSo.children) {
- for (var i = 0; i < filterSo.children.length; i++) {
- groupHtml(filterSo.children[i], filterBoard, fieldMap, i === 0, i === (filterSo.children.length - 1));
- }
- }
- filterBoard.push(' ');
- break;
- }
- filterBoard.push(' ')
- }
-
- // prefix
- form.on('switch(soul-edit-switch)', function (data) {
- changePrefix(data)
- })
-
- // column
- $('.soul-edit-out .item-field').on('click', function (e) {
- e.stopPropagation();
- showColums(this)
- })
- // type
- $('.soul-edit-out .item-type').on('click', function (e) {
- e.stopPropagation();
- showTypes(this)
- })
- // value
- $('.soul-edit-out .item-value').on('click', function (e) {
- e.stopPropagation();
- showValue(this)
- })
- // delete
- $('.soul-edit-out .delete-item').on('click', function () {
- var id = $(this).parent().data('id'),
- refresh = $('.soul-edit-out .out_auto').prop('checked');
- $(this).parent().remove();
- _this.updateWhere(myTable, {
- id: id,
- delete: true
- })
- if (refresh) {
- _this.soulReload(myTable);
- }
- })
-
- function changePrefix(data) {
- var prefix = data.elem.checked ? 'and' : 'or',
- id = $(data.elem).parents('li:eq(0)').data('id'),
- refresh = $('.soul-edit-out .out_auto').prop('checked');
-
- $(data.elem).parents('li:eq(0)').data('prefix', prefix);
- _this.updateWhere(myTable, {
- id: id,
- prefix: prefix
- })
-
- if (refresh) {
- _this.soulReload(myTable)
- }
- }
-
- function showColums(obj) {
- _this.hideDropList(myTable);
- _this.hideCondition(myTable);
- _this.hideColumns(myTable);
- _this.hideBfPrefix(myTable)
- _this.hideBfType(myTable);
- var top = $(obj).offset().top + $(obj).outerHeight(),
- left = $(obj).offset().left;
-
- $('#soul-bf-column' + tableId).find('li.soul-bf-selected').removeClass('soul-bf-selected')
- $('#soul-bf-column' + tableId)
- .data('field', $(obj).parent().data('field'))
- .data('id', $(obj).parent().data('id'))
- .data('mode', $(obj).parent().data('mode'))
- .data('group', $(obj).parents('li:eq(2)').data('id') || '')
- .data('refresh', $('.soul-edit-out .out_auto').prop('checked'))
- .show()
- .css({ top: top, left: left })
- .removeClass().addClass('fadeInUp animated')
- .find('li[data-field="' + $(obj).parent().data('field') + '"]')
- .addClass('soul-bf-selected')
- }
-
- function showTypes(obj) {
- _this.hideDropList(myTable);
- _this.hideCondition(myTable);
- _this.hideColumns(myTable);
- _this.hideBfColumn(myTable);
- _this.hideBfPrefix(myTable);
- var top = $(obj).offset().top + $(obj).outerHeight(),
- left = $(obj).offset().left,
- field = $(obj).parent().data('field');
-
- $('#soul-bf-type' + tableId + ' li').hide()
- if (tableFilterTypes[field] && tableFilterTypes[field].indexOf('date') === 0) {
- $('#soul-bf-type' + tableId + ' li[data-mode=date]').show()
- }
- if (fieldMap[field].items.indexOf('data') !== -1) {
- $('#soul-bf-type' + tableId + ' li[data-mode=in]').show()
- }
- if (fieldMap[field].items.indexOf('condition') !== -1) {
- $('#soul-bf-type' + tableId + ' li[data-mode=condition]').show()
- }
-
- $('#soul-bf-type' + tableId).find('li.soul-bf-selected').removeClass('soul-bf-selected')
- switch ($(obj).parent().data('mode')) {
- case 'in':
- $('#soul-bf-type' + tableId).find('li[data-mode="in"]')
- .addClass('soul-bf-selected')
- break;
- case 'date':
- $('#soul-bf-type' + tableId).find('li[data-mode="date"]')
- .addClass('soul-bf-selected')
- case 'condition':
- $('#soul-bf-type' + tableId).find('li[data-value="' + $(obj).parent().data('type') + '"]')
- .addClass('soul-bf-selected')
- }
-
- $('#soul-bf-type' + tableId)
- .data('type', $(obj).parent().data('type'))
- .data('mode', $(obj).parent().data('mode'))
- .data('id', $(obj).parent().data('id'))
- .data('group', $(obj).parents('li:eq(2)').data('id') || '')
- .data('refresh', $('.soul-edit-out .out_auto').prop('checked'))
- .show()
- .css({ top: top, left: left })
- .removeClass().addClass('fadeInUp animated')
- }
-
- function showValue(obj) {
- _this.hideColumns(myTable);
- _this.hideBfType(myTable);
- _this.hideBfPrefix(myTable)
- _this.hideBfColumn(myTable);
-
- var top,
- left = $(obj).offset().left,
- mode = $(obj).parent().data('mode'),
- field = $(obj).parent().data('field'),
- id = $(obj).parent().data('id'),
- head = $(obj).parent().data('head'),
- prefix = $(obj).parent().data('prefix'),
- value = $(obj).parent().data('value'),
- refresh = $('.soul-edit-out .out_auto').prop('checked'),
- where = where_cache[myTable.id] || {},
- filterSos = where.filterSos ? JSON.parse(where.filterSos) : [];
-
- switch (mode) {
- case 'in':
- _this.hideCondition(myTable);
- if (dorpListTimeOut) {
- clearTimeout(dorpListTimeOut);
- }
- $('#soul-dropList' + tableId + '>.filter-search>input').val('');
- $('#soul-dropList' + tableId).show();
- $('#soulDropList' + tableId).find('.' + field + 'DropList li input[type=checkbox]:checked').prop('checked', false);
- var filterSo = _this.getFilterSoById(filterSos, id);
- if (filterSo.values) {
- for (i = 0; i < filterSo.values.length; i++) {
- $('#soulDropList' + tableId).find('.' + field + 'DropList li input[type=checkbox][value="' + filterSo.values[i] + '"]').prop('checked', true);
- }
- }
-
- $('#soul-dropList' + tableId + '>ul').data('id', id).data('head', head).data('refresh', refresh).data('prefix', prefix).html($('#soulDropList' + tableId).find('.' + field + 'DropList li').clone());
- form.render('checkbox', 'orm');
- top = $(obj).offset().top + $(obj).outerHeight();
- $('#soul-dropList' + tableId).css({ 'top': top, 'left': left })
- .show().removeClass().addClass('fadeInUp animated');
- setTimeout(function () {
- $('#soul-dropList' + tableId + '>.filter-search>input').focus() // 聚焦搜索框
- }, 1);
-
- // 监听筛选数据
- var liClick = true;
- form.on('checkbox(soulDropList' + tableId + ')', function (data) {
- liClick = false;
- _this.updateDropList(myTable, field);
- });
-
- $('#soul-dropList' + tableId + '>ul>li[data-value]').on('click', function () {
- if (liClick) {
- $(this).find('div.layui-form-checkbox').trigger('click');
- }
- liClick = true;
- })
- break;
- case 'date':
- _this.hideDropList(myTable);
- if (conditionTimeOut) {
- clearTimeout(conditionTimeOut);
- }
- var filterSo = _this.getFilterSoById(filterSos, id),
- top = $(obj).offset().top + $(obj).height();
-
- _this.showDate(myTable, field, filterSo, "fadeInUp", top, left, "down", refresh);
- break;
- case 'condition':
- $(obj).hide();
- $(obj).after('
')
- $(obj).next().children().val(value).select().on('keydown', function (e) {
- if (e.keyCode === 13) {
- $(this).blur();
- }
- }).on('blur', function () {
- var newValue = $(this).val();
- $(obj).html(typeof newValue === 'undefined' || newValue === '' ? '请输入...' : newValue);
- $(obj).show();
- $(this).parent().remove()
- if (newValue !== value) {
- $(obj).parent().data('value', newValue);
- _this.updateWhere(myTable, {
- id: id,
- value: newValue
- })
- if (refresh) {
- _this.soulReload(myTable);
- }
- }
- })
- break;
- }
-
- }
-
- $('.soul-edit-out a[data-type]').on('click', function () {
- if ($(this).data('type') === 'search') {
- _this.soulReload(myTable);
- } else {
- addLine(this)
- }
- })
-
- function addLine(obj) {
- var refresh = $('.soul-edit-out .out_auto').prop('checked');
- filterBoard = []
- switch ($(obj).data('type')) {
- case 'addOne':
- var filterSo = {
- prefix: 'and',
- field: firstColumn.field,
- mode: 'condition',
- type: 'eq',
- value: ''
- }
- if ($(obj).parent().parent().data('id')) {
- $.extend(filterSo, {
- groupId: $(obj).parent().parent().data('id')
- })
- }
-
- _this.updateWhere(myTable, filterSo);
-
- filterBoard.push('
');
- filterBoard.push('');
- filterBoard.push('
')
- filterBoard.push('' + fieldMap[filterSo.field].title + '
');
- filterBoard.push('等于
');
- filterBoard.push('请输入...
');
- filterBoard.push('
');
- filterBoard.push(' ');
- break;
- case 'addGroup':
- var filterSo = {
- prefix: 'and',
- mode: 'group',
- children: []
- }
- if ($(obj).parent().parent().data('id')) {
- $.extend(filterSo, {
- groupId: $(obj).parent().parent().data('id')
- })
- }
- _this.updateWhere(myTable, filterSo);
-
- filterBoard.push('
');
- filterBoard.push('');
- filterBoard.push('
')
- filterBoard.push('分组
')
- filterBoard.push('')
- filterBoard.push('
');
- filterBoard.push('');
- filterBoard.push(' ');
- break;
- }
- if (refresh) {
- _this.soulReload(myTable);
- }
- if ($(obj).parent().parent().children('ul').children('li').length > 0) {
- $(obj).parent().parent().children('ul').children('li:last').removeClass('last');
- if ($(obj).parent().parent().children('ul').children('li:last').children('ul.group').length > 0) {
- $(obj).parent().parent().children('ul').children('li:last').children('ul.group').addClass('line')
- }
- }
- $(obj).parent().parent().children('ul').append(filterBoard.join(''));
- form.render('checkbox', 'soul-edit-out')
- if ($(obj).data('type') === 'addGroup') {
- $(obj).parent().parent().children('ul').children("li:last").find('a[data-type]').on('click', function () {
- addLine(this)
- })
- } else {
- $(obj).parent().parent().children('ul').children("li:last").find('.item-field').on('click', function (e) {
- e.stopPropagation();
- showColums(this);
- })
- $(obj).parent().parent().children('ul').children("li:last").find('.item-type').on('click', function (e) {
- e.stopPropagation();
- showTypes(this);
- })
- $(obj).parent().parent().children('ul').children("li:last").find('.item-value').on('click', function (e) {
- e.stopPropagation();
- showValue(this);
- })
- }
- $(obj).parent().parent().children('ul').children("li:last").children('.delete-item').on('click', function () {
- var id = $(this).parent().data('id'),
- refresh = $('.soul-edit-out .out_auto').prop('checked');
- $(this).parent().remove();
- _this.updateWhere(myTable, {
- id: id,
- delete: true
- })
- if (refresh) {
- _this.soulReload(myTable);
- }
- })
- }
- }
- , hideColumns: function (myTable, animate) {
- var tableId = myTable.id;
-
- $('#soul-columns' + tableId).removeClass().addClass('fadeOutLeft animated')
- if (columnsTimeOut) {
- clearTimeout(columnsTimeOut)
- }
- if (typeof animate === 'undefined' || animate) {
- columnsTimeOut = setTimeout(function (e) {
- $('#soul-columns' + tableId).hide();
- }, 500)
- } else {
- $('[id^=soul-columns]').hide();
- }
-
- }
- , hideDropList: function (myTable, animate) {
- var tableId = myTable.id;
- $('#soul-dropList' + tableId).removeClass().addClass('fadeOutLeft animated')
- if (dorpListTimeOut) {
- clearTimeout(dorpListTimeOut);
- }
- if (typeof animate === 'undefined' || animate) {
- dorpListTimeOut = setTimeout(function (e) {
- $('#soul-dropList' + tableId).hide();
- }, 500)
- } else {
- $('[id^=soul-dropList]').hide();
- }
-
- }
- , hideCondition: function (myTable, animate) {
- var tableId = myTable.id;
- $('#soul-condition' + tableId).removeClass().addClass('fadeOutLeft animated')
- if (conditionTimeOut) {
- clearTimeout(conditionTimeOut);
- }
- if (typeof animate === 'undefined' || animate) {
- conditionTimeOut = setTimeout(function (e) {
- $('#soul-condition' + tableId).hide();
- }, 500)
- } else {
- $('[id^=soul-condition]').hide();
- }
- }
- , hideBfPrefix: function (myTable, animate) {
- var tableId = myTable.id;
- $('#soul-bf-prefix' + tableId).removeClass().addClass('fadeOutDown animated')
- if (bfColumnTimeOut) {
- clearTimeout(bfColumnTimeOut);
- }
- if (typeof animate === 'undefined' || animate) {
- bfColumnTimeOut = setTimeout(function () {
- $('#soul-bf-prefix' + tableId).hide();
- }, 500)
- } else {
- $('[id=soul-bf-prefix' + tableId + ']').hide();
- }
- }
- , hideBfColumn: function (myTable, animate) {
- var tableId = myTable.id;
- $('#soul-bf-column' + tableId).removeClass().addClass('fadeOutDown animated')
- if (bfColumnTimeOut) {
- clearTimeout(bfColumnTimeOut);
- }
- if (typeof animate === 'undefined' || animate) {
- bfColumnTimeOut = setTimeout(function () {
- $('#soul-bf-column' + tableId).hide();
- }, 500)
- } else {
- $('[id=soul-bf-column' + tableId + ']').hide();
- }
- }
- , hideBfType: function (myTable, animate) {
- var tableId = myTable.id;
- $('#soul-bf-type' + tableId).removeClass().addClass('fadeOutDown animated')
- if (bfCond1TimeOut) {
- clearTimeout(bfCond1TimeOut);
- }
- if (typeof animate === 'undefined' || animate) {
- bfCond1TimeOut = setTimeout(function () {
- $('#soul-bf-type' + tableId).hide();
- }, 500)
- } else {
- $('[id=soul-bf-type' + tableId + ']').hide();
- }
- }
- , bindFilterClick: function (myTable) {
- var _this = this,
- $table = $(myTable.elem),
- $tableHead = $table.next().children('.layui-table-box').children('.layui-table-header').children('table'),
- $fixedLeftTableHead = $table.next().children('.layui-table-box').children('.layui-table-fixed-l').children('.layui-table-header').children('table'),
- $fixedRigthTableHead = $table.next().children('.layui-table-box').children('.layui-table-fixed-r').children('.layui-table-header').children('table'),
- tableId = myTable.id,
- filterItems = myTable.filter ? myTable.filter.items || defaultFilterItems : defaultFilterItems,
- mainListTimeOut;
-
- // 显示筛选框
- $tableHead.find('.soul-table-filter').off('click').on('click', function (e) {
- e.stopPropagation();
- showFilter($(this))
- });
- $fixedLeftTableHead.find('.soul-table-filter').off('click').on('click', function (e) {
- e.stopPropagation();
- showFilter($(this))
- });
- $fixedRigthTableHead.find('.soul-table-filter').off('click').on('click', function (e) {
- e.stopPropagation();
- showFilter($(this))
- });
-
- function showFilter($that) {
- var curItems = $that.data('items') ? $that.data('items').split(',') : filterItems
- _this.hideColumns(myTable, false);
- _this.hideDropList(myTable, false);
- _this.hideCondition(myTable, false);
- $('[id^=main-list]').hide();
-
- $('#main-list' + tableId).data({ 'field': $that.data('column'), 'split': $that.data('split') });
-
- $('#soul-columns' + tableId + ' [type=checkbox]').attr('disabled', false);
- // if (myTable.cols[0][0].type=='checkbox') {
- // $('#soul-columns'+tableId+' [type=checkbox]:eq('+($that.parents('th').data('key').split('-')[2]-1)+')').attr('disabled', true);
- // } else {
- $('#soul-columns' + tableId + ' li[data-key=' + $that.parents('th').data('key').split('-')[2] + '] [type=checkbox]').attr('disabled', true);
- // }
-
- $('#main-list' + tableId + ' > li').hide()
- // 是否显示排序框
- if ($that.hasClass('layui-table-sort')) {
- $('#main-list' + tableId + ' .soul-sort').show()
- }
- for (var i = 0; i < curItems.length; i++) {
- $('#main-list' + tableId + ' .' + itemsMap[curItems[i]]).show()
- if ($('#main-list' + tableId + ' .' + itemsMap[curItems[i]]).index() !== (i + 2)) {
- $('#main-list' + tableId + '>li:eq("' + (i + 2) + '")').before($('#main-list' + tableId + ' .' + itemsMap[curItems[i]]))
-
- }
- }
- if (mainListTimeOut) {
- clearTimeout(mainListTimeOut)
- }
- var left, animate;
- if ($that.offset().left + $('#main-list' + tableId).outerWidth() < document.body.clientWidth) {
- left = $that.offset().left + 10;
- animate = 'fadeInLeft';
- } else {
- left = $that.offset().left - $('#main-list' + tableId).outerWidth();
- animate = 'fadeInRight';
- }
- $('#main-list' + tableId).data('type', myTable.where.tableFilterType ? JSON.parse(myTable.where.tableFilterType)[$that.data('column')] || '' : '').hide().css({
- 'top': $that.offset().top + 10,
- 'left': left
- }).show().removeClass().addClass(animate + ' animated');
-
- // 排序
- $('#main-list' + tableId + ' .soul-sort').on('click', function (e) {
- $that.siblings('.layui-table-sort').find('.layui-table-sort-' + $(this).data('value')).trigger('click');
- $('#main-list' + tableId).hide();
- })
- form.render('checkbox', 'orm');
- }
-
- $(document).on('click', function (e) {
- $('#main-list' + tableId).hide();
- _this.hideColumns(myTable, false);
- _this.hideDropList(myTable, false);
- _this.hideCondition(myTable, false);
- _this.hideBfPrefix(myTable, false);
- _this.hideBfColumn(myTable, false);
- _this.hideBfType(myTable, false);
- });
- $('#main-list' + tableId + ',#soul-columns' + tableId + ',#soul-dropList' + tableId + ',#soul-condition' + tableId).on('click', function (e) {
- $(this).find('.layui-form-selected').removeClass('layui-form-selected')
- e.stopPropagation();
- });
-
- //渲染底部筛选条件
- _this.renderBottomCondition(myTable);
-
- // 表头样式
- var where = where_cache[myTable.id] || {},
- filterSos = JSON.parse(where.filterSos ? where.filterSos : '[]');
-
- for (var i = 0; i < filterSos.length; i++) {
- if (filterSos[i].head) {
- var hasFilter = false;
- switch (filterSos[i].mode) {
- case 'in':
- if (filterSos[i].values && filterSos[i].values.length > 0) {
- hasFilter = true
- }
- break;
- case 'date':
- if (filterSos[i].type !== 'all' && typeof filterSos[i].value !== 'undefined' && filterSos[i].value !== '') {
- hasFilter = true
- }
- break;
- case 'group':
- if (filterSos[i].children && filterSos[i].children.length > 0) {
- hasFilter = true
- }
- default:
- break;
- }
- $tableHead.find('thead>tr>th[data-field="' + filterSos[i].field + '"] .soul-table-filter').attr('soul-filter', '' + hasFilter);
- $fixedLeftTableHead.find('thead>tr>th[data-field="' + filterSos[i].field + '"] .soul-table-filter').attr('soul-filter', '' + hasFilter);
- $fixedRigthTableHead.find('thead>tr>th[data-field="' + filterSos[i].field + '"] .soul-table-filter').attr('soul-filter', '' + hasFilter);
- }
- }
- }
- , resize: function (myTable) {
- var _this = this,
- $table = $(myTable.elem),
- $tableBox = $table.next().children('.layui-table-box'),
- $tableMain = $tableBox.children('.layui-table-main')
- // 减去底部筛选的高度
- if ($table.next().children('.soul-bottom-contion').length > 0) {
- $table.next().children('.soul-bottom-contion').children('.condition-items').css('width', $table.next().children('.soul-bottom-contion').width() - $table.next().children('.soul-bottom-contion').children('.editCondtion').outerWidth());
-
- var bodyHeight = $table.next().height() - $table.next().children('.soul-bottom-contion').outerHeight()
- if ($table.next().children('.layui-table-tool').length > 0) {
- bodyHeight = bodyHeight - $table.next().children('.layui-table-tool').outerHeight();
- }
- if ($table.next().children('.layui-table-total').length > 0) {
- bodyHeight = bodyHeight - $table.next().children('.layui-table-total').outerHeight();
- }
- if ($table.next().children('.layui-table-page').length > 0) {
- bodyHeight = bodyHeight - $table.next().children('.layui-table-page').outerHeight();
- }
-
- bodyHeight = bodyHeight - $table.next().children('.layui-table-box').children('.layui-table-header').outerHeight();
-
- $table.next().children('.layui-table-box').children('.layui-table-body').height(bodyHeight)
- var fixHeight = bodyHeight - _this.getScrollWidth($tableMain[0])-1,
- layMainTableHeight = $tableMain.children('table').height()
- $table.next().children('.layui-table-box').children('.layui-table-fixed').children('.layui-table-body').height(layMainTableHeight >= fixHeight ? fixHeight : 'auto')
-
- var scollWidth = $tableMain.width() - $tableMain.prop('clientWidth') //纵向滚动条宽度;
- $tableBox.children('.layui-table-fixed-r').css('right', scollWidth - 1);
- }
- }
- /**
- * 同步当前 droplist
- * @param myTable
- * @param field
- */
- , updateDropList: function (myTable, field) {
- var _this = this,
- $table = $(myTable.elem),
- tableId = myTable.id,
- id = $('#soul-dropList' + tableId + '>ul').data('id'),
- $checkedDom = $('#soul-dropList' + tableId + '>ul input[type=checkbox]:checked'),
- values = [],
- head = $('#soul-dropList' + tableId + '>ul').data('head'),
- prefix = $('#soul-dropList' + tableId + '>ul').data('prefix'),
- refresh = $('#soul-dropList' + tableId + '>ul').data('refresh'),
- split = $('#soul-dropList' + tableId + '>ul').data('split');
- if ($checkedDom.length > 0) {
- $checkedDom.each(function () {
- values.push($(this).val())
- })
- }
- var filterSo = {
- id: id,
- head: head,
- prefix: prefix || 'and',
- mode: 'in',
- field: field,
- split: split,
- values: values
- };
- _this.updateWhere(myTable, filterSo);
- if (!id) {
- $('#soul-dropList' + tableId + '>ul').data('id', filterSo.id);
- }
-
- if ($('.soul-edit-out').length > 0) {
- $('.soul-edit-out li[data-id="' + filterSo.id + '"]>.item-value').html('共' + (filterSo.values ? filterSo.values.length : 0) + '条数据')
- }
-
- if (refresh) {
- _this.soulReload(myTable);
- }
- }
- , getFilterSoById: function (filterSos, id) {
- for (var i = 0; i < filterSos.length; i++) {
- if (filterSos[i].id === id) {
- return filterSos[i]
- } else if (filterSos[i].mode === 'group') {
- for (var j = 0; j < filterSos[i].children.length; j++) {
- var filterSo = this.getFilterSoById(filterSos[i].children, id);
- if (filterSo) return filterSo;
- }
- }
- }
- return null
- }
- /**
- * 更新 filter 条件
- * @param myTable
- * @param filterSo
- */
- , updateWhere: function (myTable, filterSo) {
- var _this = this,
- where = where_cache[myTable.id] || {},
- filterSos = JSON.parse(where.filterSos ? where.filterSos : '[]');
-
- if (filterSo.id || filterSo.groupId) {
- for (var i = 0; i < filterSos.length; i++) {
- if (filterSo.delete && filterSos[i].id === filterSo.id) {
- filterSos.splice(i, 1);
- break;
- }
- if (updateFilterSo(filterSos[i], filterSo)) {
- break;
- }
- }
- } else if (!(filterSo.mode === 'in' && !(filterSo.values && filterSo.values.length > 0))) {
- filterSos.push($.extend(filterSo, {
- id: _this.getDifId()
- }))
- }
- where['filterSos'] = JSON.stringify(filterSos);
- myTable.where = where;
- where_cache[myTable.id] = where;
-
- function updateFilterSo(filterSo, newFilterSo) {
- var isMatch = false;
-
- if (filterSo.id === newFilterSo.id) {
- $.extend(filterSo, newFilterSo);
- isMatch = true;
- }
-
- // 在分组中新增
- if (!newFilterSo.id && filterSo.id === newFilterSo.groupId) {
- filterSo.children.push($.extend(newFilterSo, {
- id: _this.getDifId()
- }))
- } else if (filterSo.mode === 'group') {
- for (var i = 0; i < filterSo.children.length; i++) {
- if (newFilterSo.delete && filterSo.children[i].id === newFilterSo.id) {
- filterSo.children.splice(i, 1);
- return true;
- }
- if (updateFilterSo(filterSo.children[i], newFilterSo)) {
- return true;
- }
- }
-
- }
-
- return isMatch;
- }
- }
- /**
- * 根据当前条件重载表格
- * @param myTable 需要重载的表格对象
- * @param isr 是否为筛选重载,为 true 时,不进行筛选的初始化动作(包括渲染dom、请求表头数据等)
- */
- , soulReload: function (myTable, isr) {
- var _this = this,
- $table = $(myTable.elem),
- scrollLeft = $table.next().children('.layui-table-box').children('.layui-table-main').scrollLeft();
-
- isFilterReload[myTable.id] = typeof isr === 'undefined' ? true : isr;
- if (typeof myTable.url !== 'undefined' && !!myTable.url && myTable.page) {
- $table.data('scrollLeft', scrollLeft);
- /**
- * 后台筛选
- */
- table.reload(myTable.id, {
- where: where_cache[myTable.id] || {},
- page: {
- curr: 1 //重新从第 1 页开始
- }
- }, true)
- } else {
- /**
- * 前端筛选
- */
- var where = where_cache[myTable.id] || {},
- filterSos = JSON.parse(where.filterSos ? where.filterSos : '[]'),
- tableFilterTypes = where.tableFilterType ? JSON.parse(where.tableFilterType) : {},
- loading = layer.load(2);
- if (!myTable.page) {
- // 修复前端不分页时,layui table bug 导致的只显示10条数据的问题
- myTable.limit = 100000000
- }
- if (filterSos.length > 0) {
- var newData = [];
- layui.each(cache[myTable.id], function (index, item) {
- var show = true;
-
- for (var i = 0; i < filterSos.length; i++) {
- show = _this.handleFilterSo(filterSos[i], item, tableFilterTypes, show, i === 0)
- }
-
- if (show) {
- newData.push(item)
- }
- })
- if (myTable.page) {
- table.reload(myTable.id, {
- data: newData
- , initSort: myTable.initSort
- , isSoulFrontFilter: true
- , page: {
- curr: 1 //重新从第 1 页开始
- }
- }, true)
- } else {
- var url = myTable.url;
- $table.next().off('click')
- var inst = table.reload(myTable.id, {
- url: ''
- , initSort: myTable.initSort
- , isSoulFrontFilter: true
- , data: newData
- }, true)
- inst.config.url = url;
- }
- myTable.data = newData
-
- } else {
- if (myTable.page) {
- table.reload(myTable.id, {
- data: cache[myTable.id]
- , initSort: myTable.initSort
- , isSoulFrontFilter: true
- , page: {
- curr: 1 //重新从第 1 页开始
- }
- }, true)
- } else {
- table.reload(myTable.id, {
- data: cache[myTable.id]
- , initSort: myTable.initSort
- , isSoulFrontFilter: true
- }, true)
- }
- myTable.data = cache[myTable.id]
- }
- $table.next().children('.layui-table-box').children('.layui-table-main').scrollLeft(scrollLeft);
- layer.close(loading)
- }
- }
- , handleFilterSo: function (filterSo, item, tableFilterTypes, show, first) {
- var isOr = first ? false : filterSo.prefix === 'or',
- field = filterSo.field,
- value = filterSo.value,
- status = true;
-
- // 如果有子元素
- if (filterSo.children && filterSo.children.length > 0) {
- for (var i = 0; i < filterSo.children.length; i++) {
- status = this.handleFilterSo(filterSo.children[i], item, tableFilterTypes, status, i === 0)
- }
- return isOr ? show || status : show && status;
- }
-
- switch (filterSo.mode) {
- case "in":
- if (filterSo.values && filterSo.values.length > 0) {
- if (filterSo.split) {
- var tempList = (item[field] + '').split(filterSo.split);
- var tempStatus = false;
- for (var i = 0; i < tempList.length; i++) {
- if (filterSo.values.indexOf(tempList[i]) !== -1) {
- tempStatus = true;
- }
- }
- status = tempStatus;
- } else {
- status = filterSo.values.indexOf(item[field] + '') !== -1
- }
- } else {
- return show;
- }
- break;
- case "condition":
- if (filterSo.type !== 'null' && filterSo.type !== 'notNull' && (typeof value === 'undefined' || value === '')) {
- return show;
- }
- switch (filterSo.type) {
- case "eq":
- status = isNaN(item[field]) || isNaN(value) ? item[field] === value : Number(item[field]) === Number(value);
- break;
- case "ne":
- status = isNaN(item[field]) || isNaN(value) ? item[field] !== value : Number(item[field]) !== Number(value);
- break;
- case "gt":
- status = isNaN(item[field]) || isNaN(value) ? item[field] > value : Number(item[field]) > Number(value);
- break;
- case "ge":
- status = isNaN(item[field]) || isNaN(value) ? item[field] >= value : Number(item[field]) >= Number(value);
- break;
- case "lt":
- status = isNaN(item[field]) || isNaN(value) ? item[field] < value : Number(item[field]) < Number(value);
- break;
- case "le":
- status = isNaN(item[field]) || isNaN(value) ? item[field] <= value : Number(item[field]) <= Number(value);
- break;
- case "contain":
- status = (item[field] + '').indexOf(value) !== -1;
- break;
- case "notContain":
- status = (item[field] + '').indexOf(value) === -1;
- break;
- case "start":
- status = (item[field] + '').indexOf(value) === 0;
- break;
- case "end":
- var d = (item[field] + '').length - (value + '').length;
- status = d >= 0 && (item[field] + '').lastIndexOf(value) === d;
- break;
- case "null":
- status = typeof item[field] === 'undefined' || item[field] === '' || item[field] === null;
- break;
- case "notNull":
- status = typeof item[field] !== 'undefined' && item[field] !== '' && item[field] !== null;
- break;
- }
- break;
- case "date":
- var dateVal = new Date(Date.parse(item[field].replace(/-/g, "/")));
- switch (filterSo.type) {
- case 'all':
- status = true;
- break;
- case 'yesterday':
- status = item[field] && isBetween(dateVal, getToday() - 86400, getToday() - 1);
- break;
- case 'thisWeek':
- status = item[field] && isBetween(dateVal, getFirstDayOfWeek(), getFirstDayOfWeek() + 86400 * 7 - 1);
- break;
- case 'lastWeek':
- status = item[field] && isBetween(dateVal, getFirstDayOfWeek() - 86400 * 7, getFirstDayOfWeek() - 1);
- break;
- case 'thisMonth':
- status = item[field] && isBetween(dateVal, getFirstDayOfMonth(), getCurrentMonthLast());
- break;
- case 'thisYear':
- status = item[field] && isBetween(dateVal, new Date(new Date().getFullYear(), 1, 1) / 1000, new Date(new Date().getFullYear() + 1, 1, 1) / 1000 - 1);
- break;
- case 'specific':
- var dateFormat = dateVal.getFullYear();
- dateFormat += '-' + (timeAdd0(dateVal.getMonth() + 1));
- dateFormat += '-' + timeAdd0(dateVal.getDate());
- status = item[field] && dateFormat === value
- break;
- }
- break;
- }
-
- // 今天凌晨
- function getToday() {
- return new Date().setHours(0, 0, 0, 0) / 1000;
- }
-
- // 本周第一天
- function getFirstDayOfWeek() {
- var now = new Date();
- var weekday = now.getDay() || 7; //获取星期几,getDay()返回值是 0(周日) 到 6(周六) 之间的一个整数。0||7为7,即weekday的值为1-7
- return new Date(now.setDate(now.getDate() - weekday + 1)).setHours(0, 0, 0, 0) / 1000;//往前算(weekday-1)天,年份、月份会自动变化
- }
-
- //获取当月第一天
- function getFirstDayOfMonth() {
- return new Date(new Date().setDate(1)).setHours(0, 0, 0, 0) / 1000;
- }
-
- //获取当月最后一天最后一秒
- function getCurrentMonthLast() {
- var date = new Date();
- var currentMonth = date.getMonth();
- var nextMonth = ++currentMonth;
- var nextMonthFirstDay = new Date(date.getFullYear(), nextMonth, 1);
- return nextMonthFirstDay / 1000 - 1;
- }
-
- function isBetween(v, a, b) {
- return (v.getTime() / 1000) >= a && (v.getTime() / 1000) <= b;
- }
-
- function timeAdd0(str) {
- str += "";
- if (str.length <= 1) {
- str = '0' + str;
- }
- return str
- }
-
- return isOr ? show || status : show && status;
- }
- , getDifId: function () {
- return maxId++;
- }
- , showDate: function (myTable, field, filterSo, animate, top, left, type, refresh) {
- var _this = this,
- tableId = myTable.id,
- conditionHtml = [],
- documentWidth = document.body.clientWidth,
- animate;
- conditionHtml.push('
');
- $('#soul-condition' + tableId).html(conditionHtml.join(''));
- var filterDate = util.toDateString(new Date(), 'yyyy-MM-dd');
- if (filterSo) {
- $('#soul-condition' + tableId).data({ 'id': filterSo.id, 'head': true });
- $('#soul-condition' + tableId + '>.' + field + 'Condition' + ' [name^=datetime][value="' + filterSo.type + '"]').prop('checked', true);
- if (filterSo.type === 'specific') {
- filterDate = filterSo.value;
- $('#soul-condition' + tableId + ' [name^=staticDate]').val(filterDate.replace('~', ' - '));
- $('#soul-condition' + tableId + ' [name^=staticDate]').removeClass("layui-hide");
- }
- else {
- $('#soul-condition' + tableId + ' [name^=staticDate]').addClass("layui-hide");
- }
- } else {
- $('#soul-condition' + tableId).data({ 'id': '', 'head': true });
- $('#soul-condition' + tableId + '>.' + field + 'Condition' + ' [name^=datetime][value="all"]').prop('checked', true);
- }
- $('#soul-condition' + tableId + ' .specific_value').val(filterDate);
-
- //时间范围改造=
- laydate.render({
- elem: '#soul-condition' + tableId + ' [name^=staticDate]'
- , range: true
- , btns: ['confirm']
- , type: 'date'
- , done: function (value, date, endDate) {
- var StartTime = date.year + "-" + date.month + "-" + date.date;
- var EndTime = endDate.year + "-" + endDate.month + "-" + endDate.date;
- var timeSE = StartTime + "~" + EndTime;
- var id = $('#soul-condition' + tableId).data('id'),
- head = $('#soul-condition' + tableId).data('head')
- $('#soul-condition' + tableId + ' [name^=staticDate]').val(timeSE);
- $('#soul-condition' + tableId + ' [name^=datetime]:checked').prop('checked', false);
- $('#soul-condition' + tableId + ' [name^=datetime][value=specific]').prop('checked', true);
- var filterSo = {
- id: id,
- head: head,
- prefix: head ? 'and' : 'and',
- mode: 'date',
- field: field,
- type: 'specific',
- value: timeSE
- }
- _this.updateWhere(myTable, filterSo);
- if (!id) {
- $('#soul-condition' + tableId).data('id', filterSo.id)
- }
- if ($('.soul-edit-out').length > 0) {
- $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-value').html(filterSo.value)
- }
- if (refresh) {
- _this.soulReload(myTable);
- }
- form.render('radio', 'orm');
- }
- });
-
- form.on('radio(datetime' + tableId + ')', function (data) {
- var id = $('#soul-condition' + tableId).data('id'),
- head = $('#soul-condition' + tableId).data('head')
- var filterSo = {
- id: id,
- head: head,
- prefix: head ? 'and' : 'and',
- mode: 'date',
- field: field,
- type: data.value,
- value: $('#soul-condition' + tableId + ' .specific_value').val()
- }
- if (data.value == "specific") {
- $('#soul-condition' + tableId + ' [name^=staticDate]').removeClass("layui-hide");
- return;
- }
- _this.updateWhere(myTable, filterSo);
- if (!id) {
- $('#soul-condition' + tableId).data('id', filterSo.id)
- }
- if ($('.soul-edit-out').length > 0) {
- $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-value').html(dateTimeItems[filterSo.type] || filterSo.value)
- }
- if (refresh) {
- _this.soulReload(myTable);
- }
- });
- form.render('radio', 'orm')
- if (type === 'down') {
- if (left + $('#soul-condition' + tableId).width() < documentWidth) {
- animate = 'fadeInLeft'
- } else {
- left = left - $('#main-list' + tableId).width() - $('#soul-condition' + tableId).width();
- animate = 'fadeInRight'
- }
- } else {
- top = top - $('#soul-condition' + tableId).outerHeight() - 10;
- }
- $('#soul-condition' + tableId).css({ 'top': top<0?0:top, 'left': left })
- .show().removeClass().addClass(animate + ' animated');
-
- }
- , bottomConditionHtml: function (bcHtml, filterSo, fieldMap, first) {
- var _this = this,
- isOr = filterSo.prefix === 'or',
- field = filterSo.field;
-
- if (filterSo.mode === 'group') {
- if (filterSo.children && filterSo.children.length > 0) {
- bcHtml.push('
');
- if (!first) {
- bcHtml.push('
' + (isOr ? '或' : '与') + '
');
- }
-
- for (var i = 0; i < filterSo.children.length; i++) {
- _this.bottomConditionHtml(bcHtml, filterSo.children[i], fieldMap, i === 0);
- }
- bcHtml.push('
');
- bcHtml.push('
')
- }
- return;
- }
- bcHtml.push('
');
- if (!first) {
- bcHtml.push('
' + (isOr ? '或' : '与') + '
');
- }
- bcHtml.push('
' + fieldMap[field].title + '
');
- bcHtml.push('
');
- switch (filterSo.mode) {
- case 'in':
- bcHtml.push('筛选数据');
- break;
- case 'condition':
- bcHtml.push(conditionChangeItems[filterSo.type]);
- break;
- case 'date':
- bcHtml.push('选择日期');
- break;
- default:
- bcHtml.push('未知');
- break;
- }
- bcHtml.push('
');
- if (filterSo.type !== 'null' && filterSo.type !== 'notNull') {
- bcHtml.push('
');
- switch (filterSo.mode) {
- case 'in':
- bcHtml.push('共' + (filterSo.values ? filterSo.values.length : 0) + '条数据');
- break;
- case 'date':
- bcHtml.push(filterSo.type === 'specific' ? filterSo.value || '请选择' : dateTimeItems[filterSo.type])
- break;
- case 'condition':
- default:
- bcHtml.push(typeof filterSo.value === 'undefined' || filterSo.value === '' ? '请输入...' : filterSo.value);
- break;
- }
-
- bcHtml.push('
')
- }
- bcHtml.push('
');
- bcHtml.push('
')
- }
- , renderBottomCondition: function (myTable) {
- var _this = this,
- where = where_cache[myTable.id] || {},
- filterSos = where.filterSos ? JSON.parse(where.filterSos) : [],
- tableFilterTypes = where.tableFilterType ? JSON.parse(where.tableFilterType) : {},
- $table = $(myTable.elem),
- tableId = myTable.id,
- $bottomCondition = $table.next().children('.soul-bottom-contion'),
- fieldMap = {}, bcHtml = [], curItems,
- filterItems = myTable.filter ? myTable.filter.items || defaultFilterItems : defaultFilterItems,
- columns = _this.getCompleteCols(myTable.cols);
- for (var i = 0; i < columns.length; i++) {
- if (columns[i].field && columns[i].filter) {
- curItems = columns[i].filter.items || filterItems;
- if (curItems.indexOf('data') !== -1 || curItems.indexOf('condition') !== -1) {
- fieldMap[columns[i]['field']] = {
- title: columns[i].title,
- items: curItems
- }
- }
- }
- }
-
- /**
- * 一、拼装底部内容
- */
- for (var i = 0; i < filterSos.length; i++) {
- _this.bottomConditionHtml(bcHtml, filterSos[i], fieldMap, i === 0);
- }
- $bottomCondition.children('.condition-items').html(bcHtml.join(''))
-
- /**
- * 二、组装底部弹窗条件
- */
- bcHtml = [];
- // 1. prefix
- if ($('#soul-bf-prefix' + tableId).length === 0) {
- bcHtml.push('
')
- bcHtml.push('与 ')
- bcHtml.push('或 ')
- bcHtml.push(' ')
- }
- // 2. 列选择
- if ($('#soul-bf-column' + tableId).length === 0) {
- bcHtml.push('
')
- for (var field in fieldMap) {
- bcHtml.push('' + fieldMap[field].title + ' ')
- }
- bcHtml.push(' ')
- }
-
- // 3. 条件选择
- if ($('#soul-bf-type' + tableId).length === 0) {
- bcHtml.push('
')
- bcHtml.push('筛选数据 ')
- bcHtml.push('选择日期 ')
- for (var key in conditionChangeItems) {
- bcHtml.push('' + conditionChangeItems[key] + ' ')
- }
- bcHtml.push(' ')
- }
-
- // 4. 值选择
- if ($('#soul-bf-cond2-dropList' + tableId).length === 0) {
- bcHtml.push('
')
- }
-
-
- $('body').append(bcHtml.join(''))
-
- /**
- * 三、底部弹窗事件
- */
- // 1. prefix弹出事件
- $bottomCondition.find('.item-prefix').off('click').on('click', function (e) {
- e.stopPropagation();
- $('#main-list' + tableId).hide();
- _this.hideDropList(myTable);
- _this.hideCondition(myTable);
- _this.hideColumns(myTable);
- _this.hideBfColumn(myTable);
- _this.hideBfType(myTable);
- var top = $(this).offset().top - $('#soul-bf-prefix' + tableId).outerHeight() - 10,
- left = $(this).offset().left;
-
- $('#soul-bf-prefix' + tableId).find('li.soul-bf-selected').removeClass('soul-bf-selected')
- $('#soul-bf-prefix' + tableId)
- .data('id', $(this).parent().data('id'))
- .data('prefix', $(this).parent().data('prefix'))
- .data('refresh', true)
- .show()
- .css({ top: top, left: left })
- .removeClass().addClass('fadeInUp animated')
- .find('li[data-value="' + $(this).parent().data('prefix') + '"]')
- .addClass('soul-bf-selected')
-
- })
- // 2. 弹出列选择
- $bottomCondition.find('.item-field').off('click').on('click', function (e) {
- e.stopPropagation();
- $('#main-list' + tableId).hide();
- _this.hideDropList(myTable);
- _this.hideCondition(myTable);
- _this.hideColumns(myTable);
- _this.hideBfPrefix(myTable)
- _this.hideBfType(myTable);
- var top = $(this).offset().top - $('#soul-bf-column' + tableId).outerHeight() - 10,
- left = $(this).offset().left;
-
- $('#soul-bf-column' + tableId).find('li.soul-bf-selected').removeClass('soul-bf-selected')
- $('#soul-bf-column' + tableId)
- .data('field', $(this).parent().data('field'))
- .data('id', $(this).parent().data('id'))
- .data('mode', $(this).parent().data('mode'))
- .data('group', $(this).parent().parent().data('id') || '')
- .data('refresh', true)
- .show()
- .css({ top: top, left: left })
- .removeClass().addClass('fadeInUp animated')
- .find('li[data-field="' + $(this).parent().data('field') + '"]')
- .addClass('soul-bf-selected')
- })
-
- // 3. 弹出方式选择
- $bottomCondition.find('.item-type').on('click', function (e) {
- e.stopPropagation();
- $('#main-list' + tableId).hide();
- _this.hideDropList(myTable);
- _this.hideCondition(myTable);
- _this.hideColumns(myTable);
- _this.hideBfColumn(myTable);
- _this.hideBfPrefix(myTable);
- var field = $(this).parent().data('field')
- $('#soul-bf-type' + tableId + ' li').hide()
- if (tableFilterTypes[field] && tableFilterTypes[field].indexOf('date') === 0) {
- $('#soul-bf-type' + tableId + ' li[data-mode=date]').show()
- }
- if (fieldMap[field].items.indexOf('data') !== -1) {
- $('#soul-bf-type' + tableId + ' li[data-mode=in]').show()
- }
- if (fieldMap[field].items.indexOf('condition') !== -1) {
- $('#soul-bf-type' + tableId + ' li[data-mode=condition]').show()
- }
-
- var top = $(this).offset().top - $('#soul-bf-type' + tableId).outerHeight() - 10,
- left = $(this).offset().left;
- $('#soul-bf-type' + tableId).find('li.soul-bf-selected').removeClass('soul-bf-selected')
- switch ($(this).parent().data('mode')) {
- case 'in':
- $('#soul-bf-type' + tableId).find('li[data-mode="in"]')
- .addClass('soul-bf-selected')
- break;
- case 'date':
- $('#soul-bf-type' + tableId).find('li[data-mode="date"]')
- .addClass('soul-bf-selected')
- case 'condition':
- $('#soul-bf-type' + tableId).find('li[data-value="' + $(this).parent().data('type') + '"]')
- .addClass('soul-bf-selected')
- }
-
- $('#soul-bf-type' + tableId)
- .data('type', $(this).parent().data('type'))
- .data('mode', $(this).parent().data('mode'))
- .data('id', $(this).parent().data('id'))
- .data('group', $(this).parent().parent().data('id') || '')
- .data('refresh', true)
- .show()
- .css({ top: top, left: left })
- .removeClass().addClass('fadeInUp animated')
- })
-
- // 4. 弹出值选择
- $bottomCondition.find('.item-value').on('click', function (e) {
- e.stopPropagation();
- $('#main-list' + tableId).hide();
- _this.hideColumns(myTable);
- _this.hideBfType(myTable);
- _this.hideBfPrefix(myTable)
- _this.hideBfColumn(myTable);
- var top,
- left = $(this).offset().left,
- mode = $(this).parent().data('mode'),
- field = $(this).parent().data('field'),
- id = $(this).parent().data('id'),
- head = $(this).parent().data('head'),
- prefix = $(this).parent().data('prefix');
-
- switch (mode) {
- case 'in':
- _this.hideCondition(myTable);
- if (dorpListTimeOut) {
- clearTimeout(dorpListTimeOut);
- }
- $('#soul-dropList' + tableId + '>.filter-search>input').val('');
- $('#soul-dropList' + tableId).show();
- $('#soulDropList' + tableId).find('.' + field + 'DropList li input[type=checkbox]:checked').prop('checked', false);
- var filterSo = _this.getFilterSoById(filterSos, id);
- for (var i = 0; i < filterSo.values.length; i++) {
- $('#soulDropList' + tableId).find('.' + field + 'DropList li input[type=checkbox][value="' + filterSo.values[i] + '"]').prop('checked', true);
- }
-
- $('#soul-dropList' + tableId + '>ul').data('id', id).data('head', head).data('refresh', true).data('prefix', prefix).html($('#soulDropList' + tableId).find('.' + field + 'DropList li').clone());
- form.render('checkbox', 'orm');
- top = $(this).offset().top - $('#soul-dropList' + tableId).outerHeight() - 10;
- $('#soul-dropList' + tableId).css({ 'top': top, 'left': left })
- .show().removeClass().addClass('fadeInUp animated');
- setTimeout(function () {
- $('#soul-dropList' + tableId + '>.filter-search>input').focus() // 聚焦搜索框
- }, 1);
-
-
- // 监听筛选数据
- var liClick = true;
- form.on('checkbox(soulDropList' + tableId + ')', function (data) {
- liClick = false;
- _this.updateDropList(myTable, field);
- });
-
- $('#soul-dropList' + tableId + '>ul>li[data-value]').on('click', function () {
- if (liClick) {
- $(this).find('div.layui-form-checkbox').trigger('click');
- }
- liClick = true;
- })
- break;
- case 'date':
- _this.hideDropList(myTable);
- if (conditionTimeOut) {
- clearTimeout(conditionTimeOut);
- }
- var filterSo = _this.getFilterSoById(filterSos, id),
- top = $(this).offset().top - 10;
-
- _this.showDate(myTable, field, filterSo, "fadeInUp", top, left, "up", true);
- break;
- default:
- _this.hideDropList(myTable);
- if (conditionTimeOut) {
- clearTimeout(conditionTimeOut);
- }
- var obj = this,
- value = $(this).parents('.condition-item:eq(0)').data('value');
- $(obj).hide();
- $(obj).after('
')
- $(obj).next().children().val(value).select().on('keydown', function (e) {
- if (e.keyCode === 13) {
- $(this).blur();
- }
- }).on('blur', function () {
- var newValue = $(this).val();
- $(obj).html(typeof newValue === 'undefined' || newValue === '' ? '请输入...' : newValue);
- $(obj).show();
- $(this).parent().remove()
- if (newValue !== value) {
- _this.updateWhere(myTable, {
- id: id,
- value: newValue
- })
- _this.soulReload(myTable);
- }
- })
-
- break;
- }
- })
-
- /**
- * 三、选择事件
- */
- // 1. 选择prefix
- $('#soul-bf-prefix' + tableId + '>ul>li').off('click').on('click', function () {
- var id = $(this).parent().parent().data('id'),
- newPrefix = $(this).data('value'),
- oldPrefix = $(this).parent().parent().data('prefix'),
- refresh = $(this).parent().parent().data('refresh');
-
- if (oldPrefix !== newPrefix) {
- _this.updateWhere(myTable, {
- id: id,
- prefix: newPrefix
- });
- if (refresh === true) {
- _this.soulReload(myTable);
- }
- }
- })
- // 1. 选择列
- $('#soul-bf-column' + tableId + '>ul>li').off('click').on('click', function () {
- var oldField = $(this).parent().parent().data('field'),
- newField = $(this).data('field'),
- mode = $(this).parent().parent().data('mode'),
- group = $(this).parent().parent().data('group'),
- refresh = $(this).parent().parent().data('refresh');
-
- if (oldField !== newField) {
- var filterSo = {
- id: $(this).parent().parent().data('id'),
- field: newField
- }
- if (fieldMap[newField].items.indexOf(modeMapItems[mode]) === -1) {
- $.extend(filterSo, $.extend({}, revertMode[modeMapItems[mode]],
- revertMode[modeMapItems[mode]].mode === 'condition' && _this.startsWith(tableFilterTypes[newField], 'date')
- ? {
- mode: 'date',
- type: 'all'
- } : {}))
- } else {
- // 重置values值
- if (mode === 'in') {
- $.extend(filterSo, {
- values: []
- })
- } else if (mode === 'date' && !(_this.startsWith(tableFilterTypes[newField], 'date'))) {
- $.extend(filterSo, {
- mode: 'condition',
- type: 'eq',
- value: ''
- })
- } else if (mode !== 'date' && _this.startsWith(tableFilterTypes[newField], 'date')) {
- $.extend(filterSo, {
- mode: 'date',
- type: 'all'
- })
- }
- }
- // 如果是头部条件,选择列是清除
- if (group) {
- _this.updateWhere(myTable, {
- id: group,
- head: false
- })
- }
- _this.updateWhere(myTable, filterSo);
-
- if ($('.soul-edit-out').length > 0) {
- $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-field').html(fieldMap[newField].title);
- if (filterSo.mode === 'in') {
- $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-type').html('筛选数据')
- $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-value').html('共0条数据')
- } else if (mode !== filterSo.mode) {
- if (filterSo.mode === 'date') {
- $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-type').html('选择日期')
- $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-value').html(dateTimeItems[filterSo.type])
- } else if (filterSo.mode === 'condition') {
- $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-type').html(conditionChangeItems[filterSo.type])
- $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-value').html(filterSo.value === '' ? '请输入...' : filterSo.value)
- }
- }
- }
-
- if (refresh === true) {
- _this.soulReload(myTable);
- }
- }
- })
-
- // 2. 选择类型
- $('#soul-bf-type' + tableId + '>ul>li').off('click').on('click', function () {
- var newType = $(this).data('value') + "" // 引号修复为空(null值)传递问题
- , newMode = $(this).data('mode')
- , type = $(this).parent().parent().data('type')
- , mode = $(this).parent().parent().data('mode')
- , group = $(this).parent().parent().data('group')
- , refresh = $(this).parent().parent().data('refresh')
- if (type !== newType) {
-
- var filterSo = {
- id: $(this).parent().parent().data('id'),
- type: newType,
- mode: newMode
- }
- if (mode !== newMode) {
- $.extend(filterSo, {
- value: '',
- values: []
- })
- }
-
- // 如果是头部条件,选择列是清除
- if (group && newMode === 'in') {
- _this.updateWhere(myTable, {
- id: group,
- head: false
- })
- }
- _this.updateWhere(myTable, filterSo)
-
- if ($('.soul-edit-out').length > 0) {
- $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-value').show();
- $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-type').html(conditionChangeItems[newType] || (newMode === 'in' ? '筛选数据' : '选择日期'));
- switch (newMode) {
- case 'in':
- $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-value').html('共0条数据');
- break;
- case 'date':
- $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-value').html(dateTimeItems[newType]);
- break;
- case 'condition':
- if (mode !== newMode) {
- $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-value').html('请输入...');
- }
- $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-value')[newType === 'null' || newType === 'notNull' ? 'hide' : 'show']()
-
- break;
- }
- }
-
- // 是否立即更新
- if (refresh === true) {
- _this.soulReload(myTable);
- }
- }
- })
-
- /**
- * 五、底部筛选条件删除事件
- */
- $bottomCondition.find('.condition-items .condition-item .condition-item-close').on('click', function () {
- _this.updateWhere(myTable, {
- id: $(this).parents('.condition-item:eq(0)').data('id'),
- delete: true
- })
- _this.soulReload(myTable);
- })
-
- }
- /**
- * 导出 excel 文件
- * @param myTable
- * @param curExcel
- */
- , export: function (myTable, curExcel) {
- if (typeof myTable === 'string') {
- myTable = table_cache[myTable] // tableId 转 myTable
- }
- var loading = layer.msg('文件下载中', {
- icon: 16
- , time: -1
- , anim: -1
- , fixed: false
- });
- var cols = this.deepClone(myTable.cols)
- , style = myTable.elem.next().find('style')[0]
- , sheet = style.sheet || style.styleSheet || {}
- , rules = sheet.cssRules || sheet.rules;
-
- layui.each(rules, function (i, item) {
- if (item.style.width) {
- var keys = item.selectorText.split('-');
- cols[keys[3]][keys[4]]['width'] = parseInt(item.style.width)
- }
- })
-
- var data = JSON.parse(JSON.stringify(myTable.data || cache[myTable.id])),
- showField = {},
- widths = {},
- mergeArrays = [], // 合并配置
- heightConfig = {},
- $table = $(myTable.elem),
- $tableBody = $table.next().children('.layui-table-box').children('.layui-table-body').children('table'),
- $tableTotal = myTable.totalRow ? $table.next().children('.layui-table-total').children(":first") : null,
- finalExcel = Object.assign({}, myTable.excel, curExcel);
-
- var filename = finalExcel.filename ? (typeof finalExcel.filename === 'function' ? finalExcel.filename.call(this) : finalExcel.filename) : '表格数据.xlsx',
- checked = finalExcel.checked === true,
- curPage = finalExcel.curPage === true,
- customColumns = finalExcel.columns,
- totalRow = finalExcel.totalRow,
- type = filename.substring(filename.lastIndexOf('.') + 1, filename.length),
- tableStartIndex = finalExcel.add && finalExcel.add.top && Array.isArray(finalExcel.add.top.data) ? finalExcel.add.top.data.length + 1 : 1, //表格内容从哪一行开始
- bottomLength = finalExcel.add && finalExcel.add.bottom && Array.isArray(finalExcel.add.bottom.data) ? finalExcel.add.bottom.data.length : 0,// 底部自定义行数
- i, j, k;
-
- if (finalExcel.data) {
- if (Array.isArray(finalExcel.data)) {
- data = finalExcel.data
- } else {
- console.error('导出指定数据 data 不符合数组格式', finalExcel.data)
- layer.close(loading)
- return;
- }
- } else if (checked) { // 获取选中行数据
- // data = table.checkStatus(myTable.id).data;
- data = []
- if (cache[myTable.id] && cache[myTable.id].length > 0) {
- for (i = 0; i < cache[myTable.id].length; i++) {
- if (cache[myTable.id][i][table.config.checkName]) {
- data.push(cache[myTable.id][i])
- }
- }
- }
- } else if (curPage) {
- data = layui.table.cache[myTable.id]
- } else if (myTable.url && myTable.page) {
- var ajaxStatus = true;
- var searchParam = isFilterCache[myTable.id] ? where_cache[myTable.id] : table_cache[myTable.id].where;
- if (myTable.contentType && myTable.contentType.indexOf("application/json") == 0) { //提交 json 格式
- searchParam = JSON.stringify(searchParam);
- }
- $.ajax({
- url: myTable.url,
- data: searchParam,
- dataType: 'json',
- method: myTable.method || 'post',
- async: false,
- cache: false,
- headers: myTable.headers || {},
- contentType: myTable.contentType,
- success: function (res) {
- if (typeof myTable.parseData === 'function') {
- res = myTable.parseData(res) || res;
- }
- //检查数据格式是否符合规范
- if (res[myTable.response.statusName] != myTable.response.statusCode) {
- layer.msg('返回的数据不符合规范,正确的成功状态码应为:"' + myTable.response.statusName + '": ' + myTable.response.statusCode, {
- icon: 2,
- anim: 6
- });
- } else {
- data = res[myTable.response.dataName]
- }
- },
- error: function (res) {
- layer.msg('请求异常!', { icon: 2, anim: 6 });
- ajaxStatus = false;
- }
- })
- if (!ajaxStatus) {
- return;
- }
- } else {
- var $sortDoom = $table.next().children('.layui-table-box').children('.layui-table-header').find('.layui-table-sort[lay-sort$="sc"]:eq(0)')
- if ($sortDoom.length > 0) {
- var sortField = $sortDoom.parent().parent().data('field');
- var sortOrder = $sortDoom.attr('lay-sort');
- switch (sortOrder) {
- case 'asc':
- data = layui.sort(data, sortField);
- break;
- case 'desc':
- data = layui.sort(data, sortField, true);
- break;
- default:
- break;
- }
- }
- }
-
- // 制定显示列和顺序
- var tempArray, cloneCol, columnsMap = [], curRowUnShowCount;
- for (i = 0; i < cols.length; i++) {
- curRowUnShowCount = 0;
- for (j = 0; j < cols[i].length; j++) {
- if (!cols[i][j].exportHandled) {
- if (cols[i][j].rowspan > 1) {
- if ((cols[i][j].field || cols[i][j].type === 'numbers') && !cols[i][j].hide) {
- mergeArrays.push([numberToLetter(j + 1 - curRowUnShowCount) + (i + tableStartIndex), numberToLetter(j + 1 - curRowUnShowCount) + (i + parseInt(cols[i][j].rowspan) + tableStartIndex - 1)])
- } else {
- curRowUnShowCount++;
- }
- cloneCol = this.deepClone(cols[i][j])
- cloneCol.exportHandled = true;
- k = i + 1;
- while (k < cols.length) {
- cols[k].splice(j, 0, cloneCol)
- k++
- }
- }
- if (cols[i][j].colspan > 1) {
- mergeArrays.push([numberToLetter(j + 1 - curRowUnShowCount) + (i + tableStartIndex), numberToLetter(j + parseInt(cols[i][j].colspan) - curRowUnShowCount) + (i + tableStartIndex)])
- cloneCol = this.deepClone(cols[i][j])
- cloneCol.exportHandled = true;
- for (k = 1; k < cols[i][j].colspan; k++) {
- cols[i].splice(j, 0, cloneCol)
- }
- j = j + parseInt(cols[i][j].colspan) - 1
-
- }
- } else if (!((cols[i][j].field || cols[i][j].type === 'numbers') && !cols[i][j].hide)) {
- curRowUnShowCount++;
- }
- }
- }
- var columns = cols[cols.length - 1]; // 获取真实列
-
- // 处理数据
- for (i = 0; i < data.length; i++) {
- for (j = 0; j < columns.length; j++) {
- if ((columns[j].field || columns[j].type === 'numbers') && (customColumns && Array.isArray(customColumns) || !columns[j].hide)) {
- data[i][columns[j].key] = data[i][columns[j].field || columns[j]['LAY_INDEX']]
- }
- }
- }
-
- // 处理合计行
- if (totalRow !== false && myTable.totalRow) {
- var obj = {}, totalRows = {};
- if (typeof totalRow === 'object' && totalRow.type === 'origin') {
- // 通过 dom 解析
- for (i = 0; i < columns.length; i++) {
- if (columns[i].field) {
- obj[columns[i].key] = $tableTotal.find('[data-field="' + columns[i].field + '"]').text().trim()
- }
- }
- data.push(obj);
- } else {
- // 通过数据解析
- for (i = 0; i < columns.length; i++) {
- if (columns[i].totalRowText) {
- obj[columns[i].key] = columns[i].totalRowText
- } else if (columns[i].totalRow) {
- totalRows[columns[i].key] = 0
- }
- }
- if (JSON.stringify(totalRows) !== '{}') {
- for (i = 0; i < data.length; i++) {
- for (var key in totalRows) {
- totalRows[key] = (parseFloat(totalRows[key]) + (parseFloat(data[i][key]) || 0)).toFixed(2)
- }
- }
- }
- data.push(Object.assign(obj, totalRows));
- }
- }
-
- if (customColumns && Array.isArray(customColumns)) {
- // 自定义表头
- var tempCustomColumns = [];
- tempArray = {};
- mergeArrays = []; // 重置表头合并列
- columnsMap[0] = {};
- for (i = 0; i < customColumns.length; i++) {
- for (j = 0; j < columns.length; j++) {
- if (columns[j].field === customColumns[i]) {
- columns[j].hide = false
- tempCustomColumns.push(columns[j]);
- columnsMap[0][columns[j].key] = columns[j];
- tempArray[columns[j].key] = $('
' + columns[j].title + '
').text()
- break;
- }
- }
- }
- columns = tempCustomColumns;
- data.splice(0, 0, tempArray)
- } else {
- // 拼接表头数据
- for (i = 0; i < cols.length; i++) {
- columnsMap[i] = {}
- tempArray = {}
- for (j = 0; j < cols[i].length; j++) {
- columnsMap[i][cols[cols.length - 1][j].key] = cols[i][j];
- tempArray[cols[cols.length - 1][j].key] = $('
' + cols[i][j].title + '
').text()
- }
- data.splice(i, 0, tempArray)
- }
- }
-
- //添加自定义内容
- if (finalExcel.add) {
- var addTop = finalExcel.add.top,
- addBottom = finalExcel.add.bottom,
- startPos, endPos, jumpColsNum;
-
- if (addTop && Array.isArray(addTop.data) && addTop.data.length > 0) {
-
- for (i = 0; i < addTop.data.length; i++) {
- tempArray = {}, jumpColsNum = 0;
- for (j = 0; j < (addTop.data[i].length > columns.length ? addTop.data[i].length : columns.length); j++) {
- if ((columns[j].field || columns[j].type === 'numbers') && !columns[j].hide) {
- tempArray[columns[j] ? columns[j].key : j + ''] = addTop.data[i][j - jumpColsNum] || ''
- } else {
- jumpColsNum++
- }
- }
- data.splice(i, 0, tempArray);
- }
-
- if (Array.isArray(addTop.heights) && addTop.heights.length > 0) {
- for (i = 0; i < addTop.heights.length; i++) {
- heightConfig[i] = addTop.heights[i]
- }
- }
-
- if (Array.isArray(addTop.merge) && addTop.merge.length > 0) {
- for (i = 0; i < addTop.merge.length; i++) {
- if (addTop.merge[i].length === 2) {
- startPos = addTop.merge[i][0].split(',');
- endPos = addTop.merge[i][1].split(',');
- mergeArrays.push([numberToLetter(startPos[1]) + startPos[0], numberToLetter(endPos[1]) + endPos[0]])
- }
-
- }
- }
- }
- if (addBottom && Array.isArray(addBottom.data) && addBottom.data.length > 0) {
- for (i = 0; i < addBottom.data.length; i++) {
- tempArray = {}, jumpColsNum = 0;
- for (j = 0; j < (addBottom.data[i].length > columns.length ? addBottom.data[i].length : columns.length); j++) {
- if ((columns[j].field || columns[j].type === 'numbers') && !columns[j].hide) {
- tempArray[columns[j] ? columns[j].key : j + ''] = addBottom.data[i][j - jumpColsNum] || ''
- } else {
- jumpColsNum++
- }
- }
- data.push(tempArray);
- }
-
- if (Array.isArray(addBottom.heights) && addBottom.heights.length > 0) {
- for (i = 0; i < addBottom.heights.length; i++) {
- heightConfig[data.length - addBottom.data.length + i] = addBottom.heights[i]
- }
- }
-
- if (Array.isArray(addBottom.merge) && addBottom.merge.length > 0) {
- for (i = 0; i < addBottom.merge.length; i++) {
- if (addBottom.merge[i].length === 2) {
- startPos = addBottom.merge[i][0].split(',');
- endPos = addBottom.merge[i][1].split(',');
- mergeArrays.push([numberToLetter(startPos[1]) + (data.length - addBottom.data.length + parseInt(startPos[0])), numberToLetter(endPos[1]) + (data.length - addBottom.data.length + parseInt(endPos[0]))])
- }
- }
- }
- }
- }
-
- var index = 0, alignTrans = { 'left': 'left', 'center': 'center', 'right': 'right' },
- borderTypes = ['top', 'bottom', 'left', 'right'];
- for (i = 0; i < columns.length; i++) {
- if ((columns[i].field || columns[i].type === 'numbers') && !columns[i].hide) {
- if (columns[i].width) {
- widths[String.fromCharCode(64 + parseInt(++index))] = columns[i].width
- }
- showField[columns[i].key] = function (field, line, data, curIndex) {
- var bgColor = 'ffffff', color = '000000', family = 'Calibri', size = 12, cellType = 's',
- bodyIndex = curIndex - (customColumns ? 1 : cols.length) - tableStartIndex + 1,
- border = {
- top: {
- style: 'thin',
- color: { indexed: 64 }
- },
- bottom: {
- style: 'thin',
- color: { indexed: 64 }
- },
- left: {
- style: 'thin',
- color: { indexed: 64 }
- },
- right: {
- style: 'thin',
- color: { indexed: 64 }
- }
- }
- if (finalExcel.border) {
- for (j = 0; j < borderTypes.length; j++) {
- if (finalExcel.border[borderTypes[j]]) {
- border[borderTypes[j]].style = finalExcel.border[borderTypes[j]].style || border[borderTypes[j]].style
- border[borderTypes[j]].color = handleRgb(finalExcel.border[borderTypes[j]].color) || border[borderTypes[j]].color
- } else if (finalExcel.border['color'] || finalExcel.border['style']) {
- border[borderTypes[j]].style = finalExcel.border['style'] || border[borderTypes[j]].style
- border[borderTypes[j]].color = handleRgb(finalExcel.border['color']) || border[borderTypes[j]].color
- }
- }
- }
- if (curIndex < tableStartIndex - 1 || curIndex >= data.length - bottomLength) {
- return {
- v: line[field] || '',
- s: {// s 代表样式
- alignment: {
- horizontal: 'center',
- vertical: 'center'
- },
- font: { name: family, sz: size, color: { rgb: color } },
- fill: {
- fgColor: { rgb: bgColor, bgColor: { indexed: 64 } }
- },
- border: border
- },
- t: cellType
- }
- } else if (bodyIndex < 0) {
- // 头部样式
- bgColor = 'C7C7C7';
- if (finalExcel.head) {
- bgColor = finalExcel.head.bgColor || bgColor;
- color = finalExcel.head.color || color;
- family = finalExcel.head.family || family;
- size = finalExcel.head.size || size;
- }
- } else {
- // 默认全局字体样式
- if (finalExcel.font) {
- bgColor = finalExcel.font.bgColor || bgColor;
- color = finalExcel.font.color || color;
- family = finalExcel.font.family || family;
- size = finalExcel.font.size || size;
- }
- // 默认全局边框样式
- if (finalExcel.border) {
- for (j = 0; j < borderTypes.length; j++) {
- if (finalExcel.border[borderTypes[j]]) {
- border[borderTypes[j]].style = finalExcel.border[borderTypes[j]].style || border[borderTypes[j]].style
- border[borderTypes[j]].color = handleRgb(finalExcel.border[borderTypes[j]].color) || border[borderTypes[j]].color
- } else if (finalExcel.border['color'] || finalExcel.border['style']) {
- border[borderTypes[j]].style = finalExcel.border['style'] || border[borderTypes[j]].style
- border[borderTypes[j]].color = handleRgb(finalExcel.border['color']) || border[borderTypes[j]].color
- }
- }
- }
- // 列上配置了自定义样式
- if (columnsMap[columnsMap.length - 1][field].excel) {
- var colExcel = typeof columnsMap[columnsMap.length - 1][field].excel === 'function' ? columnsMap[columnsMap.length - 1][field].excel.call(this, line, bodyIndex, data.length - cols.length - tableStartIndex + 1 - bottomLength) : columnsMap[columnsMap.length - 1][field].excel
- if (colExcel) {
- bgColor = colExcel.bgColor || bgColor;
- color = colExcel.color || color;
- family = colExcel.family || family;
- size = colExcel.size || size;
- cellType = colExcel.cellType || cellType;
-
- if (colExcel.border) {
- for (j = 0; j < borderTypes.length; j++) {
- if (colExcel.border[borderTypes[j]]) {
- border[borderTypes[j]].style = colExcel.border[borderTypes[j]].style || border[borderTypes[j]].style
- border[borderTypes[j]].color = handleRgb(colExcel.border[borderTypes[j]].color) || border[borderTypes[j]].color
- } else if (colExcel.border['color'] || colExcel.border['style']) {
- border[borderTypes[j]].style = colExcel.border['style'] || border[borderTypes[j]].style
- border[borderTypes[j]].color = handleRgb(colExcel.border['color']) || border[borderTypes[j]].color
- }
- }
- }
- }
- }
- }
-
- function handleNull(val) {
- if (typeof val === 'undefined' || val === null) {
- return ""
- }
- return val;
- }
-
- var value = bodyIndex >= 0 && columnsMap[columnsMap.length - 1][field].templet ?
- typeof columnsMap[columnsMap.length - 1][field].templet === 'function' ?
- $('
' + columnsMap[columnsMap.length - 1][field].templet(line) + '
').find(':input').length === 0 ? $('
' + columnsMap[columnsMap.length - 1][field].templet(line) + '
').text() : $tableBody.children('tbody').children('tr[data-index=' + bodyIndex + ']').children('td[data-field="' + field + '"]').find(':input').val() || handleNull(line[field])
- : $('
' + laytpl($(columnsMap[columnsMap.length - 1][field].templet).html() || String(columnsMap[columnsMap.length - 1][field].templet)).render(line) + '
').find(':input').length === 0 ? $('
' + laytpl($(columnsMap[columnsMap.length - 1][field].templet).html() || String(columnsMap[columnsMap.length - 1][field].templet)).render(line) + '
').text() : $tableBody.children('tbody').children('tr[data-index=' + bodyIndex + ']').children('td[data-field="' + field + '"]').find(':input').val() || handleNull(line[field])
- : bodyIndex >= 0 && columnsMap[columnsMap.length - 1][field].type === 'numbers' ? bodyIndex + 1 : handleNull(line[field]);
- return {
- v: value,// v 代表单元格的值
- s: {// s 代表样式
- alignment: {
- horizontal: columnsMap[bodyIndex < -1 ? curIndex - tableStartIndex + 1 : columnsMap.length - 1][field].align ? alignTrans[columnsMap[bodyIndex < -1 ? curIndex - tableStartIndex + 1 : columnsMap.length - 1][field].align] : 'top',
- vertical: 'center'
- },
- font: { name: family, sz: size, color: { rgb: color } },
- fill: {
- fgColor: { rgb: bgColor, bgColor: { indexed: 64 } }
- },
- border: border
- },
- t: UNHANDLED_VALUES.indexOf(value) === -1 ? cellType : 's'
- };
- }
- }
- }
-
- excel.exportExcel({
- sheet1: excel.filterExportData(data, showField)
- }, filename, type, {
- extend: {
- '!cols': excel.makeColConfig(widths, 80),
- '!merges': excel.makeMergeConfig(mergeArrays),
- '!rows': excel.makeRowConfig(heightConfig, 16)
- }
- });
- layer.close(loading);
-
- // 合成 excel.js 识别的 rgb
- function handleRgb(rgb) {
- return rgb ? { rgb: rgb } : rgb
- }
-
- function numberToLetter(num) {
- var result = [];
- while (num) {
- var t = num % 26;
- if (!t) {
- t = 26;
- --num;
- }
- // Polyfill 兼容旧浏览器
- if (!String.fromCodePoint) (function (stringFromCharCode) {
- var fromCodePoint = function (_) {
- var codeUnits = [], codeLen = 0, result = "";
- for (var index = 0, len = arguments.length; index !== len; ++index) {
- var codePoint = +arguments[index];
- // correctly handles all cases including `NaN`, `-Infinity`, `+Infinity`
- // The surrounding `!(...)` is required to correctly handle `NaN` cases
- // The (codePoint>>>0) === codePoint clause handles decimals and negatives
- if (!(codePoint < 0x10FFFF && (codePoint >>> 0) === codePoint))
- throw RangeError("Invalid code point: " + codePoint);
- if (codePoint <= 0xFFFF) { // BMP code point
- codeLen = codeUnits.push(codePoint);
- } else { // Astral code point; split in surrogate halves
- // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
- codePoint -= 0x10000;
- codeLen = codeUnits.push(
- (codePoint >> 10) + 0xD800, // highSurrogate
- (codePoint % 0x400) + 0xDC00 // lowSurrogate
- );
- }
- if (codeLen >= 0x3fff) {
- result += stringFromCharCode.apply(null, codeUnits);
- codeUnits.length = 0;
- }
- }
- return result + stringFromCharCode.apply(null, codeUnits);
- };
- try { // IE 8 only supports `Object.defineProperty` on DOM elements
- Object.defineProperty(String, "fromCodePoint", {
- "value": fromCodePoint, "configurable": true, "writable": true
- });
- } catch (e) {
- String.fromCodePoint = fromCodePoint;
- }
- }(String.fromCharCode));
- result.push(String.fromCodePoint(t + 64));
- if (!String.fromCodePoint) (function (stringFromCharCode) {
- var fromCodePoint = function (_) {
- var codeUnits = [], codeLen = 0, result = "";
- for (var index = 0, len = arguments.length; index !== len; ++index) {
- var codePoint = +arguments[index];
- // correctly handles all cases including `NaN`, `-Infinity`, `+Infinity`
- // The surrounding `!(...)` is required to correctly handle `NaN` cases
- // The (codePoint>>>0) === codePoint clause handles decimals and negatives
- if (!(codePoint < 0x10FFFF && (codePoint >>> 0) === codePoint))
- throw RangeError("Invalid code point: " + codePoint);
- if (codePoint <= 0xFFFF) { // BMP code point
- codeLen = codeUnits.push(codePoint);
- } else { // Astral code point; split in surrogate halves
- // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
- codePoint -= 0x10000;
- codeLen = codeUnits.push(
- (codePoint >> 10) + 0xD800, // highSurrogate
- (codePoint % 0x400) + 0xDC00 // lowSurrogate
- );
- }
- if (codeLen >= 0x3fff) {
- result += stringFromCharCode.apply(null, codeUnits);
- codeUnits.length = 0;
- }
- }
- return result + stringFromCharCode.apply(null, codeUnits);
- };
- try { // IE 8 only supports `Object.defineProperty` on DOM elements
- Object.defineProperty(String, "fromCodePoint", {
- "value": fromCodePoint, "configurable": true, "writable": true
- });
- } catch (e) {
- String.fromCodePoint = fromCodePoint;
- }
- }(String.fromCharCode));
- num = ~~(num / 26);
- }
- return result.reverse().join('');
- }
- },
- startsWith: function (content, str) {
- var reg = new RegExp("^" + str);
- return content && reg.test(content);
- },
- // 深度克隆-不丢失方法
- deepClone: function (obj) {
- var newObj = Array.isArray(obj) ? [] : {}
- if (obj && typeof obj === "object") {
- for (var key in obj) {
- if (obj.hasOwnProperty(key)) {
- newObj[key] = (obj && typeof obj[key] === 'object') ? this.deepClone(obj[key]) : obj[key];
- }
- }
- }
- return newObj
- },
- deepStringify: function (obj) {
- var JSON_SERIALIZE_FIX = {
- PREFIX: "[[JSON_FUN_PREFIX_",
- SUFFIX: "_JSON_FUN_SUFFIX]]"
- };
- return JSON.stringify(obj, function (key, value) {
- if (typeof value === 'function') {
- return JSON_SERIALIZE_FIX.PREFIX + value.toString() + JSON_SERIALIZE_FIX.SUFFIX;
- }
- return value;
- });
- },
- /* layui table 中原生的方法 */
- getScrollWidth: function (elem) {
- var width = 0;
- if (elem) {
- width = elem.offsetWidth - elem.clientWidth;
- } else {
- elem = document.createElement('div');
- elem.style.width = '100px';
- elem.style.height = '100px';
- elem.style.overflowY = 'scroll';
-
- document.body.appendChild(elem);
- width = elem.offsetWidth - elem.clientWidth;
- document.body.removeChild(elem);
- }
- return width;
- }
- , getCompleteCols: function (origin) {
- var cols = this.deepClone(origin);
- var i, j, k, cloneCol;
- for (i = 0; i < cols.length; i++) {
- for (j = 0; j < cols[i].length; j++) {
- if (!cols[i][j].exportHandled) {
- if (cols[i][j].rowspan > 1) {
- cloneCol = this.deepClone(cols[i][j])
- cloneCol.exportHandled = true;
- k = i + 1;
- while (k < cols.length) {
- cols[k].splice(j, 0, cloneCol)
- k++
- }
- }
- if (cols[i][j].colspan > 1) {
- cloneCol = this.deepClone(cols[i][j])
- cloneCol.exportHandled = true;
- for (k = 1; k < cols[i][j].colspan; k++) {
- cols[i].splice(j, 0, cloneCol)
- }
- j = j + parseInt(cols[i][j].colspan) - 1
- }
- }
- }
- }
- return cols[cols.length - 1];
- }
- , parseTempData: function (item3, content, tplData, text) { //表头数据、原始内容、表体数据、是否只返回文本
- var str = item3.templet ? function () {
- return typeof item3.templet === 'function'
- ? item3.templet(tplData)
- : laytpl($(item3.templet).html() || String(content)).render(tplData)
- }() : content;
- return text ? $('
' + str + '
').text() : str;
- }
- , cache: cache
+ var $ = layui.jquery,
+ table = layui.table,
+ form = layui.form,
+ laydate = layui.laydate,
+ laytpl = layui.laytpl,
+ util = layui.util,
+ excel = layui.excel,
+ columnsTimeOut,
+ dorpListTimeOut,
+ conditionTimeOut,
+ bfColumnTimeOut,
+ bfCond1TimeOut,
+ isFilterReload = {},
+ SOUL_ROW_INDEX = 'SOUL_ROW_INDEX',
+ cache = {},
+ HIDE = 'layui-hide',
+ maxId = 1,
+ UNHANDLED_VALUES = [undefined, '', null],
+ where_cache = {},
+ isFilterCache = {},
+ table_cache = {},
+ conditionChangeItems = {
+ 'eq': '等于',
+ 'ne': '≠ 不等于',
+ 'gt': '> 大于',
+ 'ge': '≥ 大于等于',
+ 'lt': '< 小于',
+ 'le': '≤ 小于等于',
+ 'contain': '包含',
+ 'notContain': '不包含',
+ 'start': '以...开头',
+ 'end': '以...结尾',
+ 'null': '为空',
+ 'notNull': '不为空'
+ },
+ dateTimeItems = {
+ 'all': '全部',
+ 'yesterday': '昨天',
+ 'thisWeek': '本周',
+ 'lastWeek': '上周',
+ 'thisMonth': '本月',
+ 'thisYear': '今年'
+ },
+ defaultFilterItems = ['column', 'data', 'condition', 'editCondition', 'excel'],
+ itemsMap = {
+ 'column': 'soul-column',
+ 'data': 'soul-dropList',
+ 'condition': 'soul-condition',
+ 'editCondition': 'soul-edit-condition',
+ 'excel': 'soul-export',
+ 'clearCache': 'soul-clear-cache',
+ },
+ modeMapItems = {
+ 'in': 'data',
+ 'condition': 'condition',
+ 'date': 'condition',
+ },
+ revertMode = {
+ 'data': {
+ 'mode': 'condition',
+ 'type': 'eq',
+ 'value': '',
+ },
+ 'condition': {
+ 'mode': 'in',
+ 'values': [],
+ },
};
- // 输出
- exports('tableFilter', mod);
+ // 封装方法
+ var mod = {
+ /**
+ * 摧毁render数据
+ * @param myTables
+ */
+ destroy: function (myTables) {
+ if (myTables) {
+ if (Array.isArray(myTables)) {
+ for (var i = 0; i < myTables.length; i++) {
+ deleteRender(myTables[i])
+ }
+ } else {
+ deleteRender(myTables);
+ }
+ }
+
+ function deleteRender(myTable) {
+ if (!myTable) {
+ return;
+ }
+ var tableId = myTable.config.id;
+ $('#soul-filter-list' + tableId).remove();
+ $('#soulCondition' + tableId).remove();
+ $('#soulDropList' + tableId).remove();
+
+ delete isFilterReload[tableId];
+ delete where_cache[tableId];
+ delete table_cache[tableId];
+ }
+ },
+ clearFilter: function (myTable) {
+ if (typeof myTable === 'string') {
+ myTable = table_cache[myTable]
+ }
+ if (!where_cache[myTable.id] || !where_cache[myTable.id].filterSos || where_cache[myTable.id].filterSos === "[]") {
+ return;
+ }
+ where_cache[myTable.id].filterSos = "[]"
+ this.soulReload(myTable, true)
+ if (table_cache[myTable.id].where && table_cache[myTable.id].where.filterSos && table_cache[myTable.id].where.filterSos !== "[]") {
+ table_cache[myTable.id].where.filterSos = "[]"
+ }
+ },
+ render: function (myTable) {
+ var _this = this,
+ $table = $(myTable.elem),
+ $tableMain = $table.next().children('.layui-table-box').children('.layui-table-main'),
+ $tableHead = $table.next().children('.layui-table-box').children('.layui-table-header').children('table'),
+ $fixedLeftTableHead = $table.next().children('.layui-table-box').children('.layui-table-fixed-l').children('.layui-table-header').children('table'),
+ $fixedRigthTableHead = $table.next().children('.layui-table-box').children('.layui-table-fixed-r').children('.layui-table-header').children('table'),
+ tableId = myTable.id,
+ columns = _this.getCompleteCols(myTable.cols),
+ filterItems = myTable.filter ? myTable.filter.items || defaultFilterItems : defaultFilterItems,
+ needFilter = false, // 是否存在筛选列需要进行初始化
+ initFilter = false, // 是否为第一次筛选
+ mainExcel = typeof myTable.excel === 'undefined' || ((myTable.excel && (typeof myTable.excel.on === 'undefined' || myTable.excel.on)) ? myTable.excel : false),
+ i, j;
+
+ for (i = 0; i < columns.length; i++) {
+ if (columns[i].field && columns[i].filter) {
+ needFilter = true;
+ if ($tableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.soul-table-filter').length === 0) {
+ initFilter = true;
+ if ($tableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.layui-table-sort').length > 0) {
+ $tableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.layui-table-sort').hide()
+ $tableHead.find('th[data-field="' + columns[i].field + '"]').children().append('
')
+ } else {
+ $tableHead.find('th[data-field="' + columns[i].field + '"]').children().append('
')
+ }
+ if ($fixedLeftTableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.layui-table-sort').length > 0) {
+ $fixedLeftTableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.layui-table-sort').hide()
+ $fixedLeftTableHead.find('th[data-field="' + columns[i].field + '"]').children().append('
')
+ } else {
+ $fixedLeftTableHead.find('th[data-field="' + columns[i].field + '"]').children().append('
')
+ }
+ if ($fixedRigthTableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.layui-table-sort').length > 0) {
+ $fixedRigthTableHead.find('th[data-field="' + columns[i].field + '"]').children().children('.layui-table-sort').hide()
+ $fixedRigthTableHead.find('th[data-field="' + columns[i].field + '"]').children().append('
')
+ } else {
+ $fixedRigthTableHead.find('th[data-field="' + columns[i].field + '"]').children().append('
')
+ }
+ }
+ }
+ }
+ table_cache[myTable.id] = myTable // 缓存table配置
+ isFilterCache[myTable.id] = needFilter;
+ if (!needFilter) {
+ // 缓存所有数据
+ if (myTable.url && !myTable.page) {
+ // 修复不分页时,前端筛选后,data不为空,造成所有数据丢失的问题
+ cache[myTable.id] = layui.table.cache[myTable.id]
+ } else {
+ cache[myTable.id] = myTable.data || layui.table.cache[myTable.id]
+ }
+ return;
+ } //如果没筛选列,直接退出
+
+ // 渲染底部筛选条件
+ if (!(myTable.filter && typeof myTable.filter.bottom !== 'undefined' && !myTable.filter.bottom) && $table.next().children('.soul-bottom-contion').length === 0) {
+ $table.next().children('.layui-table-box').after('
')
+ var changeHeight = $table.next().children('.layui-table-box').children('.layui-table-body').outerHeight() - $table.next().children('.soul-bottom-contion').outerHeight();
+ if (myTable.page && $table.next().children('.layui-table-page').hasClass('layui-hide')) {
+ changeHeight += $table.next().children('.layui-table-page').outerHeight()
+ }
+ $table.next().children('.layui-table-box').children('.layui-table-body').css('height', changeHeight)
+ var fixHeight = changeHeight - _this.getScrollWidth($tableMain[0]),
+ layMainTableHeight = $tableMain.children('table').height()
+ $table.next().children('.layui-table-box').children('.layui-table-fixed').children('.layui-table-body').css('height', layMainTableHeight >= fixHeight ? fixHeight : 'auto')
+ $table.next().children('.soul-bottom-contion').children('.condition-items').css('width', ($table.next().children('.soul-bottom-contion').width() - $table.next().children('.soul-bottom-contion').children('.editCondtion').width()) + 'px');
+ $table.next().children('.soul-bottom-contion').children('.editCondtion').children('a').on('click', function () {
+ _this.showConditionBoard(myTable);
+ })
+ }
+
+ /**
+ * 不重载表头数据,重新绑定事件后结束
+ */
+ if (!initFilter || isFilterReload[myTable.id] || myTable.isSoulFrontFilter) {
+ isFilterReload[myTable.id] = false
+ myTable['isSoulFrontFilter'] = false
+ // 同步选中状态
+ if (!myTable.url && myTable.page && myTable.data) {
+ myTable.data.forEach(function (row) {
+ for (i = 0; i < cache[myTable.id].length; i++) {
+ if (cache[myTable.id][i][SOUL_ROW_INDEX] === row[SOUL_ROW_INDEX]) {
+ cache[myTable.id][i] = row
+ break;
+ }
+ }
+ })
+ }
+ this.bindFilterClick(myTable);
+ return;
+ } else {
+ if (!myTable.url && myTable.page && myTable.data && myTable.data.length > myTable.limit) {
+ // 前端分页大于一页,修复 index (用于排序恢复时需要通过这个排序)
+ layui.each(myTable.data, function (index, item) {
+ item[myTable.indexName] = index;
+ })
+ }
+ /**
+ * 缓存所有数据
+ */
+ if (myTable.url && !myTable.page) {
+ // 修复不分页时,前端筛选后,data不为空,造成所有数据丢失的问题
+ cache[myTable.id] = layui.table.cache[myTable.id]
+ } else {
+ cache[myTable.id] = myTable.data || layui.table.cache[myTable.id]
+ }
+ // 给表格数据添加位置标志
+ cache[myTable.id].forEach(function (item, index) {
+ item[SOUL_ROW_INDEX] = index
+ })
+
+ if (myTable.filter && myTable.filter.clearFilter) {
+ if (myTable.where && myTable.where.filterSos && JSON.parse(myTable.where.filterSos).length > 0) {
+ // 重新查询新数据
+ myTable.where.filterSos = '[]';
+ where_cache[myTable.id] = myTable.where || {}
+ _this.soulReload(myTable, false);
+ return;
+ } else {
+ where_cache[myTable.id] = myTable.where || {}
+ }
+ } else if ((typeof myTable.url !== 'undefined' && myTable.page ? typeof myTable.where.filterSos === 'undefined' : true) && where_cache[myTable.id] && JSON.parse(where_cache[myTable.id].filterSos || '[]').length > 0) {
+ myTable.where['filterSos'] = where_cache[myTable.id].filterSos
+ where_cache[myTable.id] = myTable.where;
+ _this.soulReload(myTable, false);
+ return;
+ } else {
+ where_cache[myTable.id] = myTable.where || {}
+ }
+ }
+
+ // 第一次渲染时,追加数据
+ if ($('#soul-filter-list' + tableId).length === 0) {
+
+ if (typeof myTable.soulSort === 'undefined' || myTable.soulSort) {
+ if (typeof $table.attr('lay-filter') === 'undefined') {
+ $table.attr('lay-filter', tableId);
+ }
+ table.on('sort(' + $table.attr('lay-filter') + ')', function (obj) {
+
+ // 同步分页信息
+ myTable.limit = table_cache[myTable.id].limit
+
+ if (myTable.url && myTable.page) {
+ // 后台分页
+ where_cache[myTable.id].field = obj.field;
+ where_cache[myTable.id].order = obj.type;
+ isFilterReload[myTable.id] = true;
+ table.render($.extend(myTable, {
+ initSort: obj
+ , where: where_cache[myTable.id]
+ , page: {
+ curr: 1 //重新从第 1 页开始
+ }
+ }));
+ } else if (!myTable.url && myTable.page) {
+ // 前台分页
+ if (obj.type === 'asc') { //升序
+ cache[myTable.id] = layui.sort(cache[myTable.id], obj.field)
+ } else if (obj.type === 'desc') { //降序
+ cache[myTable.id] = layui.sort(cache[myTable.id], obj.field, true)
+ } else { //清除排序
+ cache[myTable.id] = layui.sort(cache[myTable.id], myTable.indexName)
+ }
+ myTable.initSort = obj;
+ myTable.page = {curr: 1};
+ _this.soulReload(myTable, false)
+ }
+ });
+ }
+
+ var soulFilterList = [],
+ filterItemsHtml = {
+ column: '
表格列 ',
+ data: '
筛选数据 ',
+ condition: '
筛选条件 ',
+ editCondition: '
编辑筛选条件 ',
+ excel: '
导出excel ',
+ clearCache: '
清除缓存 '
+ };
+ soulFilterList.push('
');
+ $('body').append(soulFilterList.join(''));
+
+
+ // 显示隐藏列
+ var liClick = true;
+ form.on('checkbox(changeColumns' + tableId + ')', function (data) {
+ liClick = false;
+ var columnkey = data.value
+ if (data.elem.checked) {
+ $table.next().find('[data-key=' + columnkey + ']').removeClass(HIDE);
+ } else {
+ $table.next().find('[data-key=' + columnkey + ']').addClass(HIDE);
+ }
+ // 同步配置
+ for (i = 0; i < myTable.cols.length; i++) {
+ for (j = 0; j < myTable.cols[i].length; j++) {
+ if ((myTable.index + '-' + myTable.cols[i][j].key) === columnkey) {
+ myTable.cols[i][j]['hide'] = !data.elem.checked
+ }
+ }
+ }
+ if (layui.soulTable) {
+ layui.soulTable.fixTableRemember(myTable)
+ }
+ $table.next().children('.layui-table-box').children('.layui-table-body').children('table').children('tbody').children('tr.childTr').children('td').attr('colspan', $table.next().children('.layui-table-box').children('.layui-table-header').find('thead>tr>th:visible').length)
+ table.resize(tableId)
+ });
+ $('#soul-columns' + tableId + '>li[data-value]').on('click', function () {
+ if (!$(this).find(':checkbox').is(':disabled')) { //disabled禁止点击
+ if (liClick) {
+ $(this).find('div.layui-form-checkbox').trigger('click');
+ }
+ liClick = true;
+ }
+ });
+
+ // 全选-反选事件
+ $('#soul-dropList' + tableId + ' .check [data-type]').on('click', function () {
+
+ switch ($(this).data('type')) {
+ case 'all':
+ $(this).parents('#soul-dropList' + tableId).find('input[type=checkbox]:not(:checked)').prop('checked', true);
+ break;
+ case 'reverse':
+ $(this).parents('#soul-dropList' + tableId).find('input[type=checkbox]').each(function () {
+ $(this).prop('checked', !$(this).prop('checked'))
+ });
+ break;
+ case 'none':
+ $(this).parents('#soul-dropList' + tableId).find('input[type=checkbox]:checked').prop('checked', false);
+ break;
+ }
+ form.render('checkbox', 'orm');
+ _this.updateDropList(myTable, $('#main-list' + tableId).data('field'));
+ return false;
+ });
+
+ // 关键字搜索
+ $('#soul-dropList' + tableId + ' .filter-search input').on('input', function () {
+ var key = $(this).val();
+ if (key === '') {
+ $('#soul-dropList' + tableId + '>ul>li').show();
+ } else {
+ $('#soul-dropList' + tableId + '>ul>li').hide();
+ $('#soul-dropList' + tableId + '>ul>li[data-value*="' + key.toLowerCase() + '"]').show();
+ }
+ })
+
+ // 显示表格列
+ $('#main-list' + tableId + ' .soul-column').on('mouseover', function (e) {
+ _this.hideDropList(myTable);
+ _this.hideCondition(myTable);
+ e.stopPropagation();
+ if (columnsTimeOut) {
+ clearTimeout(columnsTimeOut)
+ }
+ columns = _this.getCompleteCols(myTable.cols)
+ for (i = 0; i < columns.length; i++) {
+ $('#soul-columns' + tableId).find('li[data-value="' + columns[i].field + '"]>input').prop('checked', !columns[i].hide);
+ }
+ form.render('checkbox', 'orm');
+ $('#soul-columns' + tableId).show();
+ var left, animate;
+ if ($(this).parent().offset().left + $(this).parent().width() + $('#soul-columns' + tableId).width() < document.body.clientWidth) {
+ left = $(this).parent().offset().left + $(this).parent().width();
+ animate = 'fadeInLeft'
+ } else {
+ left = $(this).parent().offset().left - $('#soul-columns' + tableId).width();
+ animate = 'fadeInRight'
+ }
+ $('#soul-columns' + tableId).css({'top': $(this).offset().top, 'left': left})
+ .removeClass().addClass(animate + ' animated');
+ });
+ // 显示数据下拉
+ $('#main-list' + tableId + ' .soul-dropList').on('mouseover', function (e) {
+ if ($('#soul-dropList' + tableId).is(':visible') && !$('#soul-dropList' + tableId).hasClass('fadeOutLeft')) {
+ return false;
+ }
+ _this.hideColumns(myTable);
+ _this.hideCondition(myTable);
+ e.stopPropagation();
+ if (dorpListTimeOut) {
+ clearTimeout(dorpListTimeOut);
+ }
+ $('#soul-dropList' + tableId + '>.filter-search>input').val('');
+ $('#soul-dropList' + tableId).show();
+ var left, animate, field = $('#main-list' + tableId).data('field');
+ if ($('#main-list' + tableId).offset().left + $('#soul-dropList' + tableId).width() + $('#soul-dropList' + tableId).width() < document.body.clientWidth) {
+ left = $('#main-list' + tableId).offset().left + $('#main-list' + tableId).width();
+ animate = 'fadeInLeft';
+ } else {
+ left = $('#main-list' + tableId).offset().left - $('#soul-dropList' + tableId).width();
+ animate = 'fadeInRight';
+ }
+
+ $('#soulDropList' + tableId).find('.' + field + 'DropList li input[type=checkbox]:checked').prop('checked', false);
+ var where = where_cache[myTable.id] || {},
+ filterSos = JSON.parse(where.filterSos ? where.filterSos : null),
+ id = '', prefix = '';
+ if (filterSos) {
+ for (i = 0; i < filterSos.length; i++) {
+ if (filterSos[i].head && filterSos[i].mode === "in" && filterSos[i].field === field) {
+ id = filterSos[i].id;
+ prefix = filterSos[i].prefix;
+ for (j = 0; j < filterSos[i].values.length; j++) {
+ $('#soulDropList' + tableId).find('.' + field + 'DropList li input[type=checkbox][value="' + filterSos[i].values[j] + '"]').prop('checked', true);
+ }
+ break;
+ }
+ }
+ }
+ $('#soul-dropList' + tableId + '>ul').data({
+ head: true,
+ 'id': id,
+ prefix: prefix,
+ refresh: true,
+ split: $('#main-list' + tableId).data('split')
+ }).html($('#soulDropList' + tableId).find('.' + field + 'DropList li').clone());
+
+ $('#soul-dropList' + tableId).css({'top': $(this).offset().top, 'left': left})
+ .show().removeClass().addClass(animate + ' animated');
+ setTimeout(function () {
+ $('#soul-dropList' + tableId + '>.filter-search>input').focus() // 聚焦搜索框
+ form.render('checkbox', 'orm');
+ }, 1);
+
+ // 监听筛选数据
+ var liClick = true;
+ form.on('checkbox(soulDropList' + tableId + ')', function (data) {
+ liClick = false;
+ _this.updateDropList(myTable, field);
+ });
+
+ $('#soul-dropList' + tableId + '>ul>li[data-value]').on('click', function () {
+ if (liClick) {
+ $(this).find('div.layui-form-checkbox').trigger('click');
+ }
+ liClick = true;
+ })
+ });
+
+ // 显示筛选条件
+ $('#main-list' + tableId + ' .soul-condition').on('mouseover', function (e) {
+ if ($('#soul-condition' + tableId).is(':visible') && !$('#soul-condition' + tableId).hasClass('fadeOutLeft')) {
+ return false;
+ }
+ _this.hideColumns(myTable);
+ _this.hideDropList(myTable);
+ e.stopPropagation();
+ if (conditionTimeOut) {
+ clearTimeout(conditionTimeOut);
+ }
+ var documentWidth = document.body.clientWidth;
+ $('#soul-condition' + tableId).show();
+ var left, animate, field = $(this).parent().data('field');
+ if ($(this).parent().offset().left + $(this).parent().width() + $('#soul-condition' + tableId).width() < documentWidth) {
+ left = $(this).parent().offset().left + $(this).parent().width();
+ animate = 'fadeInLeft'
+ } else {
+ left = $(this).parent().offset().left - $('#soul-condition' + tableId).width();
+ animate = 'fadeInRight'
+ }
+
+ var filterSo, conditionHtml = [],
+ where = where_cache[myTable.id] || {},
+ filterSos = JSON.parse(where.filterSos ? where.filterSos : null);
+ if (filterSos) {
+ for (i = 0; i < filterSos.length; i++) {
+ if (filterSos[i].head && filterSos[i].field === field && (filterSos[i].mode === "date" || filterSos[i].mode === 'group')) {
+ filterSo = filterSos[i]
+ break;
+ }
+ }
+ }
+
+ var filterType = $(this).parent().data('type');
+ if (_this.startsWith(filterType, 'date')) {
+ _this.showDate(myTable, field, filterSo, animate, $(this).offset().top, $(this).parent().offset().left + $(this).parent().width(), 'down', true);
+ } else {
+ /**
+ * 筛选条件
+ */
+ var fieldMap = {};
+ for (i = 0; i < columns.length; i++) {
+ if (columns[i].field) {
+ fieldMap[columns[i]['field']] = columns[i]
+ }
+ }
+ // 查询条件
+ var selectStr = "
";
+ for (var key in conditionChangeItems) {
+ selectStr += '' + conditionChangeItems[key] + ' ';
+ }
+ selectStr += " ";
+ conditionHtml.push('
添加 查询
')
+
+ $('#soul-condition' + tableId).data({head: true, id: filterSo ? filterSo.id || '' : ''})
+ .html(conditionHtml.join(''))
+ .css({'top': $(this).offset().top, 'left': left})
+ .show().removeClass().addClass(animate + ' animated');
+
+ $('.condition-table').on('click', function () {
+ return false;
+ })
+
+ // 新增与查询
+ $('#soul-condition' + tableId + ' button[data-type]').on('click', function () {
+ /**
+ * 新增
+ */
+ if ($(this).data('type') === 'add') {
+ var groupId = $('#soul-condition' + tableId).data('id'),
+ head = $('#soul-condition' + tableId).data('head'),
+ type = 'eq',
+ filterSo,
+ $tr1 = $('#soul-condition' + tableId).find('tr:eq(0)');
+
+ if (groupId) {
+ filterSo = {
+ head: head,
+ prefix: 'and',
+ field: field,
+ mode: 'condition',
+ type: type,
+ value: '',
+ groupId: groupId
+ }
+ } else {
+ filterSo = {
+ head: head,
+ prefix: head ? 'and' : 'and',
+ mode: 'group',
+ field: field,
+ children: [{
+ id: _this.getDifId(),
+ prefix: 'and',
+ field: field,
+ mode: 'condition',
+ type: $tr1.find('select').val(),
+ value: $tr1.find('.value').val()
+ }, {
+ id: _this.getDifId(),
+ prefix: 'and',
+ field: field,
+ mode: 'condition',
+ type: type,
+ value: ''
+ }]
+ }
+ }
+
+ _this.updateWhere(myTable, filterSo);
+ if (!groupId) {
+ $('#soul-condition' + tableId).data('id', filterSo.id);
+ $tr1.data('id', filterSo.children[0].id);
+ }
+ // $tableHead.find('thead>tr>th[data-field="'+field+'"] .soul-table-filter').attr('soul-filter','true');
+ var newId = groupId ? filterSo.id : filterSo.children[1].id;
+ var newTr = '
' +
+ ' ' +
+ ' ' +
+ '
' +
+ ' '
+ + '' + selectStr + '
'
+ + '
'
+ + '';
+
+ $('#soul-condition' + tableId + ">table>tbody").append(newTr)
+ $('#soul-condition' + tableId).find('.del:last').on('click', function () { //删除
+ delCurrentTr(this)
+ });
+
+ // input同步筛选条件
+ $('#soul-condition' + tableId + ' input.value:last').on('input', function () {
+ updateTrWhere($(this).parents('tr:eq(0)'))
+ });
+ } else if ($(this).data('type') === 'search') {
+ /**
+ * 查询
+ */
+ _this.soulReload(myTable);
+ }
+ form.render('select', 'orm');
+ form.render('checkbox', 'orm');
+ return false;
+ });
+
+ // input同步筛选条件
+ $('#soul-condition' + tableId + ' input.value').on('input', function () {
+ updateTrWhere($(this).parents('tr:eq(0)'));
+ });
+
+ // 当前行改动时,同步where条件
+ function updateTrWhere($tr) {
+ var id = $tr.data('id'),
+ groupId = $('#soul-condition' + tableId).data('id'),
+ prefix = $tr.find('input[lay-filter="soul-coondition-switch"]:checked').prop('checked') ? 'and' : 'or',
+ type = $tr.find('select').val(),
+ value = $tr.find('.value').val(),
+ head = $('#soul-condition' + tableId).data('head');
+
+ if (groupId) {
+ filterSo = {
+ id: id,
+ prefix: prefix,
+ mode: 'condition',
+ field: field,
+ type: type,
+ value: value,
+ groupId: groupId
+ }
+ } else {
+ filterSo = {
+ head: head,
+ prefix: head ? 'and' : 'and',
+ mode: 'group',
+ field: field,
+ children: [{
+ id: _this.getDifId(),
+ prefix: prefix,
+ mode: 'condition',
+ field: field,
+ type: type,
+ value: value,
+ groupId: groupId
+ }]
+ }
+ }
+ _this.updateWhere(myTable, filterSo)
+ if (!groupId) {
+ $('#soul-condition' + tableId).data('id', filterSo.id);
+ $tr.data('id', filterSo.children[0].id)
+ } else if (!id) {
+ $tr.data('id', filterSo.id);
+ }
+ }
+
+ // select同步筛选条件
+ form.on('select(conditionChange)', function (data) {
+ if (data.value === 'null' || data.value === 'notNull') {
+ $(this).parents('tr').find('input.value').hide();
+ } else {
+ $(this).parents('tr').find('input.value').show();
+ }
+ updateTrWhere($(data.elem).parents('tr:eq(0)'));
+ })
+
+ // radio同步筛选条件
+ form.on('switch(soul-coondition-switch)', function (data) {
+ updateTrWhere($(this).parents('tr:eq(0)'));
+ });
+
+ // 删除当前行
+ $('#soul-condition' + tableId + ' .del').on('click', function () {
+ delCurrentTr(this)
+ });
+
+ function delCurrentTr(obj) {
+
+ var id;
+
+ if ($(obj).parents('table:eq(0)').find('tr').length === 1) {
+ id = $('#soul-condition' + tableId).data('id');
+ $('#soul-condition' + tableId).data('id', '');
+ $(obj).parents('tr:eq(0)').find('select').val('eq')
+ $(obj).parents('tr:eq(0)').find('.value').val('').show()
+ form.render('select', 'orm');
+ } else {
+ id = $(obj).parents('tr:eq(0)').data('id');
+ if ($(obj).parents('tr:eq(0)').index() === 0) {
+ $(obj).parents('table:eq(0)').find('tr:eq(1)>td:eq(0)').html(fieldMap[field].title).addClass('soul-condition-title')
+ }
+ $(obj).parents('tr:eq(0)').remove()
+ }
+ if (id) {
+ _this.updateWhere(myTable, {
+ id: id,
+ delete: true
+ })
+ }
+ }
+ }
+ form.render('select', 'orm');
+ form.render('checkbox', 'orm');
+
+ });
+
+ $('#soul-columns' + tableId + ', #soul-dropList' + tableId).on('mouseover', function (e) {
+ e.stopPropagation();
+ });
+ $('#main-list' + tableId + ' .soul-edit-condition').on('mouseover', function (e) {
+ _this.hideColumns(myTable)
+ _this.hideDropList(myTable)
+ _this.hideCondition(myTable)
+ e.stopPropagation();
+ }).on('click', function () {
+ $('#main-list' + tableId).hide();
+ _this.showConditionBoard(myTable)
+ });
+ $('#main-list' + tableId + ' .soul-export').on('mouseover', function (e) {
+ _this.hideColumns(myTable)
+ _this.hideDropList(myTable)
+ _this.hideCondition(myTable)
+ e.stopPropagation();
+ }).on('click', function () {
+ $('#main-list' + tableId).hide();
+ _this.export(table_cache[myTable.id])
+ });
+
+ $('#main-list' + tableId + ' .soul-clear-cache').on('mouseover', function (e) {
+ _this.hideColumns(myTable)
+ _this.hideDropList(myTable)
+ _this.hideCondition(myTable)
+ e.stopPropagation();
+ }).on('click', function () {
+ $('#main-list' + tableId).hide();
+ if (layui.soulTable) {
+ layui.soulTable.clearCache(myTable)
+ }
+ layer.msg('已还原!', {icon: 1, time: 1000})
+ });
+
+ $('#main-list' + tableId).on('mouseover', function (e) {
+ var curX = e.pageX;
+ var curY = e.pageY;
+ var div = $(this);
+ var y1 = div.offset().top; //div上面两个的点的y值
+ var y2 = y1 + div.height();//div下面两个点的y值
+ var x1 = div.offset().left; //div左边两个的点的x值
+ var x2 = x1 + div.width(); //div右边两个点的x的值
+ if (curX <= x1 || curX >= x2 || curY <= y1 || curY >= y2) {
+ } else {
+ _this.hideColumns(myTable);
+ _this.hideDropList(myTable);
+ _this.hideCondition(myTable);
+ }
+ });
+ } else {
+
+ types = {}; //存储过滤数据的类型
+ // 根据表格列显示
+ for (i = 0; i < columns.length; i++) {
+ if (columns[i].type === 'checkbox' || !columns[i].field) {
+ continue;
+ }
+ //存储过滤数据的类型
+ if (columns[i].filter && columns[i].filter.type) {
+ if (columns[i].filter.field) {
+ types[columns[i].filter.field] = columns[i].filter.type;
+ } else {
+ types[columns[i].field] = columns[i].filter.type;
+ }
+ }
+ }
+ if (JSON.stringify(types).length !== 2) {
+ myTable.where['tableFilterType'] = JSON.stringify(types);
+ }
+
+ }
+
+ // 初始化下拉数据
+ if ($('#soulDropList' + tableId).length === 0) {
+ $('body').append('
');
+ }
+
+ if ($tableHead.find('.soul-table-filter').length > 0) {
+ var columnField = [], mainDataSwitch = filterItems.indexOf('data') !== -1;
+ $tableHead.find('.soul-table-filter').each(function (index, elem) {
+ if ($(this).data('column') && (mainDataSwitch ? (!$(this).data('items') || $(this).data('items').split(',').indexOf('data') !== -1) : $(this).data('items').split(',').indexOf('data') !== -1)) {
+ columnField.push($(this).data('column'));
+ }
+ });
+ if (columnField.length > 0) {
+ if (typeof myTable.url !== 'undefined' && myTable.page) {
+ var datas = JSON.parse(JSON.stringify(myTable.where)), url = myTable.url;
+ datas['columns'] = JSON.stringify(columnField);
+ $.ajax({
+ url: url,
+ data: datas,
+ dataType: 'json',
+ method: 'post',
+ headers: myTable.headers || {},
+ contentType: myTable.contentType,
+ success: function (result) {
+
+ var uls = [];
+ for (var key in result) {
+ var list = result[key];
+ if (!((list.length === 1 && list[0] === '') || list.length === 0)) {
+ var ul = [];
+ ul.push("
");
+ uls.push(ul.join(''));
+ } else {
+ uls.push("
")
+ }
+ }
+ $('#soulDropList' + tableId).html(uls.join(''));
+ },
+ error: function () {
+ // layer.msg('列筛选数据查询失败!', {icon: 2, anim: 6})
+ }
+ })
+ } else {
+ var tableDatas = cache[myTable.id];
+ var dropDatas = {};
+ for (i = 0; i < tableDatas.length; i++) {
+ for (j = 0; j < columnField.length; j++) {
+ var value = typeof tableDatas[i][columnField[j]] === 'undefined' ? '' : tableDatas[i][columnField[j]];
+ if (dropDatas[columnField[j]]) {
+ if (dropDatas[columnField[j]].indexOf(value) === -1) {
+ dropDatas[columnField[j]].push(value);
+ }
+ } else {
+ dropDatas[columnField[j]] = [value]
+ }
+ }
+ }
+
+ var columnsConfigs = columns;
+ var uls = [];
+ for (j = 0; j < columnsConfigs.length; j++) {
+ var key = columnsConfigs[j].field;
+ var list = dropDatas[key];
+ if (list && !(list.length === 1 && list[0] === '')) {
+ if (columnsConfigs[j].filter && columnsConfigs[j].filter.split) {
+ var tempList = []
+ for (i = 0; i < list.length; i++) {
+ var tempList2 = String(list[i]).split(columnsConfigs[j].filter.split);
+ for (var k = 0; k < tempList2.length; k++) {
+ if (tempList.indexOf(tempList2[k]) === -1) {
+ tempList.push(tempList2[k])
+ }
+ }
+ }
+ list = tempList;
+ }
+ list.sort(function (a, b) {
+ if (isNaN(a) || isNaN(b)) {
+ return String(a) >= String(b)
+ } else {
+ return Number(a) - Number(b)
+ }
+ })
+ var ul = [];
+ ul.push("
");
+ uls.push(ul.join(''));
+ } else {
+ uls.push("
")
+ }
+ }
+ $('#soulDropList' + tableId).html(uls.join(''));
+ }
+ } else {
+ _this.bindFilterClick(myTable);
+ }
+ }
+
+ this.bindFilterClick(myTable);
+ },
+ showConditionBoard: function (myTable) {
+ var _this = this,
+ tableId = myTable.id,
+ where = where_cache[myTable.id] || {},
+ tableFilterTypes = where.tableFilterType ? JSON.parse(where.tableFilterType) : {},
+ filterSos = where.filterSos ? JSON.parse(where.filterSos) : [],
+ filterBoard = [], fieldMap = {}, firstColumn, curItems,
+ filterItems = myTable.filter ? myTable.filter.items || defaultFilterItems : defaultFilterItems,
+ columns = _this.getCompleteCols(myTable.cols),
+ i;
+ for (i = 0; i < columns.length; i++) {
+ if (columns[i].field && columns[i].filter) {
+ if (!firstColumn) {
+ firstColumn = columns[i]
+ }
+ curItems = columns[i].filter.items || filterItems;
+ fieldMap[columns[i]['field']] = {
+ title: columns[i].title,
+ items: curItems
+ }
+ }
+ }
+ filterBoard.push('
')
+ filterBoard.push('
')
+ filterBoard.push('
')
+ var _width = document.body.clientWidth > parseInt('480') ? '480px' : document.body.clientWidth - 10 + 'px'
+ var _height = document.body.clientHeight > parseInt('480') ? '480px' : document.body.clientHeight - 10 + 'px'
+ layer.open({
+ title: '编辑条件',
+ type: 1,
+ offset: 'auto',
+ area: [_width, _height],
+ content: filterBoard.join('')
+ })
+ form.render(null, 'soul-edit-out');
+
+ form.on('checkbox(out_auto)', function (data) {
+ if (data.elem.checked) {
+ _this.soulReload(myTable);
+ }
+ })
+
+ function groupHtml(filterSo, filterBoard, fieldMap, isFirst, isLast) {
+ var id = filterSo.id,
+ field = filterSo.field,
+ mode = filterSo.mode,
+ type = filterSo.type,
+ isOr = filterSo.prefix === 'or';
+ filterBoard.push('
');
+ filterBoard.push('')
+ // if (!isFirst) { //第一个隐藏 与或
+ filterBoard.push('
')
+ // }
+ switch (mode) {
+ case 'in':
+ filterBoard.push('' + (fieldMap[field].title) + '
');
+ filterBoard.push('筛选数据
');
+ filterBoard.push('共' + (filterSo.values ? filterSo.values.length : 0) + '条数据
');
+ filterBoard.push('
');
+ break;
+ case 'date':
+ filterBoard.push('' + (fieldMap[field].title) + '
');
+ filterBoard.push('选择日期
');
+ filterBoard.push('' + (filterSo.type === 'specific' ? filterSo.value || '请选择' : dateTimeItems[filterSo.type]) + '
');
+ filterBoard.push('
');
+ break;
+ case 'condition':
+ filterBoard.push('' + (fieldMap[field].title) + '
');
+ filterBoard.push('' + conditionChangeItems[filterSo.type] + '
');
+ if (type !== 'null' && type !== 'notNull') {
+ filterBoard.push('' + (typeof filterSo.value === 'undefined' || filterSo.value === '' ? '请输入...' : filterSo.value) + '
');
+ }
+ filterBoard.push('
');
+ break;
+ case 'group':
+ filterBoard.push('分组
')
+ filterBoard.push('')
+ filterBoard.push('
');
+ filterBoard.push('');
+ if (filterSo.children) {
+ for (var i = 0; i < filterSo.children.length; i++) {
+ groupHtml(filterSo.children[i], filterBoard, fieldMap, i === 0, i === (filterSo.children.length - 1));
+ }
+ }
+ filterBoard.push(' ');
+ break;
+ }
+ filterBoard.push(' ')
+ }
+
+ // prefix
+ form.on('switch(soul-edit-switch)', function (data) {
+ changePrefix(data)
+ })
+
+ // column
+ $('.soul-edit-out .item-field').on('click', function (e) {
+ e.stopPropagation();
+ showColums(this)
+ })
+ // type
+ $('.soul-edit-out .item-type').on('click', function (e) {
+ e.stopPropagation();
+ showTypes(this)
+ })
+ // value
+ $('.soul-edit-out .item-value').on('click', function (e) {
+ e.stopPropagation();
+ showValue(this)
+ })
+ // delete
+ $('.soul-edit-out .delete-item').on('click', function () {
+ var id = $(this).parent().data('id'),
+ refresh = $('.soul-edit-out .out_auto').prop('checked');
+ $(this).parent().remove();
+ _this.updateWhere(myTable, {
+ id: id,
+ delete: true
+ })
+ if (refresh) {
+ _this.soulReload(myTable);
+ }
+ })
+
+ function changePrefix(data) {
+ var prefix = data.elem.checked ? 'and' : 'or',
+ id = $(data.elem).parents('li:eq(0)').data('id'),
+ refresh = $('.soul-edit-out .out_auto').prop('checked');
+
+ $(data.elem).parents('li:eq(0)').data('prefix', prefix);
+ _this.updateWhere(myTable, {
+ id: id,
+ prefix: prefix
+ })
+
+ if (refresh) {
+ _this.soulReload(myTable)
+ }
+ }
+
+ function showColums(obj) {
+ _this.hideDropList(myTable);
+ _this.hideCondition(myTable);
+ _this.hideColumns(myTable);
+ _this.hideBfPrefix(myTable)
+ _this.hideBfType(myTable);
+ var top = $(obj).offset().top + $(obj).outerHeight(),
+ left = $(obj).offset().left;
+
+ $('#soul-bf-column' + tableId).find('li.soul-bf-selected').removeClass('soul-bf-selected')
+ $('#soul-bf-column' + tableId)
+ .data('field', $(obj).parent().data('field'))
+ .data('id', $(obj).parent().data('id'))
+ .data('mode', $(obj).parent().data('mode'))
+ .data('group', $(obj).parents('li:eq(2)').data('id') || '')
+ .data('refresh', $('.soul-edit-out .out_auto').prop('checked'))
+ .show()
+ .css({top: top, left: left})
+ .removeClass().addClass('fadeInUp animated')
+ .find('li[data-field="' + $(obj).parent().data('field') + '"]')
+ .addClass('soul-bf-selected')
+ }
+
+ function showTypes(obj) {
+ _this.hideDropList(myTable);
+ _this.hideCondition(myTable);
+ _this.hideColumns(myTable);
+ _this.hideBfColumn(myTable);
+ _this.hideBfPrefix(myTable);
+ var top = $(obj).offset().top + $(obj).outerHeight(),
+ left = $(obj).offset().left,
+ field = $(obj).parent().data('field');
+
+ $('#soul-bf-type' + tableId + ' li').hide()
+ if (tableFilterTypes[field] && tableFilterTypes[field].indexOf('date') === 0) {
+ $('#soul-bf-type' + tableId + ' li[data-mode=date]').show()
+ }
+ if (fieldMap[field].items.indexOf('data') !== -1) {
+ $('#soul-bf-type' + tableId + ' li[data-mode=in]').show()
+ }
+ if (fieldMap[field].items.indexOf('condition') !== -1) {
+ $('#soul-bf-type' + tableId + ' li[data-mode=condition]').show()
+ }
+
+ $('#soul-bf-type' + tableId).find('li.soul-bf-selected').removeClass('soul-bf-selected')
+ switch ($(obj).parent().data('mode')) {
+ case 'in':
+ $('#soul-bf-type' + tableId).find('li[data-mode="in"]')
+ .addClass('soul-bf-selected')
+ break;
+ case 'date':
+ $('#soul-bf-type' + tableId).find('li[data-mode="date"]')
+ .addClass('soul-bf-selected')
+ case 'condition':
+ $('#soul-bf-type' + tableId).find('li[data-value="' + $(obj).parent().data('type') + '"]')
+ .addClass('soul-bf-selected')
+ }
+
+ $('#soul-bf-type' + tableId)
+ .data('type', $(obj).parent().data('type'))
+ .data('mode', $(obj).parent().data('mode'))
+ .data('id', $(obj).parent().data('id'))
+ .data('group', $(obj).parents('li:eq(2)').data('id') || '')
+ .data('refresh', $('.soul-edit-out .out_auto').prop('checked'))
+ .show()
+ .css({top: top, left: left})
+ .removeClass().addClass('fadeInUp animated')
+ }
+
+ function showValue(obj) {
+ _this.hideColumns(myTable);
+ _this.hideBfType(myTable);
+ _this.hideBfPrefix(myTable)
+ _this.hideBfColumn(myTable);
+
+ var top,
+ left = $(obj).offset().left,
+ mode = $(obj).parent().data('mode'),
+ field = $(obj).parent().data('field'),
+ id = $(obj).parent().data('id'),
+ head = $(obj).parent().data('head'),
+ prefix = $(obj).parent().data('prefix'),
+ value = $(obj).parent().data('value'),
+ refresh = $('.soul-edit-out .out_auto').prop('checked'),
+ where = where_cache[myTable.id] || {},
+ filterSos = where.filterSos ? JSON.parse(where.filterSos) : [];
+
+ switch (mode) {
+ case 'in':
+ _this.hideCondition(myTable);
+ if (dorpListTimeOut) {
+ clearTimeout(dorpListTimeOut);
+ }
+ $('#soul-dropList' + tableId + '>.filter-search>input').val('');
+ $('#soul-dropList' + tableId).show();
+ $('#soulDropList' + tableId).find('.' + field + 'DropList li input[type=checkbox]:checked').prop('checked', false);
+ var filterSo = _this.getFilterSoById(filterSos, id);
+ if (filterSo.values) {
+ for (i = 0; i < filterSo.values.length; i++) {
+ $('#soulDropList' + tableId).find('.' + field + 'DropList li input[type=checkbox][value="' + filterSo.values[i] + '"]').prop('checked', true);
+ }
+ }
+
+ $('#soul-dropList' + tableId + '>ul').data('id', id).data('head', head).data('refresh', refresh).data('prefix', prefix).html($('#soulDropList' + tableId).find('.' + field + 'DropList li').clone());
+ form.render('checkbox', 'orm');
+ top = $(obj).offset().top + $(obj).outerHeight();
+ $('#soul-dropList' + tableId).css({'top': top, 'left': left})
+ .show().removeClass().addClass('fadeInUp animated');
+ setTimeout(function () {
+ $('#soul-dropList' + tableId + '>.filter-search>input').focus() // 聚焦搜索框
+ }, 1);
+
+ // 监听筛选数据
+ var liClick = true;
+ form.on('checkbox(soulDropList' + tableId + ')', function (data) {
+ liClick = false;
+ _this.updateDropList(myTable, field);
+ });
+
+ $('#soul-dropList' + tableId + '>ul>li[data-value]').on('click', function () {
+ if (liClick) {
+ $(this).find('div.layui-form-checkbox').trigger('click');
+ }
+ liClick = true;
+ })
+ break;
+ case 'date':
+ _this.hideDropList(myTable);
+ if (conditionTimeOut) {
+ clearTimeout(conditionTimeOut);
+ }
+ var filterSo = _this.getFilterSoById(filterSos, id),
+ top = $(obj).offset().top + $(obj).height();
+
+ _this.showDate(myTable, field, filterSo, "fadeInUp", top, left, "down", refresh);
+ break;
+ case 'condition':
+ $(obj).hide();
+ $(obj).after('
')
+ $(obj).next().children().val(value).select().on('keydown', function (e) {
+ if (e.keyCode === 13) {
+ $(this).blur();
+ }
+ }).on('blur', function () {
+ var newValue = $(this).val();
+ $(obj).html(typeof newValue === 'undefined' || newValue === '' ? '请输入...' : newValue);
+ $(obj).show();
+ $(this).parent().remove()
+ if (newValue !== value) {
+ $(obj).parent().data('value', newValue);
+ _this.updateWhere(myTable, {
+ id: id,
+ value: newValue
+ })
+ if (refresh) {
+ _this.soulReload(myTable);
+ }
+ }
+ })
+ break;
+ }
+
+ }
+
+ $('.soul-edit-out a[data-type]').on('click', function () {
+ if ($(this).data('type') === 'search') {
+ _this.soulReload(myTable);
+ } else {
+ addLine(this)
+ }
+ })
+
+ function addLine(obj) {
+ var refresh = $('.soul-edit-out .out_auto').prop('checked');
+ filterBoard = []
+ switch ($(obj).data('type')) {
+ case 'addOne':
+ var filterSo = {
+ prefix: 'and',
+ field: firstColumn.field,
+ mode: 'condition',
+ type: 'eq',
+ value: ''
+ }
+ if ($(obj).parent().parent().data('id')) {
+ $.extend(filterSo, {
+ groupId: $(obj).parent().parent().data('id')
+ })
+ }
+
+ _this.updateWhere(myTable, filterSo);
+
+ filterBoard.push('
');
+ filterBoard.push('');
+ filterBoard.push('
')
+ filterBoard.push('' + fieldMap[filterSo.field].title + '
');
+ filterBoard.push('等于
');
+ filterBoard.push('请输入...
');
+ filterBoard.push('
');
+ filterBoard.push(' ');
+ break;
+ case 'addGroup':
+ var filterSo = {
+ prefix: 'and',
+ mode: 'group',
+ children: []
+ }
+ if ($(obj).parent().parent().data('id')) {
+ $.extend(filterSo, {
+ groupId: $(obj).parent().parent().data('id')
+ })
+ }
+ _this.updateWhere(myTable, filterSo);
+
+ filterBoard.push('
');
+ filterBoard.push('');
+ filterBoard.push('
')
+ filterBoard.push('分组
')
+ filterBoard.push('')
+ filterBoard.push('
');
+ filterBoard.push('');
+ filterBoard.push(' ');
+ break;
+ }
+ if (refresh) {
+ _this.soulReload(myTable);
+ }
+ if ($(obj).parent().parent().children('ul').children('li').length > 0) {
+ $(obj).parent().parent().children('ul').children('li:last').removeClass('last');
+ if ($(obj).parent().parent().children('ul').children('li:last').children('ul.group').length > 0) {
+ $(obj).parent().parent().children('ul').children('li:last').children('ul.group').addClass('line')
+ }
+ }
+ $(obj).parent().parent().children('ul').append(filterBoard.join(''));
+ form.render('checkbox', 'soul-edit-out')
+ if ($(obj).data('type') === 'addGroup') {
+ $(obj).parent().parent().children('ul').children("li:last").find('a[data-type]').on('click', function () {
+ addLine(this)
+ })
+ } else {
+ $(obj).parent().parent().children('ul').children("li:last").find('.item-field').on('click', function (e) {
+ e.stopPropagation();
+ showColums(this);
+ })
+ $(obj).parent().parent().children('ul').children("li:last").find('.item-type').on('click', function (e) {
+ e.stopPropagation();
+ showTypes(this);
+ })
+ $(obj).parent().parent().children('ul').children("li:last").find('.item-value').on('click', function (e) {
+ e.stopPropagation();
+ showValue(this);
+ })
+ }
+ $(obj).parent().parent().children('ul').children("li:last").children('.delete-item').on('click', function () {
+ var id = $(this).parent().data('id'),
+ refresh = $('.soul-edit-out .out_auto').prop('checked');
+ $(this).parent().remove();
+ _this.updateWhere(myTable, {
+ id: id,
+ delete: true
+ })
+ if (refresh) {
+ _this.soulReload(myTable);
+ }
+ })
+ }
+ }
+ , hideColumns: function (myTable, animate) {
+ var tableId = myTable.id;
+
+ $('#soul-columns' + tableId).removeClass().addClass('fadeOutLeft animated')
+ if (columnsTimeOut) {
+ clearTimeout(columnsTimeOut)
+ }
+ if (typeof animate === 'undefined' || animate) {
+ columnsTimeOut = setTimeout(function (e) {
+ $('#soul-columns' + tableId).hide();
+ }, 500)
+ } else {
+ $('[id^=soul-columns]').hide();
+ }
+
+ }
+ , hideDropList: function (myTable, animate) {
+ var tableId = myTable.id;
+ $('#soul-dropList' + tableId).removeClass().addClass('fadeOutLeft animated')
+ if (dorpListTimeOut) {
+ clearTimeout(dorpListTimeOut);
+ }
+ if (typeof animate === 'undefined' || animate) {
+ dorpListTimeOut = setTimeout(function (e) {
+ $('#soul-dropList' + tableId).hide();
+ }, 500)
+ } else {
+ $('[id^=soul-dropList]').hide();
+ }
+
+ }
+ , hideCondition: function (myTable, animate) {
+ var tableId = myTable.id;
+ $('#soul-condition' + tableId).removeClass().addClass('fadeOutLeft animated')
+ if (conditionTimeOut) {
+ clearTimeout(conditionTimeOut);
+ }
+ if (typeof animate === 'undefined' || animate) {
+ conditionTimeOut = setTimeout(function (e) {
+ $('#soul-condition' + tableId).hide();
+ }, 500)
+ } else {
+ $('[id^=soul-condition]').hide();
+ }
+ }
+ , hideBfPrefix: function (myTable, animate) {
+ var tableId = myTable.id;
+ $('#soul-bf-prefix' + tableId).removeClass().addClass('fadeOutDown animated')
+ if (bfColumnTimeOut) {
+ clearTimeout(bfColumnTimeOut);
+ }
+ if (typeof animate === 'undefined' || animate) {
+ bfColumnTimeOut = setTimeout(function () {
+ $('#soul-bf-prefix' + tableId).hide();
+ }, 500)
+ } else {
+ $('[id=soul-bf-prefix' + tableId + ']').hide();
+ }
+ }
+ , hideBfColumn: function (myTable, animate) {
+ var tableId = myTable.id;
+ $('#soul-bf-column' + tableId).removeClass().addClass('fadeOutDown animated')
+ if (bfColumnTimeOut) {
+ clearTimeout(bfColumnTimeOut);
+ }
+ if (typeof animate === 'undefined' || animate) {
+ bfColumnTimeOut = setTimeout(function () {
+ $('#soul-bf-column' + tableId).hide();
+ }, 500)
+ } else {
+ $('[id=soul-bf-column' + tableId + ']').hide();
+ }
+ }
+ , hideBfType: function (myTable, animate) {
+ var tableId = myTable.id;
+ $('#soul-bf-type' + tableId).removeClass().addClass('fadeOutDown animated')
+ if (bfCond1TimeOut) {
+ clearTimeout(bfCond1TimeOut);
+ }
+ if (typeof animate === 'undefined' || animate) {
+ bfCond1TimeOut = setTimeout(function () {
+ $('#soul-bf-type' + tableId).hide();
+ }, 500)
+ } else {
+ $('[id=soul-bf-type' + tableId + ']').hide();
+ }
+ }
+ , bindFilterClick: function (myTable) {
+ var _this = this,
+ $table = $(myTable.elem),
+ $tableHead = $table.next().children('.layui-table-box').children('.layui-table-header').children('table'),
+ $fixedLeftTableHead = $table.next().children('.layui-table-box').children('.layui-table-fixed-l').children('.layui-table-header').children('table'),
+ $fixedRigthTableHead = $table.next().children('.layui-table-box').children('.layui-table-fixed-r').children('.layui-table-header').children('table'),
+ tableId = myTable.id,
+ filterItems = myTable.filter ? myTable.filter.items || defaultFilterItems : defaultFilterItems,
+ mainListTimeOut;
+
+ // 显示筛选框
+ $tableHead.find('.soul-table-filter').off('click').on('click', function (e) {
+ e.stopPropagation();
+ showFilter($(this))
+ });
+ $fixedLeftTableHead.find('.soul-table-filter').off('click').on('click', function (e) {
+ e.stopPropagation();
+ showFilter($(this))
+ });
+ $fixedRigthTableHead.find('.soul-table-filter').off('click').on('click', function (e) {
+ e.stopPropagation();
+ showFilter($(this))
+ });
+
+ function showFilter($that) {
+ var curItems = $that.data('items') ? $that.data('items').split(',') : filterItems
+ _this.hideColumns(myTable, false);
+ _this.hideDropList(myTable, false);
+ _this.hideCondition(myTable, false);
+ $('[id^=main-list]').hide();
+
+ $('#main-list' + tableId).data({'field': $that.data('column'), 'split': $that.data('split')});
+
+ $('#soul-columns' + tableId + ' [type=checkbox]').attr('disabled', false);
+ // if (myTable.cols[0][0].type=='checkbox') {
+ // $('#soul-columns'+tableId+' [type=checkbox]:eq('+($that.parents('th').data('key').split('-')[2]-1)+')').attr('disabled', true);
+ // } else {
+ $('#soul-columns' + tableId + ' li[data-key=' + $that.parents('th').data('key').split('-')[2] + '] [type=checkbox]').attr('disabled', true);
+ // }
+
+ $('#main-list' + tableId + ' > li').hide()
+ // 是否显示排序框
+ if ($that.hasClass('layui-table-sort')) {
+ $('#main-list' + tableId + ' .soul-sort').show()
+ }
+ for (var i = 0; i < curItems.length; i++) {
+ $('#main-list' + tableId + ' .' + itemsMap[curItems[i]]).show()
+ if ($('#main-list' + tableId + ' .' + itemsMap[curItems[i]]).index() !== (i + 2)) {
+ $('#main-list' + tableId + '>li:eq("' + (i + 2) + '")').before($('#main-list' + tableId + ' .' + itemsMap[curItems[i]]))
+
+ }
+ }
+ if (mainListTimeOut) {
+ clearTimeout(mainListTimeOut)
+ }
+ var left, animate;
+ if ($that.offset().left + $('#main-list' + tableId).outerWidth() < document.body.clientWidth) {
+ left = $that.offset().left + 10;
+ animate = 'fadeInLeft';
+ } else {
+ left = $that.offset().left - $('#main-list' + tableId).outerWidth();
+ animate = 'fadeInRight';
+ }
+ $('#main-list' + tableId).data('type', myTable.where.tableFilterType ? JSON.parse(myTable.where.tableFilterType)[$that.data('column')] || '' : '').hide().css({
+ 'top': $that.offset().top + 10,
+ 'left': left
+ }).show().removeClass().addClass(animate + ' animated');
+
+ // 排序
+ $('#main-list' + tableId + ' .soul-sort').on('click', function (e) {
+ $that.siblings('.layui-table-sort').find('.layui-table-sort-' + $(this).data('value')).trigger('click');
+ $('#main-list' + tableId).hide();
+ })
+ form.render('checkbox', 'orm');
+ }
+
+ $(document).on('click', function (e) {
+ $('#main-list' + tableId).hide();
+ _this.hideColumns(myTable, false);
+ _this.hideDropList(myTable, false);
+ _this.hideCondition(myTable, false);
+ _this.hideBfPrefix(myTable, false);
+ _this.hideBfColumn(myTable, false);
+ _this.hideBfType(myTable, false);
+ });
+ $('#main-list' + tableId + ',#soul-columns' + tableId + ',#soul-dropList' + tableId + ',#soul-condition' + tableId).on('click', function (e) {
+ $(this).find('.layui-form-selected').removeClass('layui-form-selected')
+ e.stopPropagation();
+ });
+
+ //渲染底部筛选条件
+ _this.renderBottomCondition(myTable);
+
+ // 表头样式
+ var where = where_cache[myTable.id] || {},
+ filterSos = JSON.parse(where.filterSos ? where.filterSos : '[]');
+
+ for (var i = 0; i < filterSos.length; i++) {
+ if (filterSos[i].head) {
+ var hasFilter = false;
+ switch (filterSos[i].mode) {
+ case 'in':
+ if (filterSos[i].values && filterSos[i].values.length > 0) {
+ hasFilter = true
+ }
+ break;
+ case 'date':
+ if (filterSos[i].type !== 'all' && typeof filterSos[i].value !== 'undefined' && filterSos[i].value !== '') {
+ hasFilter = true
+ }
+ break;
+ case 'group':
+ if (filterSos[i].children && filterSos[i].children.length > 0) {
+ hasFilter = true
+ }
+ default:
+ break;
+ }
+ $tableHead.find('thead>tr>th[data-field="' + filterSos[i].field + '"] .soul-table-filter').attr('soul-filter', '' + hasFilter);
+ $fixedLeftTableHead.find('thead>tr>th[data-field="' + filterSos[i].field + '"] .soul-table-filter').attr('soul-filter', '' + hasFilter);
+ $fixedRigthTableHead.find('thead>tr>th[data-field="' + filterSos[i].field + '"] .soul-table-filter').attr('soul-filter', '' + hasFilter);
+ }
+ }
+ }
+ , resize: function (myTable) {
+ var _this = this,
+ $table = $(myTable.elem),
+ $tableBox = $table.next().children('.layui-table-box'),
+ $tableMain = $tableBox.children('.layui-table-main')
+ // 减去底部筛选的高度
+ if ($table.next().children('.soul-bottom-contion').length > 0) {
+ $table.next().children('.soul-bottom-contion').children('.condition-items').css('width', $table.next().children('.soul-bottom-contion').width() - $table.next().children('.soul-bottom-contion').children('.editCondtion').outerWidth());
+
+ var bodyHeight = $table.next().height() - $table.next().children('.soul-bottom-contion').outerHeight()
+ if ($table.next().children('.layui-table-tool').length > 0) {
+ bodyHeight = bodyHeight - $table.next().children('.layui-table-tool').outerHeight();
+ }
+ if ($table.next().children('.layui-table-total').length > 0) {
+ bodyHeight = bodyHeight - $table.next().children('.layui-table-total').outerHeight();
+ }
+ if ($table.next().children('.layui-table-page').length > 0) {
+ bodyHeight = bodyHeight - $table.next().children('.layui-table-page').outerHeight();
+ }
+
+ bodyHeight = bodyHeight - $table.next().children('.layui-table-box').children('.layui-table-header').outerHeight();
+
+ $table.next().children('.layui-table-box').children('.layui-table-body').height(bodyHeight)
+ var fixHeight = bodyHeight - _this.getScrollWidth($tableMain[0]),
+ layMainTableHeight = $tableMain.children('table').height()
+ $table.next().children('.layui-table-box').children('.layui-table-fixed').children('.layui-table-body').height(layMainTableHeight >= fixHeight ? fixHeight : 'auto')
+
+ var scollWidth = $tableMain.width() - $tableMain.prop('clientWidth') //纵向滚动条宽度;
+ $tableBox.children('.layui-table-fixed-r').css('right', scollWidth - 1);
+ }
+ }
+ /**
+ * 同步当前 droplist
+ * @param myTable
+ * @param field
+ */
+ , updateDropList: function (myTable, field) {
+ var _this = this,
+ $table = $(myTable.elem),
+ tableId = myTable.id,
+ id = $('#soul-dropList' + tableId + '>ul').data('id'),
+ $checkedDom = $('#soul-dropList' + tableId + '>ul input[type=checkbox]:checked'),
+ values = [],
+ head = $('#soul-dropList' + tableId + '>ul').data('head'),
+ prefix = $('#soul-dropList' + tableId + '>ul').data('prefix'),
+ refresh = $('#soul-dropList' + tableId + '>ul').data('refresh'),
+ split = $('#soul-dropList' + tableId + '>ul').data('split');
+ if ($checkedDom.length > 0) {
+ $checkedDom.each(function () {
+ values.push($(this).val())
+ })
+ }
+ var filterSo = {
+ id: id,
+ head: head,
+ prefix: prefix || 'and',
+ mode: 'in',
+ field: field,
+ split: split,
+ values: values
+ };
+ _this.updateWhere(myTable, filterSo);
+ if (!id) {
+ $('#soul-dropList' + tableId + '>ul').data('id', filterSo.id);
+ }
+
+ if ($('.soul-edit-out').length > 0) {
+ $('.soul-edit-out li[data-id="' + filterSo.id + '"]>.item-value').html('共' + (filterSo.values ? filterSo.values.length : 0) + '条数据')
+ }
+
+ if (refresh) {
+ _this.soulReload(myTable);
+ }
+ }
+ , getFilterSoById: function (filterSos, id) {
+ for (var i = 0; i < filterSos.length; i++) {
+ if (filterSos[i].id === id) {
+ return filterSos[i]
+ } else if (filterSos[i].mode === 'group') {
+ for (var j = 0; j < filterSos[i].children.length; j++) {
+ var filterSo = this.getFilterSoById(filterSos[i].children, id);
+ if (filterSo) return filterSo;
+ }
+ }
+ }
+ return null
+ }
+ /**
+ * 更新 filter 条件
+ * @param myTable
+ * @param filterSo
+ */
+ , updateWhere: function (myTable, filterSo) {
+ var _this = this,
+ where = where_cache[myTable.id] || {},
+ filterSos = JSON.parse(where.filterSos ? where.filterSos : '[]');
+
+ if (filterSo.id || filterSo.groupId) {
+ for (var i = 0; i < filterSos.length; i++) {
+ if (filterSo.delete && filterSos[i].id === filterSo.id) {
+ filterSos.splice(i, 1);
+ break;
+ }
+ if (updateFilterSo(filterSos[i], filterSo)) {
+ break;
+ }
+ }
+ } else if (!(filterSo.mode === 'in' && !(filterSo.values && filterSo.values.length > 0))) {
+ filterSos.push($.extend(filterSo, {
+ id: _this.getDifId()
+ }))
+ }
+ where['filterSos'] = JSON.stringify(filterSos);
+ myTable.where = where;
+ where_cache[myTable.id] = where;
+
+ function updateFilterSo(filterSo, newFilterSo) {
+ var isMatch = false;
+
+ if (filterSo.id === newFilterSo.id) {
+ $.extend(filterSo, newFilterSo);
+ isMatch = true;
+ }
+
+ // 在分组中新增
+ if (!newFilterSo.id && filterSo.id === newFilterSo.groupId) {
+ filterSo.children.push($.extend(newFilterSo, {
+ id: _this.getDifId()
+ }))
+ } else if (filterSo.mode === 'group') {
+ for (var i = 0; i < filterSo.children.length; i++) {
+ if (newFilterSo.delete && filterSo.children[i].id === newFilterSo.id) {
+ filterSo.children.splice(i, 1);
+ return true;
+ }
+ if (updateFilterSo(filterSo.children[i], newFilterSo)) {
+ return true;
+ }
+ }
+
+ }
+
+ return isMatch;
+ }
+ }
+ /**
+ * 根据当前条件重载表格
+ * @param myTable 需要重载的表格对象
+ * @param isr 是否为筛选重载,为 true 时,不进行筛选的初始化动作(包括渲染dom、请求表头数据等)
+ */
+ , soulReload: function (myTable, isr) {
+ var _this = this,
+ $table = $(myTable.elem),
+ scrollLeft = $table.next().children('.layui-table-box').children('.layui-table-main').scrollLeft();
+
+ isFilterReload[myTable.id] = typeof isr === 'undefined' ? true : isr;
+ if (typeof myTable.url !== 'undefined' && myTable.page) {
+ $table.data('scrollLeft', scrollLeft);
+ /**
+ * 后台筛选
+ */
+ table.reload(myTable.id, {
+ where: where_cache[myTable.id] || {},
+ page: {
+ curr: 1 //重新从第 1 页开始
+ }
+ }, true)
+ } else {
+ /**
+ * 前端筛选
+ */
+ var where = where_cache[myTable.id] || {},
+ filterSos = JSON.parse(where.filterSos ? where.filterSos : '[]'),
+ tableFilterTypes = where.tableFilterType ? JSON.parse(where.tableFilterType) : {},
+ loading = layer.load(2);
+ if (!myTable.page) {
+ // 修复前端不分页时,layui table bug 导致的只显示10条数据的问题
+ myTable.limit = 100000000
+ }
+ if (filterSos.length > 0) {
+ var newData = [];
+ layui.each(cache[myTable.id], function (index, item) {
+ var show = true;
+
+ for (var i = 0; i < filterSos.length; i++) {
+ show = _this.handleFilterSo(filterSos[i], item, tableFilterTypes, show, i === 0)
+ }
+
+ if (show) {
+ newData.push(item)
+ }
+ })
+ if (myTable.page) {
+ table.reload(myTable.id, {
+ data: newData
+ , initSort: myTable.initSort
+ , isSoulFrontFilter: true
+ , page: {
+ curr: 1 //重新从第 1 页开始
+ }
+ }, true)
+ } else {
+ var url = myTable.url;
+ $table.next().off('click')
+ var inst = table.reload(myTable.id, {
+ url: ''
+ , initSort: myTable.initSort
+ , isSoulFrontFilter: true
+ , data: newData
+ }, true)
+ inst.config.url = url;
+ }
+ myTable.data = newData
+
+ } else {
+ if (myTable.page) {
+ table.reload(myTable.id, {
+ data: cache[myTable.id]
+ , initSort: myTable.initSort
+ , isSoulFrontFilter: true
+ , page: {
+ curr: 1 //重新从第 1 页开始
+ }
+ }, true)
+ } else {
+ table.reload(myTable.id, {
+ data: cache[myTable.id]
+ , initSort: myTable.initSort
+ , isSoulFrontFilter: true
+ }, true)
+ }
+ myTable.data = cache[myTable.id]
+ }
+ $table.next().children('.layui-table-box').children('.layui-table-main').scrollLeft(scrollLeft);
+ layer.close(loading)
+ }
+ }
+ , handleFilterSo: function (filterSo, item, tableFilterTypes, show, first) {
+ var isOr = first ? false : filterSo.prefix === 'or',
+ field = filterSo.field,
+ value = filterSo.value,
+ status = true;
+
+ // 如果有子元素
+ if (filterSo.children && filterSo.children.length > 0) {
+ for (var i = 0; i < filterSo.children.length; i++) {
+ status = this.handleFilterSo(filterSo.children[i], item, tableFilterTypes, status, i === 0)
+ }
+ return isOr ? show || status : show && status;
+ }
+
+ switch (filterSo.mode) {
+ case "in":
+ if (filterSo.values && filterSo.values.length > 0) {
+ if (filterSo.split) {
+ var tempList = (item[field] + '').split(filterSo.split);
+ var tempStatus = false;
+ for (var i = 0; i < tempList.length; i++) {
+ if (filterSo.values.indexOf(tempList[i]) !== -1) {
+ tempStatus = true;
+ }
+ }
+ status = tempStatus;
+ } else {
+ status = filterSo.values.indexOf(item[field] + '') !== -1
+ }
+ } else {
+ return show;
+ }
+ break;
+ case "condition":
+ if (filterSo.type !== 'null' && filterSo.type !== 'notNull' && (typeof value === 'undefined' || value === '')) {
+ return show;
+ }
+ switch (filterSo.type) {
+ case "eq":
+ status = isNaN(item[field]) || isNaN(value) ? item[field] === value : Number(item[field]) === Number(value);
+ break;
+ case "ne":
+ status = isNaN(item[field]) || isNaN(value) ? item[field] !== value : Number(item[field]) !== Number(value);
+ break;
+ case "gt":
+ status = isNaN(item[field]) || isNaN(value) ? item[field] > value : Number(item[field]) > Number(value);
+ break;
+ case "ge":
+ status = isNaN(item[field]) || isNaN(value) ? item[field] >= value : Number(item[field]) >= Number(value);
+ break;
+ case "lt":
+ status = isNaN(item[field]) || isNaN(value) ? item[field] < value : Number(item[field]) < Number(value);
+ break;
+ case "le":
+ status = isNaN(item[field]) || isNaN(value) ? item[field] <= value : Number(item[field]) <= Number(value);
+ break;
+ case "contain":
+ status = (item[field] + '').indexOf(value) !== -1;
+ break;
+ case "notContain":
+ status = (item[field] + '').indexOf(value) === -1;
+ break;
+ case "start":
+ status = (item[field] + '').indexOf(value) === 0;
+ break;
+ case "end":
+ var d = (item[field] + '').length - (value + '').length;
+ status = d >= 0 && (item[field] + '').lastIndexOf(value) === d;
+ break;
+ case "null":
+ status = typeof item[field] === 'undefined' || item[field] === '' || item[field] === null;
+ break;
+ case "notNull":
+ status = typeof item[field] !== 'undefined' && item[field] !== '' && item[field] !== null;
+ break;
+ }
+ break;
+ case "date":
+ var dateVal = new Date(Date.parse(item[field].replace(/-/g, "/")));
+ switch (filterSo.type) {
+ case 'all':
+ status = true;
+ break;
+ case 'yesterday':
+ status = item[field] && isBetween(dateVal, getToday() - 86400, getToday() - 1);
+ break;
+ case 'thisWeek':
+ status = item[field] && isBetween(dateVal, getFirstDayOfWeek(), getFirstDayOfWeek() + 86400 * 7 - 1);
+ break;
+ case 'lastWeek':
+ status = item[field] && isBetween(dateVal, getFirstDayOfWeek() - 86400 * 7, getFirstDayOfWeek() - 1);
+ break;
+ case 'thisMonth':
+ status = item[field] && isBetween(dateVal, getFirstDayOfMonth(), getCurrentMonthLast());
+ break;
+ case 'thisYear':
+ status = item[field] && isBetween(dateVal, new Date(new Date().getFullYear(), 1, 1) / 1000, new Date(new Date().getFullYear() + 1, 1, 1) / 1000 - 1);
+ break;
+ case 'specific':
+ var dateFormat = dateVal.getFullYear();
+ dateFormat += '-' + (timeAdd0(dateVal.getMonth() + 1));
+ dateFormat += '-' + timeAdd0(dateVal.getDate());
+ status = item[field] && dateFormat === value
+ break;
+ }
+ break;
+ }
+
+ // 今天凌晨
+ function getToday() {
+ return new Date().setHours(0, 0, 0, 0) / 1000;
+ }
+
+ // 本周第一天
+ function getFirstDayOfWeek() {
+ var now = new Date();
+ var weekday = now.getDay() || 7; //获取星期几,getDay()返回值是 0(周日) 到 6(周六) 之间的一个整数。0||7为7,即weekday的值为1-7
+ return new Date(now.setDate(now.getDate() - weekday + 1)).setHours(0, 0, 0, 0) / 1000;//往前算(weekday-1)天,年份、月份会自动变化
+ }
+
+ //获取当月第一天
+ function getFirstDayOfMonth() {
+ return new Date(new Date().setDate(1)).setHours(0, 0, 0, 0) / 1000;
+ }
+
+ //获取当月最后一天最后一秒
+ function getCurrentMonthLast() {
+ var date = new Date();
+ var currentMonth = date.getMonth();
+ var nextMonth = ++currentMonth;
+ var nextMonthFirstDay = new Date(date.getFullYear(), nextMonth, 1);
+ return nextMonthFirstDay / 1000 - 1;
+ }
+
+ function isBetween(v, a, b) {
+ return (v.getTime() / 1000) >= a && (v.getTime() / 1000) <= b;
+ }
+
+ function timeAdd0(str) {
+ str += "";
+ if (str.length <= 1) {
+ str = '0' + str;
+ }
+ return str
+ }
+
+ return isOr ? show || status : show && status;
+ }
+ , getDifId: function () {
+ return maxId++;
+ }
+ , showDate: function (myTable, field, filterSo, animate, top, left, type, refresh) {
+ var _this = this,
+ tableId = myTable.id,
+ conditionHtml = [],
+ documentWidth = document.body.clientWidth,
+ animate;
+ conditionHtml.push('
');
+ conditionHtml.push('
');
+ for (var key in dateTimeItems) {
+ conditionHtml.push('
');
+ }
+ conditionHtml.push('
');
+ conditionHtml.push('
');
+ $('#soul-condition' + tableId).html(conditionHtml.join(''));
+ var filterDate = util.toDateString(new Date(), 'yyyy-MM-dd');
+ if (filterSo) {
+ $('#soul-condition' + tableId).data({'id': filterSo.id, 'head': true});
+ $('#soul-condition' + tableId + '>.' + field + 'Condition' + ' [name^=datetime][value="' + filterSo.type + '"]').prop('checked', true);
+ if (filterSo.type === 'specific') {
+ filterDate = filterSo.value
+ }
+ } else {
+ $('#soul-condition' + tableId).data({'id': '', 'head': true});
+ $('#soul-condition' + tableId + '>.' + field + 'Condition' + ' [name^=datetime][value="all"]').prop('checked', true);
+ }
+
+ $('#soul-condition' + tableId + ' .specific_value').val(filterDate);
+ laydate.render({
+ elem: '#soul-condition' + tableId + ' .staticDate'
+ , position: 'static'
+ , calendar: true
+ , btns: ['now']
+ , value: filterDate
+ , done: function (value) {
+ var id = $('#soul-condition' + tableId).data('id'),
+ head = $('#soul-condition' + tableId).data('head')
+ $('#soul-condition' + tableId + ' .specific_value').val(value);
+ $('#soul-condition' + tableId + ' [name^=datetime]:checked').prop('checked', false);
+ $('#soul-condition' + tableId + ' [name^=datetime][value=specific]').prop('checked', true);
+ var filterSo = {
+ id: id,
+ head: head,
+ prefix: head ? 'and' : 'and',
+ mode: 'date',
+ field: field,
+ type: 'specific',
+ value: value
+ }
+ _this.updateWhere(myTable, filterSo);
+ if (!id) {
+ $('#soul-condition' + tableId).data('id', filterSo.id)
+ }
+ if ($('.soul-edit-out').length > 0) {
+ $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-value').html(filterSo.value)
+ }
+ if (refresh) {
+ _this.soulReload(myTable);
+ }
+ form.render('radio', 'orm');
+ }
+ });
+ form.on('radio(datetime' + tableId + ')', function (data) {
+ var id = $('#soul-condition' + tableId).data('id'),
+ head = $('#soul-condition' + tableId).data('head')
+ var filterSo = {
+ id: id,
+ head: head,
+ prefix: head ? 'and' : 'and',
+ mode: 'date',
+ field: field,
+ type: data.value,
+ value: $('#soul-condition' + tableId + ' .specific_value').val()
+ }
+ _this.updateWhere(myTable, filterSo);
+ if (!id) {
+ $('#soul-condition' + tableId).data('id', filterSo.id)
+ }
+ if ($('.soul-edit-out').length > 0) {
+ $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-value').html(dateTimeItems[filterSo.type] || filterSo.value)
+ }
+ if (refresh) {
+ _this.soulReload(myTable);
+ }
+ });
+ form.render('radio', 'orm')
+ if (type === 'down') {
+ if (left + $('#soul-condition' + tableId).width() < documentWidth) {
+ animate = 'fadeInLeft'
+ } else {
+ left = left - $('#main-list' + tableId).width() - $('#soul-condition' + tableId).width();
+ animate = 'fadeInRight'
+ }
+ } else {
+ top = top - $('#soul-condition' + tableId).outerHeight() - 10;
+ }
+ $('#soul-condition' + tableId).css({'top': top, 'left': left})
+ .show().removeClass().addClass(animate + ' animated');
+
+ }
+ , bottomConditionHtml: function (bcHtml, filterSo, fieldMap, first) {
+ var _this = this,
+ isOr = filterSo.prefix === 'or',
+ field = filterSo.field;
+
+ if (filterSo.mode === 'group') {
+ if (filterSo.children && filterSo.children.length > 0) {
+ bcHtml.push('
');
+ if (!first) {
+ bcHtml.push('
' + (isOr ? '或' : '与') + '
');
+ }
+
+ for (var i = 0; i < filterSo.children.length; i++) {
+ _this.bottomConditionHtml(bcHtml, filterSo.children[i], fieldMap, i === 0);
+ }
+ bcHtml.push('
');
+ bcHtml.push('
')
+ }
+ return;
+ }
+ bcHtml.push('
');
+ if (!first) {
+ bcHtml.push('
' + (isOr ? '或' : '与') + '
');
+ }
+ bcHtml.push('
' + fieldMap[field].title + '
');
+ bcHtml.push('
');
+ switch (filterSo.mode) {
+ case 'in':
+ bcHtml.push('筛选数据');
+ break;
+ case 'condition':
+ bcHtml.push(conditionChangeItems[filterSo.type]);
+ break;
+ case 'date':
+ bcHtml.push('选择日期');
+ break;
+ default:
+ bcHtml.push('未知');
+ break;
+ }
+ bcHtml.push('
');
+ if (filterSo.type !== 'null' && filterSo.type !== 'notNull') {
+ bcHtml.push('
');
+ switch (filterSo.mode) {
+ case 'in':
+ bcHtml.push('共' + (filterSo.values ? filterSo.values.length : 0) + '条数据');
+ break;
+ case 'date':
+ bcHtml.push(filterSo.type === 'specific' ? filterSo.value || '请选择' : dateTimeItems[filterSo.type])
+ break;
+ case 'condition':
+ default:
+ bcHtml.push(typeof filterSo.value === 'undefined' || filterSo.value === '' ? '请输入...' : filterSo.value);
+ break;
+ }
+
+ bcHtml.push('
')
+ }
+ bcHtml.push('
');
+ bcHtml.push('
')
+ }
+ , renderBottomCondition: function (myTable) {
+ var _this = this,
+ where = where_cache[myTable.id] || {},
+ filterSos = where.filterSos ? JSON.parse(where.filterSos) : [],
+ tableFilterTypes = where.tableFilterType ? JSON.parse(where.tableFilterType) : {},
+ $table = $(myTable.elem),
+ tableId = myTable.id,
+ $bottomCondition = $table.next().children('.soul-bottom-contion'),
+ fieldMap = {}, bcHtml = [], curItems,
+ filterItems = myTable.filter ? myTable.filter.items || defaultFilterItems : defaultFilterItems,
+ columns = _this.getCompleteCols(myTable.cols);
+ for (var i = 0; i < columns.length; i++) {
+ if (columns[i].field && columns[i].filter) {
+ curItems = columns[i].filter.items || filterItems;
+ if (curItems.indexOf('data') !== -1 || curItems.indexOf('condition') !== -1) {
+ fieldMap[columns[i]['field']] = {
+ title: columns[i].title,
+ items: curItems
+ }
+ }
+ }
+ }
+
+ /**
+ * 一、拼装底部内容
+ */
+ for (var i = 0; i < filterSos.length; i++) {
+ _this.bottomConditionHtml(bcHtml, filterSos[i], fieldMap, i === 0);
+ }
+ $bottomCondition.children('.condition-items').html(bcHtml.join(''))
+
+ /**
+ * 二、组装底部弹窗条件
+ */
+ bcHtml = [];
+ // 1. prefix
+ if ($('#soul-bf-prefix' + tableId).length === 0) {
+ bcHtml.push('
')
+ bcHtml.push('与 ')
+ bcHtml.push('或 ')
+ bcHtml.push(' ')
+ }
+ // 2. 列选择
+ if ($('#soul-bf-column' + tableId).length === 0) {
+ bcHtml.push('
')
+ for (var field in fieldMap) {
+ bcHtml.push('' + fieldMap[field].title + ' ')
+ }
+ bcHtml.push(' ')
+ }
+
+ // 3. 条件选择
+ if ($('#soul-bf-type' + tableId).length === 0) {
+ bcHtml.push('
')
+ bcHtml.push('筛选数据 ')
+ bcHtml.push('选择日期 ')
+ for (var key in conditionChangeItems) {
+ bcHtml.push('' + conditionChangeItems[key] + ' ')
+ }
+ bcHtml.push(' ')
+ }
+
+ // 4. 值选择
+ if ($('#soul-bf-cond2-dropList' + tableId).length === 0) {
+ bcHtml.push('
')
+ }
+
+
+ $('body').append(bcHtml.join(''))
+
+ /**
+ * 三、底部弹窗事件
+ */
+ // 1. prefix弹出事件
+ $bottomCondition.find('.item-prefix').off('click').on('click', function (e) {
+ e.stopPropagation();
+ $('#main-list' + tableId).hide();
+ _this.hideDropList(myTable);
+ _this.hideCondition(myTable);
+ _this.hideColumns(myTable);
+ _this.hideBfColumn(myTable);
+ _this.hideBfType(myTable);
+ var top = $(this).offset().top - $('#soul-bf-prefix' + tableId).outerHeight() - 10,
+ left = $(this).offset().left;
+
+ $('#soul-bf-prefix' + tableId).find('li.soul-bf-selected').removeClass('soul-bf-selected')
+ $('#soul-bf-prefix' + tableId)
+ .data('id', $(this).parent().data('id'))
+ .data('prefix', $(this).parent().data('prefix'))
+ .data('refresh', true)
+ .show()
+ .css({top: top, left: left})
+ .removeClass().addClass('fadeInUp animated')
+ .find('li[data-value="' + $(this).parent().data('prefix') + '"]')
+ .addClass('soul-bf-selected')
+
+ })
+ // 2. 弹出列选择
+ $bottomCondition.find('.item-field').off('click').on('click', function (e) {
+ e.stopPropagation();
+ $('#main-list' + tableId).hide();
+ _this.hideDropList(myTable);
+ _this.hideCondition(myTable);
+ _this.hideColumns(myTable);
+ _this.hideBfPrefix(myTable)
+ _this.hideBfType(myTable);
+ var top = $(this).offset().top - $('#soul-bf-column' + tableId).outerHeight() - 10,
+ left = $(this).offset().left;
+
+ $('#soul-bf-column' + tableId).find('li.soul-bf-selected').removeClass('soul-bf-selected')
+ $('#soul-bf-column' + tableId)
+ .data('field', $(this).parent().data('field'))
+ .data('id', $(this).parent().data('id'))
+ .data('mode', $(this).parent().data('mode'))
+ .data('group', $(this).parent().parent().data('id') || '')
+ .data('refresh', true)
+ .show()
+ .css({top: top, left: left})
+ .removeClass().addClass('fadeInUp animated')
+ .find('li[data-field="' + $(this).parent().data('field') + '"]')
+ .addClass('soul-bf-selected')
+ })
+
+ // 3. 弹出方式选择
+ $bottomCondition.find('.item-type').on('click', function (e) {
+ e.stopPropagation();
+ $('#main-list' + tableId).hide();
+ _this.hideDropList(myTable);
+ _this.hideCondition(myTable);
+ _this.hideColumns(myTable);
+ _this.hideBfColumn(myTable);
+ _this.hideBfPrefix(myTable);
+ var field = $(this).parent().data('field')
+ $('#soul-bf-type' + tableId + ' li').hide()
+ if (tableFilterTypes[field] && tableFilterTypes[field].indexOf('date') === 0) {
+ $('#soul-bf-type' + tableId + ' li[data-mode=date]').show()
+ }
+ if (fieldMap[field].items.indexOf('data') !== -1) {
+ $('#soul-bf-type' + tableId + ' li[data-mode=in]').show()
+ }
+ if (fieldMap[field].items.indexOf('condition') !== -1) {
+ $('#soul-bf-type' + tableId + ' li[data-mode=condition]').show()
+ }
+
+ var top = $(this).offset().top - $('#soul-bf-type' + tableId).outerHeight() - 10,
+ left = $(this).offset().left;
+ $('#soul-bf-type' + tableId).find('li.soul-bf-selected').removeClass('soul-bf-selected')
+ switch ($(this).parent().data('mode')) {
+ case 'in':
+ $('#soul-bf-type' + tableId).find('li[data-mode="in"]')
+ .addClass('soul-bf-selected')
+ break;
+ case 'date':
+ $('#soul-bf-type' + tableId).find('li[data-mode="date"]')
+ .addClass('soul-bf-selected')
+ case 'condition':
+ $('#soul-bf-type' + tableId).find('li[data-value="' + $(this).parent().data('type') + '"]')
+ .addClass('soul-bf-selected')
+ }
+
+ $('#soul-bf-type' + tableId)
+ .data('type', $(this).parent().data('type'))
+ .data('mode', $(this).parent().data('mode'))
+ .data('id', $(this).parent().data('id'))
+ .data('group', $(this).parent().parent().data('id') || '')
+ .data('refresh', true)
+ .show()
+ .css({top: top, left: left})
+ .removeClass().addClass('fadeInUp animated')
+ })
+
+ // 4. 弹出值选择
+ $bottomCondition.find('.item-value').on('click', function (e) {
+ e.stopPropagation();
+ $('#main-list' + tableId).hide();
+ _this.hideColumns(myTable);
+ _this.hideBfType(myTable);
+ _this.hideBfPrefix(myTable)
+ _this.hideBfColumn(myTable);
+ var top,
+ left = $(this).offset().left,
+ mode = $(this).parent().data('mode'),
+ field = $(this).parent().data('field'),
+ id = $(this).parent().data('id'),
+ head = $(this).parent().data('head'),
+ prefix = $(this).parent().data('prefix');
+
+ switch (mode) {
+ case 'in':
+ _this.hideCondition(myTable);
+ if (dorpListTimeOut) {
+ clearTimeout(dorpListTimeOut);
+ }
+ $('#soul-dropList' + tableId + '>.filter-search>input').val('');
+ $('#soul-dropList' + tableId).show();
+ $('#soulDropList' + tableId).find('.' + field + 'DropList li input[type=checkbox]:checked').prop('checked', false);
+ var filterSo = _this.getFilterSoById(filterSos, id);
+ for (var i = 0; i < filterSo.values.length; i++) {
+ $('#soulDropList' + tableId).find('.' + field + 'DropList li input[type=checkbox][value="' + filterSo.values[i] + '"]').prop('checked', true);
+ }
+
+ $('#soul-dropList' + tableId + '>ul').data('id', id).data('head', head).data('refresh', true).data('prefix', prefix).html($('#soulDropList' + tableId).find('.' + field + 'DropList li').clone());
+ form.render('checkbox', 'orm');
+ top = $(this).offset().top - $('#soul-dropList' + tableId).outerHeight() - 10;
+ $('#soul-dropList' + tableId).css({'top': top, 'left': left})
+ .show().removeClass().addClass('fadeInUp animated');
+ setTimeout(function () {
+ $('#soul-dropList' + tableId + '>.filter-search>input').focus() // 聚焦搜索框
+ }, 1);
+
+
+ // 监听筛选数据
+ var liClick = true;
+ form.on('checkbox(soulDropList' + tableId + ')', function (data) {
+ liClick = false;
+ _this.updateDropList(myTable, field);
+ });
+
+ $('#soul-dropList' + tableId + '>ul>li[data-value]').on('click', function () {
+ if (liClick) {
+ $(this).find('div.layui-form-checkbox').trigger('click');
+ }
+ liClick = true;
+ })
+ break;
+ case 'date':
+ _this.hideDropList(myTable);
+ if (conditionTimeOut) {
+ clearTimeout(conditionTimeOut);
+ }
+ var filterSo = _this.getFilterSoById(filterSos, id),
+ top = $(this).offset().top - 10;
+
+ _this.showDate(myTable, field, filterSo, "fadeInUp", top, left, "up", true);
+ break;
+ default:
+ _this.hideDropList(myTable);
+ if (conditionTimeOut) {
+ clearTimeout(conditionTimeOut);
+ }
+ var obj = this,
+ value = $(this).parents('.condition-item:eq(0)').data('value');
+ $(obj).hide();
+ $(obj).after('
')
+ $(obj).next().children().val(value).select().on('keydown', function (e) {
+ if (e.keyCode === 13) {
+ $(this).blur();
+ }
+ }).on('blur', function () {
+ var newValue = $(this).val();
+ $(obj).html(typeof newValue === 'undefined' || newValue === '' ? '请输入...' : newValue);
+ $(obj).show();
+ $(this).parent().remove()
+ if (newValue !== value) {
+ _this.updateWhere(myTable, {
+ id: id,
+ value: newValue
+ })
+ _this.soulReload(myTable);
+ }
+ })
+
+ break;
+ }
+ })
+
+ /**
+ * 三、选择事件
+ */
+ // 1. 选择prefix
+ $('#soul-bf-prefix' + tableId + '>ul>li').off('click').on('click', function () {
+ var id = $(this).parent().parent().data('id'),
+ newPrefix = $(this).data('value'),
+ oldPrefix = $(this).parent().parent().data('prefix'),
+ refresh = $(this).parent().parent().data('refresh');
+
+ if (oldPrefix !== newPrefix) {
+ _this.updateWhere(myTable, {
+ id: id,
+ prefix: newPrefix
+ });
+ if (refresh === true) {
+ _this.soulReload(myTable);
+ }
+ }
+ })
+ // 1. 选择列
+ $('#soul-bf-column' + tableId + '>ul>li').off('click').on('click', function () {
+ var oldField = $(this).parent().parent().data('field'),
+ newField = $(this).data('field'),
+ mode = $(this).parent().parent().data('mode'),
+ group = $(this).parent().parent().data('group'),
+ refresh = $(this).parent().parent().data('refresh');
+
+ if (oldField !== newField) {
+ var filterSo = {
+ id: $(this).parent().parent().data('id'),
+ field: newField
+ }
+ if (fieldMap[newField].items.indexOf(modeMapItems[mode]) === -1) {
+ $.extend(filterSo, $.extend({}, revertMode[modeMapItems[mode]],
+ revertMode[modeMapItems[mode]].mode === 'condition' && _this.startsWith(tableFilterTypes[newField], 'date')
+ ? {
+ mode: 'date',
+ type: 'all'
+ } : {}))
+ } else {
+ // 重置values值
+ if (mode === 'in') {
+ $.extend(filterSo, {
+ values: []
+ })
+ } else if (mode === 'date' && !(_this.startsWith(tableFilterTypes[newField], 'date'))) {
+ $.extend(filterSo, {
+ mode: 'condition',
+ type: 'eq',
+ value: ''
+ })
+ } else if (mode !== 'date' && _this.startsWith(tableFilterTypes[newField], 'date')) {
+ $.extend(filterSo, {
+ mode: 'date',
+ type: 'all'
+ })
+ }
+ }
+ // 如果是头部条件,选择列是清除
+ if (group) {
+ _this.updateWhere(myTable, {
+ id: group,
+ head: false
+ })
+ }
+ _this.updateWhere(myTable, filterSo);
+
+ if ($('.soul-edit-out').length > 0) {
+ $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-field').html(fieldMap[newField].title);
+ if (filterSo.mode === 'in') {
+ $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-type').html('筛选数据')
+ $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-value').html('共0条数据')
+ } else if (mode !== filterSo.mode) {
+ if (filterSo.mode === 'date') {
+ $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-type').html('选择日期')
+ $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-value').html(dateTimeItems[filterSo.type])
+ } else if (filterSo.mode === 'condition') {
+ $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-type').html(conditionChangeItems[filterSo.type])
+ $('.soul-edit-out li[data-id="' + filterSo.id + '"]').children('.item-value').html(filterSo.value === '' ? '请输入...' : filterSo.value)
+ }
+ }
+ }
+
+ if (refresh === true) {
+ _this.soulReload(myTable);
+ }
+ }
+ })
+
+ // 2. 选择类型
+ $('#soul-bf-type' + tableId + '>ul>li').off('click').on('click', function () {
+ var newType = $(this).data('value') + "" // 引号修复为空(null值)传递问题
+ , newMode = $(this).data('mode')
+ , type = $(this).parent().parent().data('type')
+ , mode = $(this).parent().parent().data('mode')
+ , group = $(this).parent().parent().data('group')
+ , refresh = $(this).parent().parent().data('refresh')
+ if (type !== newType) {
+
+ var filterSo = {
+ id: $(this).parent().parent().data('id'),
+ type: newType,
+ mode: newMode
+ }
+ if (mode !== newMode) {
+ $.extend(filterSo, {
+ value: '',
+ values: []
+ })
+ }
+
+ // 如果是头部条件,选择列是清除
+ if (group && newMode === 'in') {
+ _this.updateWhere(myTable, {
+ id: group,
+ head: false
+ })
+ }
+ _this.updateWhere(myTable, filterSo)
+
+ if ($('.soul-edit-out').length > 0) {
+ $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-value').show();
+ $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-type').html(conditionChangeItems[newType] || (newMode === 'in' ? '筛选数据' : '选择日期'));
+ switch (newMode) {
+ case 'in':
+ $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-value').html('共0条数据');
+ break;
+ case 'date':
+ $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-value').html(dateTimeItems[newType]);
+ break;
+ case 'condition':
+ if (mode !== newMode) {
+ $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-value').html('请输入...');
+ }
+ $('.soul-edit-out li[data-id="' + filterSo.id + '"]').data(filterSo).children('.item-value')[newType === 'null' || newType === 'notNull' ? 'hide' : 'show']()
+
+ break;
+ }
+ }
+
+ // 是否立即更新
+ if (refresh === true) {
+ _this.soulReload(myTable);
+ }
+ }
+ })
+
+ /**
+ * 五、底部筛选条件删除事件
+ */
+ $bottomCondition.find('.condition-items .condition-item .condition-item-close').on('click', function () {
+ _this.updateWhere(myTable, {
+ id: $(this).parents('.condition-item:eq(0)').data('id'),
+ delete: true
+ })
+ _this.soulReload(myTable);
+ })
+
+ }
+ /**
+ * 导出 excel 文件
+ * @param myTable
+ * @param curExcel
+ */
+ , export: function (myTable, curExcel) {
+ if (typeof myTable === 'string') {
+ myTable = table_cache[myTable] // tableId 转 myTable
+ }
+ var loading = layer.msg('文件下载中', {
+ icon: 16
+ , time: -1
+ , anim: -1
+ , fixed: false
+ });
+ var cols = this.deepClone(myTable.cols)
+ , style = myTable.elem.next().find('style')[0]
+ , sheet = style.sheet || style.styleSheet || {}
+ , rules = sheet.cssRules || sheet.rules;
+
+ layui.each(rules, function (i, item) {
+ if (item.style.width) {
+ var keys = item.selectorText.split('-');
+ cols[keys[3]][keys[4]]['width'] = parseInt(item.style.width)
+ }
+ })
+
+ var data = JSON.parse(JSON.stringify(myTable.data || cache[myTable.id])),
+ showField = {},
+ widths = {},
+ mergeArrays = [], // 合并配置
+ heightConfig = {},
+ $table = $(myTable.elem),
+ $tableBody = $table.next().children('.layui-table-box').children('.layui-table-body').children('table'),
+ $tableTotal = myTable.totalRow ? $table.next().children('.layui-table-total').children(":first") : null,
+ finalExcel = Object.assign({}, myTable.excel, curExcel);
+
+ var filename = finalExcel.filename ? (typeof finalExcel.filename === 'function' ? finalExcel.filename.call(this) : finalExcel.filename) : '表格数据.xlsx',
+ checked = finalExcel.checked === true,
+ curPage = finalExcel.curPage === true,
+ customColumns = finalExcel.columns,
+ totalRow = finalExcel.totalRow,
+ type = filename.substring(filename.lastIndexOf('.') + 1, filename.length),
+ tableStartIndex = finalExcel.add && finalExcel.add.top && Array.isArray(finalExcel.add.top.data) ? finalExcel.add.top.data.length + 1 : 1, //表格内容从哪一行开始
+ bottomLength = finalExcel.add && finalExcel.add.bottom && Array.isArray(finalExcel.add.bottom.data) ? finalExcel.add.bottom.data.length : 0,// 底部自定义行数
+ i, j, k;
+
+ if (finalExcel.data){
+ if(Array.isArray(finalExcel.data)) {
+ data = finalExcel.data
+ } else {
+ console.error('导出指定数据 data 不符合数组格式', finalExcel.data)
+ layer.close(loading)
+ return;
+ }
+ } else if (checked) { // 获取选中行数据
+ // data = table.checkStatus(myTable.id).data;
+ data = []
+ if (cache[myTable.id] && cache[myTable.id].length > 0) {
+ for (i = 0; i < cache[myTable.id].length; i++) {
+ if (cache[myTable.id][i][table.config.checkName]) {
+ data.push(cache[myTable.id][i])
+ }
+ }
+ }
+ } else if (curPage) {
+ data = layui.table.cache[myTable.id]
+ } else if (myTable.url && myTable.page) {
+ var ajaxStatus = true;
+ var searchParam = isFilterCache[myTable.id] ? where_cache[myTable.id] : table_cache[myTable.id].where;
+ if (myTable.contentType && myTable.contentType.indexOf("application/json") == 0) { //提交 json 格式
+ searchParam = JSON.stringify(searchParam);
+ }
+ $.ajax({
+ url: myTable.url,
+ data: searchParam,
+ dataType: 'json',
+ method: myTable.method || 'post',
+ async: false,
+ cache: false,
+ headers: myTable.headers || {},
+ contentType: myTable.contentType,
+ success: function (res) {
+ if (typeof myTable.parseData === 'function') {
+ res = myTable.parseData(res) || res;
+ }
+ //检查数据格式是否符合规范
+ if (res[myTable.response.statusName] != myTable.response.statusCode) {
+ layer.msg('返回的数据不符合规范,正确的成功状态码应为:"' + myTable.response.statusName + '": ' + myTable.response.statusCode, {
+ icon: 2,
+ anim: 6
+ });
+ } else {
+ data = res[myTable.response.dataName]
+ }
+ },
+ error: function (res) {
+ layer.msg('请求异常!', {icon: 2, anim: 6});
+ ajaxStatus = false;
+ }
+ })
+ if (!ajaxStatus) {
+ return;
+ }
+ } else {
+ var $sortDoom = $table.next().children('.layui-table-box').children('.layui-table-header').find('.layui-table-sort[lay-sort$="sc"]:eq(0)')
+ if ($sortDoom.length > 0) {
+ var sortField = $sortDoom.parent().parent().data('field');
+ var sortOrder = $sortDoom.attr('lay-sort');
+ switch (sortOrder) {
+ case 'asc':
+ data = layui.sort(data, sortField);
+ break;
+ case 'desc':
+ data = layui.sort(data, sortField, true);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ // 制定显示列和顺序
+ var tempArray, cloneCol, columnsMap = [], curRowUnShowCount;
+ for (i = 0; i < cols.length; i++) {
+ curRowUnShowCount = 0;
+ for (j = 0; j < cols[i].length; j++) {
+ if (!cols[i][j].exportHandled) {
+ if (cols[i][j].rowspan > 1) {
+ if ((cols[i][j].field || cols[i][j].type === 'numbers') && !cols[i][j].hide) {
+ mergeArrays.push([numberToLetter(j + 1 - curRowUnShowCount) + (i + tableStartIndex), numberToLetter(j + 1 - curRowUnShowCount) + (i + parseInt(cols[i][j].rowspan) + tableStartIndex - 1)])
+ } else {
+ curRowUnShowCount++;
+ }
+ cloneCol = this.deepClone(cols[i][j])
+ cloneCol.exportHandled = true;
+ k = i + 1;
+ while (k < cols.length) {
+ cols[k].splice(j, 0, cloneCol)
+ k++
+ }
+ }
+ if (cols[i][j].colspan > 1) {
+ mergeArrays.push([numberToLetter(j + 1 - curRowUnShowCount) + (i + tableStartIndex), numberToLetter(j + parseInt(cols[i][j].colspan) - curRowUnShowCount) + (i + tableStartIndex)])
+ cloneCol = this.deepClone(cols[i][j])
+ cloneCol.exportHandled = true;
+ for (k = 1; k < cols[i][j].colspan; k++) {
+ cols[i].splice(j, 0, cloneCol)
+ }
+ j = j + parseInt(cols[i][j].colspan) - 1
+
+ }
+ } else if (!((cols[i][j].field || cols[i][j].type === 'numbers') && !cols[i][j].hide)) {
+ curRowUnShowCount++;
+ }
+ }
+ }
+ var columns = cols[cols.length - 1]; // 获取真实列
+
+ // 处理数据
+ for (i = 0; i < data.length; i++) {
+ for (j = 0; j < columns.length; j++) {
+ if ((columns[j].field || columns[j].type === 'numbers') && (customColumns && Array.isArray(customColumns) || !columns[j].hide)) {
+ data[i][columns[j].key] = data[i][columns[j].field || columns[j]['LAY_INDEX']]
+ }
+ }
+ }
+
+ // 处理合计行
+ if (totalRow !== false && myTable.totalRow) {
+ var obj = {}, totalRows = {};
+ if (typeof totalRow === 'object' && totalRow.type === 'origin') {
+ // 通过 dom 解析
+ for (i = 0; i < columns.length; i++) {
+ if (columns[i].field) {
+ obj[columns[i].key] = $tableTotal.find('[data-field="'+columns[i].field+'"]').text().trim()
+ }
+ }
+ data.push(obj);
+ } else {
+ // 通过数据解析
+ for (i = 0; i < columns.length; i++) {
+ if (columns[i].totalRowText) {
+ obj[columns[i].key] = columns[i].totalRowText
+ } else if (columns[i].totalRow) {
+ totalRows[columns[i].key] = 0
+ }
+ }
+ if (JSON.stringify(totalRows) !== '{}') {
+ for (i = 0; i < data.length; i++) {
+ for (var key in totalRows) {
+ totalRows[key] = (parseFloat(totalRows[key]) + (parseFloat(data[i][key]) || 0)).toFixed(2)
+ }
+ }
+ }
+ data.push(Object.assign(obj, totalRows));
+ }
+ }
+
+ if (customColumns && Array.isArray(customColumns)) {
+ // 自定义表头
+ var tempCustomColumns = [];
+ tempArray = {};
+ mergeArrays = []; // 重置表头合并列
+ columnsMap[0] = {};
+ for (i = 0; i < customColumns.length; i++) {
+ for (j = 0; j < columns.length; j++) {
+ if (columns[j].field === customColumns[i]) {
+ columns[j].hide = false
+ tempCustomColumns.push(columns[j]);
+ columnsMap[0][columns[j].key] = columns[j];
+ tempArray[columns[j].key] = $('
'+columns[j].title+'
').text()
+ break;
+ }
+ }
+ }
+ columns = tempCustomColumns;
+ data.splice(0, 0, tempArray)
+ } else {
+ // 拼接表头数据
+ for (i = 0; i < cols.length; i++) {
+ columnsMap[i] = {}
+ tempArray = {}
+ for (j = 0; j < cols[i].length; j++) {
+ columnsMap[i][cols[cols.length - 1][j].key] = cols[i][j];
+ tempArray[cols[cols.length - 1][j].key] = $('
'+cols[i][j].title+'
').text()
+ }
+ data.splice(i, 0, tempArray)
+ }
+ }
+
+ //添加自定义内容
+ if (finalExcel.add) {
+ var addTop = finalExcel.add.top,
+ addBottom = finalExcel.add.bottom,
+ startPos, endPos, jumpColsNum;
+
+ if (addTop && Array.isArray(addTop.data) && addTop.data.length > 0) {
+
+ for (i = 0; i < addTop.data.length; i++) {
+ tempArray = {}, jumpColsNum = 0;
+ for (j = 0; j < (addTop.data[i].length > columns.length ? addTop.data[i].length : columns.length); j++) {
+ if ((columns[j].field || columns[j].type === 'numbers') && !columns[j].hide) {
+ tempArray[columns[j] ? columns[j].key : j + ''] = addTop.data[i][j - jumpColsNum] || ''
+ } else {
+ jumpColsNum++
+ }
+ }
+ data.splice(i, 0, tempArray);
+ }
+
+ if (Array.isArray(addTop.heights) && addTop.heights.length > 0) {
+ for (i = 0; i < addTop.heights.length; i++) {
+ heightConfig[i] = addTop.heights[i]
+ }
+ }
+
+ if (Array.isArray(addTop.merge) && addTop.merge.length > 0) {
+ for (i = 0; i < addTop.merge.length; i++) {
+ if (addTop.merge[i].length === 2) {
+ startPos = addTop.merge[i][0].split(',');
+ endPos = addTop.merge[i][1].split(',');
+ mergeArrays.push([numberToLetter(startPos[1]) + startPos[0], numberToLetter(endPos[1]) + endPos[0]])
+ }
+
+ }
+ }
+ }
+ if (addBottom && Array.isArray(addBottom.data) && addBottom.data.length > 0) {
+ for (i = 0; i < addBottom.data.length; i++) {
+ tempArray = {}, jumpColsNum = 0;
+ for (j = 0; j < (addBottom.data[i].length > columns.length ? addBottom.data[i].length : columns.length); j++) {
+ if ((columns[j].field || columns[j].type === 'numbers') && !columns[j].hide) {
+ tempArray[columns[j] ? columns[j].key : j + ''] = addBottom.data[i][j - jumpColsNum] || ''
+ } else {
+ jumpColsNum++
+ }
+ }
+ data.push(tempArray);
+ }
+
+ if (Array.isArray(addBottom.heights) && addBottom.heights.length > 0) {
+ for (i = 0; i < addBottom.heights.length; i++) {
+ heightConfig[data.length - addBottom.data.length + i] = addBottom.heights[i]
+ }
+ }
+
+ if (Array.isArray(addBottom.merge) && addBottom.merge.length > 0) {
+ for (i = 0; i < addBottom.merge.length; i++) {
+ if (addBottom.merge[i].length === 2) {
+ startPos = addBottom.merge[i][0].split(',');
+ endPos = addBottom.merge[i][1].split(',');
+ mergeArrays.push([numberToLetter(startPos[1]) + (data.length - addBottom.data.length + parseInt(startPos[0])), numberToLetter(endPos[1]) + (data.length - addBottom.data.length + parseInt(endPos[0]))])
+ }
+ }
+ }
+ }
+ }
+
+ var index = 0, alignTrans = {'left': 'left', 'center': 'center', 'right': 'right'},
+ borderTypes = ['top', 'bottom', 'left', 'right'];
+ for (i = 0; i < columns.length; i++) {
+ if ((columns[i].field || columns[i].type === 'numbers') && !columns[i].hide) {
+ if (columns[i].width) {
+ widths[String.fromCharCode(64 + parseInt(++index))] = columns[i].width
+ }
+ showField[columns[i].key] = function (field, line, data, curIndex) {
+ var bgColor = 'ffffff', color = '000000', family = 'Calibri', size = 12, cellType = 's',
+ bodyIndex = curIndex - (customColumns ? 1 : cols.length) - tableStartIndex + 1,
+ border = {
+ top: {
+ style: 'thin',
+ color: {indexed: 64}
+ },
+ bottom: {
+ style: 'thin',
+ color: {indexed: 64}
+ },
+ left: {
+ style: 'thin',
+ color: {indexed: 64}
+ },
+ right: {
+ style: 'thin',
+ color: {indexed: 64}
+ }
+ }
+ if (finalExcel.border) {
+ for (j = 0; j < borderTypes.length; j++) {
+ if (finalExcel.border[borderTypes[j]]) {
+ border[borderTypes[j]].style = finalExcel.border[borderTypes[j]].style || border[borderTypes[j]].style
+ border[borderTypes[j]].color = handleRgb(finalExcel.border[borderTypes[j]].color) || border[borderTypes[j]].color
+ } else if (finalExcel.border['color'] || finalExcel.border['style']) {
+ border[borderTypes[j]].style = finalExcel.border['style'] || border[borderTypes[j]].style
+ border[borderTypes[j]].color = handleRgb(finalExcel.border['color']) || border[borderTypes[j]].color
+ }
+ }
+ }
+ if (curIndex < tableStartIndex - 1 || curIndex >= data.length - bottomLength) {
+ return {
+ v: line[field] || '',
+ s: {// s 代表样式
+ alignment: {
+ horizontal: 'center',
+ vertical: 'center'
+ },
+ font: {name: family, sz: size, color: {rgb: color}},
+ fill: {
+ fgColor: {rgb: bgColor, bgColor: {indexed: 64}}
+ },
+ border: border
+ },
+ t: cellType
+ }
+ } else if (bodyIndex < 0) {
+ // 头部样式
+ bgColor = 'C7C7C7';
+ if (finalExcel.head) {
+ bgColor = finalExcel.head.bgColor || bgColor;
+ color = finalExcel.head.color || color;
+ family = finalExcel.head.family || family;
+ size = finalExcel.head.size || size;
+ }
+ } else {
+ // 默认全局字体样式
+ if (finalExcel.font) {
+ bgColor = finalExcel.font.bgColor || bgColor;
+ color = finalExcel.font.color || color;
+ family = finalExcel.font.family || family;
+ size = finalExcel.font.size || size;
+ }
+ // 默认全局边框样式
+ if (finalExcel.border) {
+ for (j = 0; j < borderTypes.length; j++) {
+ if (finalExcel.border[borderTypes[j]]) {
+ border[borderTypes[j]].style = finalExcel.border[borderTypes[j]].style || border[borderTypes[j]].style
+ border[borderTypes[j]].color = handleRgb(finalExcel.border[borderTypes[j]].color) || border[borderTypes[j]].color
+ } else if (finalExcel.border['color'] || finalExcel.border['style']) {
+ border[borderTypes[j]].style = finalExcel.border['style'] || border[borderTypes[j]].style
+ border[borderTypes[j]].color = handleRgb(finalExcel.border['color']) || border[borderTypes[j]].color
+ }
+ }
+ }
+ // 列上配置了自定义样式
+ if (columnsMap[columnsMap.length - 1][field].excel) {
+ var colExcel = typeof columnsMap[columnsMap.length - 1][field].excel === 'function' ? columnsMap[columnsMap.length - 1][field].excel.call(this, line, bodyIndex, data.length - cols.length - tableStartIndex + 1 - bottomLength) : columnsMap[columnsMap.length - 1][field].excel
+ if (colExcel) {
+ bgColor = colExcel.bgColor || bgColor;
+ color = colExcel.color || color;
+ family = colExcel.family || family;
+ size = colExcel.size || size;
+ cellType = colExcel.cellType || cellType;
+
+ if (colExcel.border) {
+ for (j = 0; j < borderTypes.length; j++) {
+ if (colExcel.border[borderTypes[j]]) {
+ border[borderTypes[j]].style = colExcel.border[borderTypes[j]].style || border[borderTypes[j]].style
+ border[borderTypes[j]].color = handleRgb(colExcel.border[borderTypes[j]].color) || border[borderTypes[j]].color
+ } else if (colExcel.border['color'] || colExcel.border['style']) {
+ border[borderTypes[j]].style = colExcel.border['style'] || border[borderTypes[j]].style
+ border[borderTypes[j]].color = handleRgb(colExcel.border['color']) || border[borderTypes[j]].color
+ }
+ }
+ }
+ }
+ }
+ }
+
+ function handleNull(val) {
+ if (typeof val === 'undefined' || val === null) {
+ return ""
+ }
+ return val;
+ }
+
+ var value = bodyIndex >= 0 && columnsMap[columnsMap.length - 1][field].templet ?
+ typeof columnsMap[columnsMap.length - 1][field].templet === 'function' ?
+ $('
' + columnsMap[columnsMap.length - 1][field].templet(line) + '
').find(':input').length === 0 ? $('
' + columnsMap[columnsMap.length - 1][field].templet(line) + '
').text() : $tableBody.children('tbody').children('tr[data-index=' + bodyIndex + ']').children('td[data-key="' + field + '"]').find(':input').val() || handleNull(line[field])
+ : $('
' + laytpl($(columnsMap[columnsMap.length - 1][field].templet).html() || String(columnsMap[columnsMap.length - 1][field].templet)).render(line) + '
').find(':input').length === 0 ? $('
' + laytpl($(columnsMap[columnsMap.length - 1][field].templet).html() || String(columnsMap[columnsMap.length - 1][field].templet)).render(line) + '
').text() : $tableBody.children('tbody').children('tr[data-index=' + bodyIndex + ']').children('td[data-key="' + field + '"]').find(':input').val() || handleNull(line[field])
+ : bodyIndex >= 0 && columnsMap[columnsMap.length - 1][field].type === 'numbers' ? bodyIndex + 1 : handleNull(line[field]);
+ return {
+ v: value,// v 代表单元格的值
+ s: {// s 代表样式
+ alignment: {
+ horizontal: columnsMap[bodyIndex < -1 ? curIndex - tableStartIndex + 1 : columnsMap.length - 1][field].align ? alignTrans[columnsMap[bodyIndex < -1 ? curIndex - tableStartIndex + 1 : columnsMap.length - 1][field].align] : 'top',
+ vertical: 'center'
+ },
+ font: {name: family, sz: size, color: {rgb: color}},
+ fill: {
+ fgColor: {rgb: bgColor, bgColor: {indexed: 64}}
+ },
+ border: border
+ },
+ t: UNHANDLED_VALUES.indexOf(value) === -1 ? cellType : 's'
+ };
+ }
+ }
+ }
+
+ excel.exportExcel({
+ sheet1: excel.filterExportData(data, showField)
+ }, filename, type, {
+ extend: {
+ '!cols': excel.makeColConfig(widths, 80),
+ '!merges': excel.makeMergeConfig(mergeArrays),
+ '!rows': excel.makeRowConfig(heightConfig, 16)
+ }
+ });
+ layer.close(loading);
+
+ // 合成 excel.js 识别的 rgb
+ function handleRgb(rgb) {
+ return rgb ? {rgb: rgb} : rgb
+ }
+
+ function numberToLetter(num) {
+ var result = [];
+ while (num) {
+ var t = num % 26;
+ if (!t) {
+ t = 26;
+ --num;
+ }
+ // Polyfill 兼容旧浏览器
+ if (!String.fromCodePoint) (function (stringFromCharCode) {
+ var fromCodePoint = function (_) {
+ var codeUnits = [], codeLen = 0, result = "";
+ for (var index = 0, len = arguments.length; index !== len; ++index) {
+ var codePoint = +arguments[index];
+ // correctly handles all cases including `NaN`, `-Infinity`, `+Infinity`
+ // The surrounding `!(...)` is required to correctly handle `NaN` cases
+ // The (codePoint>>>0) === codePoint clause handles decimals and negatives
+ if (!(codePoint < 0x10FFFF && (codePoint >>> 0) === codePoint))
+ throw RangeError("Invalid code point: " + codePoint);
+ if (codePoint <= 0xFFFF) { // BMP code point
+ codeLen = codeUnits.push(codePoint);
+ } else { // Astral code point; split in surrogate halves
+ // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
+ codePoint -= 0x10000;
+ codeLen = codeUnits.push(
+ (codePoint >> 10) + 0xD800, // highSurrogate
+ (codePoint % 0x400) + 0xDC00 // lowSurrogate
+ );
+ }
+ if (codeLen >= 0x3fff) {
+ result += stringFromCharCode.apply(null, codeUnits);
+ codeUnits.length = 0;
+ }
+ }
+ return result + stringFromCharCode.apply(null, codeUnits);
+ };
+ try { // IE 8 only supports `Object.defineProperty` on DOM elements
+ Object.defineProperty(String, "fromCodePoint", {
+ "value": fromCodePoint, "configurable": true, "writable": true
+ });
+ } catch (e) {
+ String.fromCodePoint = fromCodePoint;
+ }
+ }(String.fromCharCode));
+ result.push(String.fromCodePoint(t + 64));
+ if (!String.fromCodePoint) (function (stringFromCharCode) {
+ var fromCodePoint = function (_) {
+ var codeUnits = [], codeLen = 0, result = "";
+ for (var index = 0, len = arguments.length; index !== len; ++index) {
+ var codePoint = +arguments[index];
+ // correctly handles all cases including `NaN`, `-Infinity`, `+Infinity`
+ // The surrounding `!(...)` is required to correctly handle `NaN` cases
+ // The (codePoint>>>0) === codePoint clause handles decimals and negatives
+ if (!(codePoint < 0x10FFFF && (codePoint >>> 0) === codePoint))
+ throw RangeError("Invalid code point: " + codePoint);
+ if (codePoint <= 0xFFFF) { // BMP code point
+ codeLen = codeUnits.push(codePoint);
+ } else { // Astral code point; split in surrogate halves
+ // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
+ codePoint -= 0x10000;
+ codeLen = codeUnits.push(
+ (codePoint >> 10) + 0xD800, // highSurrogate
+ (codePoint % 0x400) + 0xDC00 // lowSurrogate
+ );
+ }
+ if (codeLen >= 0x3fff) {
+ result += stringFromCharCode.apply(null, codeUnits);
+ codeUnits.length = 0;
+ }
+ }
+ return result + stringFromCharCode.apply(null, codeUnits);
+ };
+ try { // IE 8 only supports `Object.defineProperty` on DOM elements
+ Object.defineProperty(String, "fromCodePoint", {
+ "value": fromCodePoint, "configurable": true, "writable": true
+ });
+ } catch (e) {
+ String.fromCodePoint = fromCodePoint;
+ }
+ }(String.fromCharCode));
+ num = ~~(num / 26);
+ }
+ return result.reverse().join('');
+ }
+ },
+ startsWith: function (content, str) {
+ var reg = new RegExp("^" + str);
+ return content && reg.test(content);
+ },
+ // 深度克隆-不丢失方法
+ deepClone: function (obj) {
+ var newObj = Array.isArray(obj) ? [] : {}
+ if (obj && typeof obj === "object") {
+ for (var key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ newObj[key] = (obj && typeof obj[key] === 'object') ? this.deepClone(obj[key]) : obj[key];
+ }
+ }
+ }
+ return newObj
+ },
+ deepStringify: function (obj) {
+ var JSON_SERIALIZE_FIX = {
+ PREFIX: "[[JSON_FUN_PREFIX_",
+ SUFFIX: "_JSON_FUN_SUFFIX]]"
+ };
+ return JSON.stringify(obj, function (key, value) {
+ if (typeof value === 'function') {
+ return JSON_SERIALIZE_FIX.PREFIX + value.toString() + JSON_SERIALIZE_FIX.SUFFIX;
+ }
+ return value;
+ });
+ },
+ /* layui table 中原生的方法 */
+ getScrollWidth: function (elem) {
+ var width = 0;
+ if (elem) {
+ width = elem.offsetWidth - elem.clientWidth;
+ } else {
+ elem = document.createElement('div');
+ elem.style.width = '100px';
+ elem.style.height = '100px';
+ elem.style.overflowY = 'scroll';
+
+ document.body.appendChild(elem);
+ width = elem.offsetWidth - elem.clientWidth;
+ document.body.removeChild(elem);
+ }
+ return width;
+ }
+ , getCompleteCols: function (origin) {
+ var cols = this.deepClone(origin);
+ var i, j, k, cloneCol;
+ for (i = 0; i < cols.length; i++) {
+ for (j = 0; j < cols[i].length; j++) {
+ if (!cols[i][j].exportHandled) {
+ if (cols[i][j].rowspan > 1) {
+ cloneCol = this.deepClone(cols[i][j])
+ cloneCol.exportHandled = true;
+ k = i + 1;
+ while (k < cols.length) {
+ cols[k].splice(j, 0, cloneCol)
+ k++
+ }
+ }
+ if (cols[i][j].colspan > 1) {
+ cloneCol = this.deepClone(cols[i][j])
+ cloneCol.exportHandled = true;
+ for (k = 1; k < cols[i][j].colspan; k++) {
+ cols[i].splice(j, 0, cloneCol)
+ }
+ j = j + parseInt(cols[i][j].colspan) - 1
+ }
+ }
+ }
+ }
+ return cols[cols.length - 1];
+ }
+ , parseTempData: function (item3, content, tplData, text) { //表头数据、原始内容、表体数据、是否只返回文本
+ var str = item3.templet ? function () {
+ return typeof item3.templet === 'function'
+ ? item3.templet(tplData)
+ : laytpl($(item3.templet).html() || String(content)).render(tplData)
+ }() : content;
+ return text ? $('
' + str + '
').text() : str;
+ }
+ , cache: cache
+ };
+
+ // 输出
+ exports('tableFilter', mod);
});
diff --git a/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/tableMerge.js b/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/tableMerge.js
index 44e75ae..fa98da3 100644
--- a/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/tableMerge.js
+++ b/HT.Cloud.Web/wwwroot/js/lay-module/soulTable/tableMerge.js
@@ -4,100 +4,100 @@
* @author: yelog
* @link: https://github.com/yelog/layui-soul-table
* @license: MIT
- * @version: v1.6.1
+ * @version: v1.9.0
*/
layui.define(['table'], function (exports) {
- var $ = layui.jquery;
+ var $ = layui.jquery;
- // 封装方法
- var mod = {
- /**
- * 渲染入口
- * @param myTable
- */
- render: function (myTable) {
- var tableBox = $(myTable.elem).next().children('.layui-table-box'),
- $main = $(tableBox.children('.layui-table-body').children('table').children('tbody').children('tr').toArray().reverse()),
- $fixLeft = $(tableBox.children('.layui-table-fixed-l').children('.layui-table-body').children('table').children('tbody').children('tr').toArray().reverse()),
- $fixRight = $(tableBox.children('.layui-table-fixed-r').children('.layui-table-body').children('table').children('tbody').children('tr').toArray().reverse()),
- mergeRecord = {};
+ // 封装方法
+ var mod = {
+ /**
+ * 渲染入口
+ * @param myTable
+ */
+ render: function (myTable) {
+ var tableBox = $(myTable.elem).next().children('.layui-table-box'),
+ $main = $(tableBox.children('.layui-table-body').children('table').children('tbody').children('tr').toArray().reverse()),
+ $fixLeft = $(tableBox.children('.layui-table-fixed-l').children('.layui-table-body').children('table').children('tbody').children('tr').toArray().reverse()),
+ $fixRight = $(tableBox.children('.layui-table-fixed-r').children('.layui-table-body').children('table').children('tbody').children('tr').toArray().reverse()),
+ mergeRecord = {};
- layui.each(myTable.cols, function (i1, item1) {
- layui.each(item1, function (i2, item2) {
- if (item2.merge && item2.field) {
- var mergeField = [item2.field];
- if (item2.merge !== true) {
- if (typeof item2.merge === 'string') {
- mergeField = [item2.merge]
- } else {
- mergeField = item2.merge
- }
- }
- mergeRecord[myTable.index + '-' + i1 + '-' + i2] = { mergeField: mergeField, rowspan: 1 }
- }
- })
- })
-
- $main.each(function (i) {
-
- for (var item in mergeRecord) {
- if (i === $main.length - 1 || isMaster(i, item)) {
- var tdHeight = $(this).children('[data-key="' + item + '"]').outerHeight(), patchHeight = 0; // 获取td高度
- if ($main.eq(i).data('index') === 0) {
- patchHeight = 1
- }
- $(this).children('[data-key="' + item + '"]').attr('rowspan', mergeRecord[item].rowspan).css({
- 'position': 'static',
- 'height': tdHeight * mergeRecord[item].rowspan + patchHeight
- }).children().css({
- height: 'auto',
- 'white-space': 'normal',
- 'max-height': tdHeight * mergeRecord[item].rowspan + patchHeight - 10
- });
- $fixLeft.eq(i).children('[data-key="' + item + '"]').attr('rowspan', mergeRecord[item].rowspan).css({
- 'position': 'static',
- 'height': tdHeight * mergeRecord[item].rowspan + patchHeight
- }).children().css({
- height: 'auto',
- 'white-space': 'normal',
- 'max-height': tdHeight * mergeRecord[item].rowspan + patchHeight - 10
- });
- $fixRight.eq(i).children('[data-key="' + item + '"]').attr('rowspan', mergeRecord[item].rowspan).css({
- 'position': 'static',
- 'height': tdHeight * mergeRecord[item].rowspan + patchHeight
- }).children().css({
- height: 'auto',
- 'white-space': 'normal',
- 'max-height': tdHeight * mergeRecord[item].rowspan + patchHeight - 10
- });
- mergeRecord[item].rowspan = 1;
- } else {
- $(this).children('[data-key="' + item + '"]').remove();
- $fixLeft.eq(i).children('[data-key="' + item + '"]').remove();
- $fixRight.eq(i).children('[data-key="' + item + '"]').remove();
- mergeRecord[item].rowspan += 1;
- }
- }
- })
-
- function isMaster(index, item) {
- var mergeField = mergeRecord[item].mergeField;
- var dataLength = layui.table.cache[myTable.id].length;
- for (var i = 0; i < mergeField.length; i++) {
-
- if (layui.table.cache[myTable.id][dataLength - 2 - index][mergeField[i]]
- !== layui.table.cache[myTable.id][dataLength - 1 - index][mergeField[i]]) {
- return true;
- }
- }
- return false;
+ layui.each(myTable.cols, function (i1, item1) {
+ layui.each(item1, function (i2, item2) {
+ if (item2.merge && item2.field) {
+ var mergeField = [item2.field];
+ if (item2.merge !== true) {
+ if (typeof item2.merge === 'string') {
+ mergeField = [item2.merge]
+ } else {
+ mergeField = item2.merge
+ }
}
+ mergeRecord[myTable.index + '-' + i1 + '-' + i2] = {mergeField: mergeField, rowspan: 1}
+ }
+ })
+ })
+ $main.each(function (i) {
+
+ for (var item in mergeRecord) {
+ if (i === $main.length - 1 || isMaster(i, item)) {
+ var tdHeight = $(this).children('[data-key="' + item + '"]').outerHeight(), patchHeight = 0; // 获取td高度
+ if ($main.eq(i).data('index') === 0) {
+ patchHeight = 1
+ }
+ $(this).children('[data-key="' + item + '"]').attr('rowspan', mergeRecord[item].rowspan).css({
+ 'position': 'static',
+ 'height': tdHeight * mergeRecord[item].rowspan + patchHeight
+ }).children().css({
+ height: 'auto',
+ 'white-space': 'normal',
+ 'max-height': tdHeight * mergeRecord[item].rowspan + patchHeight - 10
+ });
+ $fixLeft.eq(i).children('[data-key="' + item + '"]').attr('rowspan', mergeRecord[item].rowspan).css({
+ 'position': 'static',
+ 'height': tdHeight * mergeRecord[item].rowspan + patchHeight
+ }).children().css({
+ height: 'auto',
+ 'white-space': 'normal',
+ 'max-height': tdHeight * mergeRecord[item].rowspan + patchHeight - 10
+ });
+ $fixRight.eq(i).children('[data-key="' + item + '"]').attr('rowspan', mergeRecord[item].rowspan).css({
+ 'position': 'static',
+ 'height': tdHeight * mergeRecord[item].rowspan + patchHeight
+ }).children().css({
+ height: 'auto',
+ 'white-space': 'normal',
+ 'max-height': tdHeight * mergeRecord[item].rowspan + patchHeight - 10
+ });
+ mergeRecord[item].rowspan = 1;
+ } else {
+ $(this).children('[data-key="' + item + '"]').remove();
+ $fixLeft.eq(i).children('[data-key="' + item + '"]').remove();
+ $fixRight.eq(i).children('[data-key="' + item + '"]').remove();
+ mergeRecord[item].rowspan += 1;
+ }
}
- };
+ })
- // 输出
- exports('tableMerge', mod);
+ function isMaster(index, item) {
+ var mergeField = mergeRecord[item].mergeField;
+ var dataLength = layui.table.cache[myTable.id].length;
+ for (var i = 0; i < mergeField.length; i++) {
+
+ if (layui.table.cache[myTable.id][dataLength - 2 - index][mergeField[i]]
+ !== layui.table.cache[myTable.id][dataLength - 1 - index][mergeField[i]]) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ }
+ };
+
+ // 输出
+ exports('tableMerge', mod);
});
diff --git a/HT.Cloud.Web/wwwroot/js/lay-module/tabletree/tabletree.js b/HT.Cloud.Web/wwwroot/js/lay-module/tabletree/tabletree.js
index 5948467..920a53c 100644
--- a/HT.Cloud.Web/wwwroot/js/lay-module/tabletree/tabletree.js
+++ b/HT.Cloud.Web/wwwroot/js/lay-module/tabletree/tabletree.js
@@ -166,14 +166,14 @@ layui.define(['layer', 'table','soulTable'], function (exports) {
if (isOpen) {
$(this).hide();
var index = $(this).attr('data-index');
- $('div[lay-id=' + id + ']').find('.layui-table-fixed tbody tr[data-index= ' + index + ']').hide();
+ $('div[lay-table-id=' + id + ']').find('.layui-table-fixed tbody tr[data-index= ' + index + ']').hide();
if ('dir' == ttype && tOpen == isOpen) {
$ti.trigger('click');
}
} else {
$(this).show();
var index = $(this).attr('data-index');
- $('div[lay-id=' + id + ']').find('.layui-table-fixed tbody tr[data-index= ' + index + ']').show();
+ $('div[lay-table-id=' + id + ']').find('.layui-table-fixed tbody tr[data-index= ' + index + ']').show();
if (linkage && 'dir' == ttype && tOpen == isOpen) {
$ti.trigger('click');
}
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/css/layui.css b/HT.Cloud.Web/wwwroot/lib/layui/css/layui.css
index 7037848..202c082 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/css/layui.css
+++ b/HT.Cloud.Web/wwwroot/lib/layui/css/layui.css
@@ -19,7 +19,7 @@ pre{white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; w
/** 初始化全局标签 **/
body{line-height: 1.6; color: #333; color: rgba(0,0,0,.85); font: 14px Helvetica Neue,Helvetica,PingFang SC,Tahoma,Arial,sans-serif;}
-hr{height: 0; line-height: 0; margin: 10px 0; padding: 0; border: none!important; border-bottom: 1px solid #eee !important; clear: both; overflow: hidden; background: none;}
+hr{height: 0; line-height: 0; margin: 10px 0; padding: 0; border: none; border-bottom: 1px solid #eee; clear: both; overflow: hidden; background: none;}
a{color: #333; text-decoration:none;}
a:hover{color: #777;}
a cite{font-style: normal; *cursor:pointer;}
@@ -513,12 +513,37 @@ a cite{font-style: normal; *cursor:pointer;}
.layui-col-space32>*{padding: 16px;}
-/** 页面元素 **/
-.layui-btn, .layui-input, .layui-textarea, .layui-upload-button, .layui-select{outline: none; -webkit-appearance: none; transition: all .3s; -webkit-transition: all .3s; box-sizing: border-box;}
+/* 内边距 */
+.layui-padding-1{padding: 4px !important;}
+.layui-padding-2{padding: 8px !important;}
+.layui-padding-3{padding: 16px !important;}
+.layui-padding-4{padding: 32px !important;}
+.layui-padding-5{padding: 48px !important;}
-/* 引用 */.layui-elem-quote{margin-bottom: 10px; padding: 15px; line-height: 1.8; border-left: 5px solid #16b777; border-radius: 0 2px 2px 0; background-color: #fafafa;}
+/* 外边距 */
+.layui-margin-1{margin: 4px !important;}
+.layui-margin-2{margin: 8px !important;}
+.layui-margin-3{margin: 16px !important;}
+.layui-margin-4{margin: 32px !important;}
+.layui-margin-5{margin: 48px !important;}
+
+
+/*
+ * 页面元素
+ */
+
+.layui-btn,
+.layui-input,
+.layui-select,
+.layui-textarea,
+.layui-upload-button{outline: none; -webkit-appearance: none; transition: all .3s; -webkit-transition: all .3s; box-sizing: border-box;}
+
+/* 引用 */
+.layui-elem-quote{margin-bottom: 10px; padding: 15px; line-height: 1.8; border-left: 5px solid #16b777; border-radius: 0 2px 2px 0; background-color: #fafafa;}
.layui-quote-nm{border-style: solid; border-width: 1px; border-left-width: 5px; background: none;}
-/* 字段集合 */.layui-elem-field{margin-bottom: 10px; padding: 0; border-width: 1px; border-style: solid;}
+
+/* 字段集合 */
+.layui-elem-field{margin-bottom: 10px; padding: 0; border-width: 1px; border-style: solid;}
.layui-elem-field legend{margin-left: 20px; padding: 0 10px; font-size: 20px;}
.layui-field-title{margin: 16px 0; border-width: 0; border-top-width: 1px;}
.layui-field-box{padding: 15px;}
@@ -534,10 +559,8 @@ a cite{font-style: normal; *cursor:pointer;}
/*
-
- 面板
-
-*/
+ * 面板
+ */
/* 折叠面板 */
@@ -566,8 +589,8 @@ a cite{font-style: normal; *cursor:pointer;}
.layui-panel-window{position: relative; padding: 15px; border-radius: 0; border-top: 5px solid #eee; background-color: #fff;}
/* 其它辅助 */
-.layui-auxiliar-moving{position: fixed; left: 0; right: 0; top: 0; bottom: 0; width: 100%; height: 100%; background: none; z-index: 9999999999;}
-.layui-scollbar-hide{overflow: hidden !important;}
+.layui-auxiliar-moving{position: fixed; left: 0; right: 0; top: 0; bottom: 0; width: 100%; height: 100%; background: none; z-index: 9999999999; -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; user-select: none;}
+.layui-scrollbar-hide{overflow: hidden !important;}
/*
@@ -613,6 +636,15 @@ a cite{font-style: normal; *cursor:pointer;}
.layui-border-purple{border-width: 1px; border-style: solid; border-color: #a233c6!important; color: #a233c6!important;}
.layui-border-black{border-width: 1px; border-style: solid; border-color: #2f363c!important; color: #2f363c!important;}
+/* 分割线边框 */
+hr.layui-border-red,
+hr.layui-border-orange,
+hr.layui-border-green,
+hr.layui-border-cyan,
+hr.layui-border-blue,
+hr.layui-border-purple,
+hr.layui-border-black{border-width: 0 0 1px;}
+
/* 背景边框 */
.layui-timeline-item:before{background-color: #eee;}
@@ -642,9 +674,9 @@ a cite{font-style: normal; *cursor:pointer;}
.layui-text a:not(.layui-btn){color: #01AAED;}
.layui-text a:not(.layui-btn):hover{text-decoration: underline;}
.layui-text blockquote:not(.layui-elem-quote){padding: 5px 15px; border-left: 5px solid #eee;}
-.layui-text pre > code:not(.layui-code){padding: 15px; font-family: Courier New,Lucida Console,Consolas; background-color: #fafafa;}
+.layui-text pre > code:not(.layui-code){padding: 15px; font-family: "Courier New",Consolas,"Lucida Console";}
-/* 字体大小及颜色 */
+/* 字体大小 */
.layui-font-12{font-size: 12px !important;}
.layui-font-13{font-size: 13px !important;}
.layui-font-14{font-size: 14px !important;}
@@ -658,6 +690,7 @@ a cite{font-style: normal; *cursor:pointer;}
.layui-font-30{font-size: 30px !important;}
.layui-font-32{font-size: 32px !important;}
+/* 字体颜色 */
.layui-font-red{color: #ff5722 !important;} /*赤*/
.layui-font-orange{color: #ffb800!important;} /*橙*/
.layui-font-green{color: #16baaa!important;} /*绿*/
@@ -670,10 +703,8 @@ a cite{font-style: normal; *cursor:pointer;}
/*
-
- 按钮
-
-*/
+ * 按钮
+ */
.layui-btn{display: inline-block; vertical-align: middle; height: 38px; line-height: 38px; border: 1px solid transparent; padding: 0 18px; background-color: #16baaa; color: #fff; white-space: nowrap; text-align: center; font-size: 14px; border-radius: 2px; cursor: pointer; -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none;}
.layui-btn:hover{opacity: 0.8; filter:alpha(opacity=80); color: #fff;}
@@ -764,8 +795,8 @@ a cite{font-style: normal; *cursor:pointer;}
.layui-input-group{position: relative; display: table; box-sizing: border-box;}
.layui-input-group>*{display: table-cell; vertical-align: middle; position: relative;}
.layui-input-group .layui-input{padding-right: 15px;}
-.layui-input-group .layui-input-prefix{width: auto; border-right: 0;}
-.layui-input-group .layui-input-suffix{width: auto; border-left: 0;}
+.layui-input-group > .layui-input-prefix{width: auto; border-right: 0;}
+.layui-input-group > .layui-input-suffix{width: auto; border-left: 0;}
.layui-input-group .layui-input-split{white-space: nowrap;}
/* 输入框前后缀容器 */
@@ -783,7 +814,9 @@ a cite{font-style: normal; *cursor:pointer;}
.layui-input-wrap .layui-input-split{pointer-events: none;}
.layui-input-wrap .layui-input:hover + .layui-input-split{border-color: #d2d2d2;}
.layui-input-wrap .layui-input:focus + .layui-input-split{border-color: #16b777;}
+.layui-input-wrap .layui-input.layui-form-danger:focus + .layui-input-split{border-color: #ff5722;}
.layui-input-wrap .layui-input-prefix.layui-input-split{border-width: 0; border-right-width: 1px;}
+.layui-input-wrap .layui-input-suffix.layui-input-split{border-width: 0; border-left-width: 1px;}
/* 输入框动态点缀 */
.layui-input-affix{line-height: 38px;}
@@ -793,15 +826,16 @@ a cite{font-style: normal; *cursor:pointer;}
.layui-input-affix .layui-icon:hover{color: rgba(0,0,0,.6);}
/* 数字输入框动态点缀 */
-.layui-input-number{width: 24px; padding: 0;}
-.layui-input-number .layui-icon{position: absolute; right: 0; width: 100%; height: 50%; line-height: normal; font-size: 12px;}
-.layui-input-number .layui-icon:before{position: absolute; left: 50%; top: 50%; margin-top: -6px; margin-left: -6px;}
-.layui-input-number .layui-icon:first-child{top: 0; border-bottom: 1px solid #eee;}
-.layui-input-number .layui-icon:last-child{bottom: 0;}
-.layui-input-number .layui-icon:hover{font-weight: 700;}
+.layui-input-wrap .layui-input-number{width: 24px; padding: 0;}
+.layui-input-wrap .layui-input-number .layui-icon{position: absolute; right: 0; width: 100%; height: 50%; line-height: normal; font-size: 12px;}
+.layui-input-wrap .layui-input-number .layui-icon:before{position: absolute; left: 50%; top: 50%; margin-top: -6px; margin-left: -6px;}
+.layui-input-wrap .layui-input-number .layui-icon-up{top: 0; border-bottom: 1px solid #eee;}
+.layui-input-wrap .layui-input-number .layui-icon-down{bottom: 0;}
+.layui-input-wrap .layui-input-number .layui-icon:hover{font-weight: 700;}
.layui-input-wrap .layui-input[type="number"]::-webkit-outer-spin-button,
.layui-input-wrap .layui-input[type="number"]::-webkit-inner-spin-button{-webkit-appearance: none !important;}
.layui-input-wrap .layui-input[type="number"]{-moz-appearance: textfield;}
+.layui-input-wrap .layui-input[type="number"].layui-input-number-out-of-range{color:#ff5722;}
@@ -826,6 +860,8 @@ a cite{font-style: normal; *cursor:pointer;}
:root .layui-form-selected .layui-edge{margin-top: -9px\0/IE9;}
.layui-form-selectup dl{top: auto; bottom: 42px;}
.layui-select-none{margin: 5px 0; text-align: center; color: #999;}
+.layui-select-panel-wrap {position: absolute; z-index: 99999999;}
+.layui-select-panel-wrap dl{position: relative; display: block; top:0;}
.layui-select-disabled .layui-disabled{border-color: #eee !important;}
.layui-select-disabled .layui-edge{border-top-color: #d2d2d2}
@@ -839,11 +875,11 @@ a cite{font-style: normal; *cursor:pointer;}
.layui-form-checkbox:hover > div{background-color: #c2c2c2;}
.layui-form-checkbox > i{position: absolute; right: 0; top: 0; width: 30px; height: 100%; border: 1px solid #d2d2d2; border-left: none; border-radius: 0 2px 2px 0; color: #fff; color: rgba(255,255,255,0); font-size: 20px; text-align: center; box-sizing: border-box;}
.layui-form-checkbox:hover > i{border-color: #c2c2c2; color: #c2c2c2;}
-.layui-form-checked,
+.layui-form-checked,
.layui-form-checked:hover{border-color: #16b777;}
-.layui-form-checked > div,
+.layui-form-checked > div,
.layui-form-checked:hover > div{background-color: #16b777;}
-.layui-form-checked > i,
+.layui-form-checked > i,
.layui-form-checked:hover > i{color: #16b777;}
.layui-form-item .layui-form-checkbox{margin-top: 4px;}
.layui-form-checkbox.layui-checkbox-disabled > div{background-color: #eee !important;}
@@ -870,6 +906,18 @@ a cite{font-style: normal; *cursor:pointer;}
.layui-form-onswitch > i{left: 100%; margin-left: -21px; background-color: #fff;}
.layui-form-onswitch > div{margin-left: 0; margin-right: 21px; color: #fff!important;}
+/* 无样式风格-根据模板自定义样式*/
+.layui-form-checkbox[lay-skin="none"] *,
+.layui-form-radio[lay-skin="none"] *{box-sizing: border-box;}
+.layui-form-checkbox[lay-skin="none"],
+.layui-form-radio[lay-skin="none"] {position: relative; min-height: 20px; margin: 0; padding: 0; height: auto; line-height: normal;}
+.layui-form-checkbox[lay-skin="none"]>div,
+.layui-form-radio[lay-skin="none"]>div{position: relative; top: 0; left: 0; cursor: pointer; z-index: 10; color: inherit; background-color: inherit;}
+.layui-form-checkbox[lay-skin="none"]>i,
+.layui-form-radio[lay-skin="none"]>i{display: none;}
+.layui-form-checkbox[lay-skin="none"].layui-checkbox-disabled>div,
+.layui-form-radio[lay-skin="none"].layui-radio-disabled>div{cursor: not-allowed;}
+
.layui-checkbox-disabled{border-color: #eee !important;}
.layui-checkbox-disabled > div{color: #c2c2c2!important;}
.layui-checkbox-disabled > i{border-color: #eee !important;}
@@ -980,6 +1028,9 @@ a cite{font-style: normal; *cursor:pointer;}
.layui-table-checked{background-color: #dbfbf0;}
.layui-table-checked.layui-table-hover,
.layui-table-checked.layui-table-click{background-color: #abf8dd;}
+.layui-table-disabled-transition *,
+.layui-table-disabled-transition *:before,
+.layui-table-disabled-transition *:after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}
.layui-table th,
@@ -1035,8 +1086,10 @@ a cite{font-style: normal; *cursor:pointer;}
.layui-table-view .layui-form-checkbox[lay-skin="primary"] i{width: 18px; height: 18px; line-height: 16px;}
.layui-table-view .layui-form-radio{line-height: 0; padding: 0;}
.layui-table-view .layui-form-radio>i{margin: 0; font-size: 20px;}
-.layui-table-init{position: absolute; left: 0; top: 0; width: 100%; height: 100%; text-align: center; z-index: 199;}
-.layui-table-init .layui-icon{position: absolute; left: 50%; top: 50%; margin: -15px 0 0 -15px; font-size: 30px; color: #c2c2c2;}
+.layui-table-init{position: absolute; left: 0; top: 0; right: 0; bottom: 0; margin: 0; z-index: 199; transition: opacity .1s; user-select: none; opacity: 1;}
+.layui-table-init.layui-hide-v{opacity: 0;}
+.layui-table-loading-icon{position: absolute; width: 100%\0; left: 50%; left:auto\0; top: 50%; margin-top: -15px\0; transform: translate(-50%, -50%); transform: none\0; text-align: center;}
+.layui-table-loading-icon .layui-icon{font-size: 30px; color: #c2c2c2;}
.layui-table-header{border-width: 0; border-bottom-width: 1px; overflow: hidden;}
.layui-table-header .layui-table{margin-bottom: -1px;}
@@ -1071,6 +1124,7 @@ a cite{font-style: normal; *cursor:pointer;}
.layui-table-cell{height: 38px; line-height: 28px; padding: 6px 15px; position: relative; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; box-sizing: border-box;}
.layui-table-cell .layui-form-checkbox[lay-skin="primary"]{top: -1px; padding: 0;}
+.layui-table-cell .layui-form-checkbox[lay-skin="primary"] > div{padding-left: 24px;}
.layui-table-cell .layui-table-link{color: #01AAED;}
.layui-table-cell .layui-btn{vertical-align: inherit;}
.layui-table-cell[align="center"]{-webkit-box-pack: center;}
@@ -1130,16 +1184,28 @@ select.layui-table-edit{padding: 0 0 0 10px; border-color: #d2d2d2;}
/* 展开溢出的单元格 */
.layui-table-grid .layui-table-cell{overflow: visible;}
-.layui-table-grid-down{position: absolute; top: 0; right: 0; width: 26px; height: 100%; padding: 5px 0; border-width: 0; border-left-width: 1px; text-align: center; background-color: #fff; color: #999; cursor: pointer;}
-.layui-table-grid-down .layui-icon{position: absolute; top: 50%; left: 50%; margin: -8px 0 0 -8px;}
+.layui-table-grid-down{position: absolute; top: 0; right: 0; width: 24px; height: 100%; padding: 5px 0; border-width: 0; border-left-width: 1px; text-align: center; background-color: #fff; color: #999; cursor: pointer;}
+.layui-table-grid-down .layui-icon{position: absolute; top: 50%; left: 50%; margin: -8px 0 0 -8px; font-size: 14px;}
.layui-table-grid-down:hover{background-color: #fbfbfb;}
+/* 单元格多行展开风格 */
+.layui-table-expanded{height: 95px;}
+.layui-table-expanded .layui-table-cell,
+.layui-table-view .layui-table[lay-size="sm"] .layui-table-expanded .layui-table-cell,
+.layui-table-view .layui-table[lay-size="lg"] .layui-table-expanded .layui-table-cell{height: auto; max-height: 94px; white-space: normal; text-overflow: clip;}
+.layui-table-cell-c{position: absolute; bottom: -10px; right: 50%; margin-right: -9px; width: 20px; height: 20px; line-height: 18px; cursor: pointer; text-align: center; background-color: #fff; border: 1px solid #eee; border-radius: 50%; z-index: 1000; transition: 0.3s all; font-size: 14px;}
+.layui-table-cell-c:hover{border-color: #16b777;}
+.layui-table-expanded td:hover .layui-table-cell{overflow: auto;}
+.layui-table-main > .layui-table > tbody > tr:last-child > td > .layui-table-cell-c{bottom: 0;}
+
+/* 单元格 TIPS 展开风格 */
body .layui-table-tips .layui-layer-content{background: none; padding: 0; box-shadow: 0 1px 6px rgba(0,0,0,.12);}
.layui-table-tips-main{margin: -49px 0 0 -1px; max-height: 150px; padding: 8px 15px; font-size: 14px; overflow-y: scroll; background-color: #fff; color: #5F5F5F;}
.layui-table-tips-c{position: absolute; right: -3px; top: -13px; width: 20px; height: 20px; padding: 3px; cursor: pointer; background-color: #5F5F5F; border-radius: 50%; color: #fff;}
.layui-table-tips-c:hover{background-color: #777;}
.layui-table-tips-c:before{position: relative; right: -2px;}
+
/** 树表 **/
.layui-table-tree-nodeIcon {max-width: 20px;}
.layui-table-tree-nodeIcon > * {width: 100%;}
@@ -1166,7 +1232,7 @@ body .layui-table-tips .layui-layer-content{background: none; padding: 0; box-sh
.layui-menu li,
.layui-menu-body-title,
.layui-menu-body-title a{padding: 5px 15px; color: initial}
-.layui-menu li{position: relative; margin: 1px 0; line-height: 26px; color: rgba(0,0,0,.8); font-size: 14px; white-space: nowrap; cursor: pointer; transition: all .3s;}
+.layui-menu li{position: relative; margin: 0 0 1px; line-height: 26px; color: rgba(0,0,0,.8); font-size: 14px; white-space: nowrap; cursor: pointer; transition: all .3s;}
.layui-menu li:hover{background-color: #f8f8f8; }
.layui-menu li.layui-disabled,
.layui-menu li.layui-disabled *{background: none !important; color: #d2d2d2 !important; cursor: not-allowed !important;}
@@ -1189,6 +1255,8 @@ body .layui-table-tips .layui-layer-content{background: none; padding: 0; box-sh
.layui-menu .layui-menu-item-down:hover{cursor: pointer;}
.layui-menu .layui-menu-item-up>.layui-menu-body-title{ color: rgba(0,0,0,.8);}
.layui-menu .layui-menu-item-up>ul{visibility: hidden; height: 0; overflow: hidden;}
+.layui-menu .layui-menu-item-down>.layui-menu-body-title>.layui-icon-down{transform: rotate(180deg);}
+.layui-menu .layui-menu-item-up>.layui-menu-body-title>.layui-icon-up{transform: rotate(-180deg);}
.layui-menu .layui-menu-item-up>.layui-menu-body-title:hover>.layui-icon,
.layui-menu .layui-menu-item-down:hover>.layui-menu-body-title>.layui-icon{color: rgba(0,0,0,1);}
.layui-menu .layui-menu-item-down>ul{visibility: visible; height: auto;}
@@ -1202,7 +1270,7 @@ body .layui-table-tips .layui-layer-content{background: none; padding: 0; box-sh
.layui-menu-body-title{position: relative; margin: -5px -15px; overflow: hidden; text-overflow: ellipsis;}
.layui-menu-body-title a{display: block; margin: -5px -15px; color: rgba(0,0,0,.8);}
.layui-menu-body-title a:hover{transition: all .3s;}
-.layui-menu-body-title>.layui-icon{position: absolute; right: 15px; top: 50%; margin-top: -6px; line-height: normal; font-size: 14px;}
+.layui-menu-body-title>.layui-icon{position: absolute; right: 15px; top: 50%; margin-top: -6px; line-height: normal; font-size: 14px; transition: all .2s; -webkit-transition: all .2s;}
.layui-menu-body-title>.layui-icon:hover{transition: all .3s;}
.layui-menu-body-title>.layui-icon-right{right: 14px;}
.layui-menu-body-panel{display: none; position: absolute; top: -7px; left: 100%; z-index: 1000; margin-left: 13px; padding: 5px 0;}
@@ -1271,26 +1339,24 @@ body .layui-table-tips .layui-layer-content{background: none; padding: 0; box-sh
.layui-nav-itemed>a{color: #fff !important;}
.layui-nav-tree .layui-nav-bar{background-color: #16baaa;}
-.layui-nav-tree .layui-nav-child{position: relative; z-index: 0; top: 0; border: none; box-shadow: none;}
+.layui-nav-tree .layui-nav-child{position: relative; z-index: 0; top: 0; border: none; background: none; background-color: rgba(0,0,0,.3); box-shadow: none;}
.layui-nav-tree .layui-nav-child dd{margin: 0;}
.layui-nav-tree .layui-nav-child a{color: #fff; color: rgba(255,255,255,.7);}
-.layui-nav-tree .layui-nav-child a:hover,
-.layui-nav-tree .layui-nav-child{background: none; color: #fff;}
+.layui-nav-tree .layui-nav-child a:hover{background: none; color: #fff;}
-.layui-nav-itemed>.layui-nav-child{display: block; background-color: rgba(0,0,0,.3) !important;}
+/* 垂直导航 - 展开状态 */
+.layui-nav-itemed>.layui-nav-child,
.layui-nav-itemed>.layui-nav-child>.layui-this>.layui-nav-child{display: block;}
-/* 侧边 */.layui-nav-side{position: fixed; top: 0; bottom: 0; left: 0; overflow-x: hidden; z-index: 999;}
+/* 垂直导航 - 侧边 */
+.layui-nav-side{position: fixed; top: 0; bottom: 0; left: 0; overflow-x: hidden; z-index: 999;}
/* 导航浅色背景 */
.layui-nav.layui-bg-gray .layui-nav-item a,
-.layui-nav-tree.layui-bg-gray a{color: rgba(0,0,0,.8);}
-.layui-nav-tree.layui-bg-gray{padding: 6px 0;}
+.layui-nav-tree.layui-bg-gray a{color: #373737; color: rgba(0,0,0,.8);}
.layui-nav-tree.layui-bg-gray .layui-nav-itemed>a{color: #000 !important;}
.layui-nav.layui-bg-gray .layui-this a{color: #16b777;}
-.layui-nav-tree.layui-bg-gray .layui-nav-itemed>.layui-nav-child{padding-left: 11px; background: none!important;}
-.layui-nav-tree.layui-bg-gray .layui-nav-item>a{padding-top: 0; padding-bottom: 0;}
-.layui-nav-tree.layui-bg-gray .layui-nav-item>a .layui-nav-more{padding: 0;}
+.layui-nav-tree.layui-bg-gray .layui-nav-child{padding-left: 11px; background: none;}
.layui-nav-tree.layui-bg-gray .layui-this,
.layui-nav-tree.layui-bg-gray .layui-this>a,
.layui-nav-tree.layui-bg-gray .layui-nav-child dd.layui-this,
@@ -1315,7 +1381,7 @@ body .layui-table-tips .layui-layer-content{background: none; padding: 0; box-sh
.layui-tab .layui-tab-title li a{display: block; padding: 0 15px; margin: 0 -15px;}
.layui-tab-title .layui-this{color: #000;}
-.layui-tab-title .layui-this:after{position: absolute; left:0; top: 0; content: ""; width:100%; height: 41px; border-width: 1px; border-style: solid; border-bottom-color: #fff; border-radius: 2px 2px 0 0; box-sizing: border-box; pointer-events: none;}
+.layui-tab-title .layui-this:after{position: absolute; left:0; top: 0; content: ""; width:100%; height: 41px; border-width: 1px; border-bottom-width: 2px; border-style: solid; border-bottom-color: #fff; border-radius: 2px 2px 0 0; box-sizing: border-box; pointer-events: none;}
.layui-tab-bar{position: absolute; right: 0; top: 0; z-index: 10; width: 30px; height: 39px; line-height: 39px; border-width: 1px; border-style: solid; border-radius: 2px; text-align: center; background-color: #fff; cursor: pointer;}
.layui-tab-bar .layui-icon{position: relative; display: inline-block; top: 3px; transition: all .3s; -webkit-transition: all .3s;}
.layui-tab-item{display: none;}
@@ -1445,7 +1511,7 @@ body .layui-util-face .layui-layer-content{padding:0; background-color:#fff; co
.layui-util-face ul li:hover{position: relative; z-index: 2; border: 1px solid #eb7350; background: #fff9ec;}
/** 代码文本修饰 **/
-.layui-code{position: relative; margin: 10px 0; padding: 15px; line-height: 20px; border: 1px solid #eee; border-left-width: 6px; background-color: #fafafa; color: #333; font-family: Courier New,Lucida Console,Consolas; font-size: 12px;}
+.layui-code{display: block; position: relative; padding: 15px; line-height: 20px; border: 1px solid #eee; border-left-width: 6px; background-color: #fff; color: #333; font-family: "Courier New",Consolas,"Lucida Console"; font-size: 12px;}
/** 穿梭框 **/
.layui-transfer-box,
@@ -1474,7 +1540,8 @@ body .layui-util-face .layui-layer-content{padding:0; background-color:#fff; co
.layui-rate li{margin-top: 0 !important;}
.layui-rate li i.layui-icon{ font-size: 20px; color: #ffb800;}
.layui-rate li i.layui-icon{margin-right: 5px; transition: all .3s; -webkit-transition: all .3s;}
-.layui-rate li i:hover{cursor: pointer; transform: scale(1.12); -webkit-transform: scale(1.12);}
+.layui-rate li i:hover,
+.layui-rate-hover{cursor: pointer; transform: scale(1.12); -webkit-transform: scale(1.12);}
.layui-rate[readonly] li i:hover{cursor: default; transform: scale(1);}
/** 颜色选择器 **/
@@ -1491,10 +1558,10 @@ body .layui-util-face .layui-layer-content{padding:0; background-color:#fff; co
.layui-colorpicker-main{position: absolute; left: -999999px; top: -999999px; z-index: 77777777; width: 280px; margin: 5px 0; padding: 7px; background: #FFF; border: 1px solid #d2d2d2; border-radius: 2px; box-shadow: 0 2px 4px rgba(0,0,0,.12);}
.layui-colorpicker-main-wrapper{height: 180px; position: relative;}
-.layui-colorpicker-basis{width: 260px; height: 100%; position: relative;}
+.layui-colorpicker-basis{width: 260px; height: 100%; position: relative; overflow: hidden;}
.layui-colorpicker-basis-white{width: 100%; height: 100%; position: absolute; top: 0; left: 0; background: linear-gradient(90deg, #FFF, hsla(0,0%,100%,0));}
.layui-colorpicker-basis-black{width: 100%; height: 100%; position: absolute; top: 0; left: 0; background: linear-gradient(0deg, #000, transparent);}
-.layui-colorpicker-basis-cursor{width: 10px; height: 10px; border: 1px solid #FFF; border-radius: 50%; position: absolute; top: -3px; right: -3px; cursor: pointer;}
+.layui-colorpicker-basis-cursor{width: 10px; height: 10px; border: 1px solid #FFF; border-radius: 50%; position: absolute; top: 0%; right: 100%; cursor: pointer; transform: translate(-50%,-50%);}
.layui-colorpicker-side{position: absolute; top: 0; right: 0; width: 12px; height: 100%; background: linear-gradient(#F00, #FF0, #0F0, #0FF, #00F, #F0F, #F00);}
.layui-colorpicker-side-slider{width: 100%; height: 5px; box-shadow: 0 0 1px #888888; box-sizing: border-box; background: #FFF; border-radius: 1px; border: 1px solid #f0f0f0; cursor: pointer; position: absolute; left: 0;}
.layui-colorpicker-main-alpha{display: none; height: 12px; margin-top: 7px; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}
@@ -1508,8 +1575,8 @@ body .layui-util-face .layui-layer-content{padding:0; background-color:#fff; co
.layui-colorpicker-pre > div{height: 100%; border-radius: 2px;}
.layui-colorpicker-main-input{text-align: right; padding-top: 7px;}
.layui-colorpicker-main-input .layui-btn-container .layui-btn{margin: 0 0 0 10px;}
-.layui-colorpicker-main-input div.layui-inline{float: left; margin-right: 10px; font-size: 14px;}
-.layui-colorpicker-main-input input.layui-input{width: 150px; height: 30px; color: #5F5F5F;}
+.layui-colorpicker-main-input div.layui-inline{float: left; font-size: 14px;}
+.layui-colorpicker-main-input input.layui-input{width: 168px; height: 30px; color: #5F5F5F; padding-left: 5px;}
/** 滑块 **/
.layui-slider{height: 4px; background: #eee; border-radius: 3px; position: relative; cursor: pointer;}
@@ -1521,7 +1588,7 @@ body .layui-util-face .layui-layer-content{padding:0; background-color:#fff; co
.layui-slider-wrap-btn:hover,
.layui-slider-wrap-btn.layui-slider-hover{transform: scale(1.2);}
.layui-slider-wrap-btn.layui-disabled:hover{transform: scale(1) !important;}
-.layui-slider-tips{position: absolute; top: -42px; z-index: 77777777; white-space:nowrap; display: none; -webkit-transform: translateX(-50%); transform: translateX(-50%); color: #FFF; background: #000; border-radius: 3px; height: 25px; line-height: 25px; padding: 0 10px;}
+.layui-slider-tips{position: absolute; top: -42px; z-index: 77777777; white-space:nowrap; -webkit-transform: translateX(-50%); transform: translateX(-50%); color: #FFF; background: #000; border-radius: 3px; height: 25px; line-height: 25px; padding: 0 10px;}
.layui-slider-tips:after{content: ""; position: absolute; bottom: -12px; left: 50%; margin-left: -6px; width: 0; height: 0; border-width: 6px; border-style: solid; border-color: #000 transparent transparent transparent;}
.layui-slider-input{width: 70px; height: 32px; border: 1px solid #eee; border-radius: 3px; font-size: 16px; line-height: 32px; position: absolute; right: 0; top: -14px; box-sizing: border-box;}
.layui-slider-input-btn{position: absolute; top: 0; right: 0; width: 20px; height: 100%; border-left: 1px solid #eee;}
@@ -1550,7 +1617,7 @@ body .layui-util-face .layui-layer-content{padding:0; background-color:#fff; co
.layui-tree-pack{display: none; padding-left: 20px; position: relative;}
.layui-tree-line .layui-tree-pack{padding-left: 27px;}
.layui-tree-line .layui-tree-set .layui-tree-set:after{content: ""; position: absolute; top: 14px; left: -9px; width: 17px; height: 0; border-top: 1px dotted #c0c4cc;}
-.layui-tree-entry{position: relative; padding: 3px 0; height: 20px; white-space: nowrap;}
+.layui-tree-entry{position: relative; padding: 3px 0; height: 26px; white-space: nowrap;}
.layui-tree-entry:hover{background-color: #eee;}
.layui-tree-line .layui-tree-entry:hover{background-color: rgba(0,0,0,0);}
.layui-tree-line .layui-tree-entry:hover .layui-tree-txt{color: #999; text-decoration: underline; transition: 0.3s;}
@@ -1559,7 +1626,7 @@ body .layui-util-face .layui-layer-content{padding:0; background-color:#fff; co
.layui-tree-line .layui-tree-set.layui-tree-setLineShort:before{height: 13px;}
.layui-tree-line .layui-tree-set.layui-tree-setHide:before{height: 0;}
.layui-tree-iconClick{display: inline-block; vertical-align: middle; position: relative; height: 20px; line-height: 20px; margin: 0 10px; color: #c0c4cc;}
-.layui-tree-icon{height: 12px; line-height: 12px; width: 12px; text-align: center; border: 1px solid #c0c4cc;}
+.layui-tree-icon{height: 14px; line-height: 12px; width: 14px; text-align: center; border: 1px solid #c0c4cc;}
.layui-tree-iconClick .layui-icon{font-size: 18px;}
.layui-tree-icon .layui-icon{font-size: 12px; color: #5F5F5F;}
.layui-tree-iconArrow{padding: 0 5px;}
@@ -1571,7 +1638,7 @@ body .layui-util-face .layui-layer-content{padding:0; background-color:#fff; co
.layui-tree-btnGroup .layui-icon{display: inline-block; vertical-align: middle; padding: 0 2px; cursor: pointer;}
.layui-tree-btnGroup .layui-icon:hover{color: #999; transition: 0.3s;}
.layui-tree-entry:hover .layui-tree-btnGroup{visibility: visible;}
-.layui-tree-editInput{position: relative; display: inline-block; vertical-align: middle; height: 20px; line-height: 20px; padding: 0 3px; border: none; background-color: rgba(0,0,0,0.05);}
+.layui-tree-editInput{position: relative; display: inline-block; vertical-align: middle; height: 20px; line-height: 20px; padding: 0; border: none; background-color: rgba(0,0,0,0.05);}
.layui-tree-emptyText{text-align: center; color: #999;}
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/css/modules/code.css b/HT.Cloud.Web/wwwroot/lib/layui/css/modules/code.css
index 348a8e6..cbd36ce 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/css/modules/code.css
+++ b/HT.Cloud.Web/wwwroot/lib/layui/css/modules/code.css
@@ -2,59 +2,74 @@
* code
*/
-/* 加载就绪标志 */
-html #layuicss-skincodecss{display:none; position: absolute; width:1989px;}
+html #layuicss-skincodecss{display: none; position: absolute; width: 1989px;}
-/* 默认风格 */
-.layui-code-view{display: block; position: relative; margin: 11px 0; padding: 0; border: 1px solid #eee; border-left-width: 6px; background-color: #FAFAFA; color: #333; font-family: Courier New; font-size: 13px;}
-.layui-code-title{position: relative; padding: 0 10px; height: 40px; line-height: 40px; border-bottom: 1px solid #eee; font-size: 12px;}
-.layui-code-title > .layui-code-about{position: absolute; right: 10px; top: 0; color: #B7B7B7;}
-.layui-code-about > a{padding-left: 10px;}
-.layui-code-view > .layui-code-ol,
-.layui-code-view > .layui-code-ul{max-height: 100%; padding: 0 !important; position: relative; overflow: auto;}
-.layui-code-view > .layui-code-ol > li{position: relative; margin-top: 0 !important; margin-left: 45px !important; line-height: 20px; padding: 0 10px !important; border-left: 1px solid #e2e2e2; list-style-type: decimal-leading-zero; *list-style-type: decimal; background-color: #fff;}
-.layui-code-view > .layui-code-ol > li:first-child,
-.layui-code-view > .layui-code-ul > li:first-child{padding-top: 10px !important;}
-.layui-code-view > .layui-code-ol > li:last-child,
-.layui-code-view > .layui-code-ul > li:last-child{padding-bottom: 10px !important;}
-.layui-code-view > .layui-code-ul > li{position: relative; line-height: 20px; padding: 0 10px !important; list-style-type: none; *list-style-type: none; background-color: #fff;}
-.layui-code-view pre{margin: 0;}
+/* 字体 */
+.layui-code-wrap{font-size: 13px; font-family: "Courier New",Consolas,"Lucida Console";}
+
+/* 基础结构 */
+.layui-code-view{display: block; position: relative; padding: 0 !important; border: 1px solid #eee; border-left-width: 6px; background-color: #fff; color: #333;}
+.layui-code-view pre{margin: 0 !important;}
+
+.layui-code-header{position: relative; z-index: 3; padding: 0 11px; height: 40px; line-height: 40px; border-bottom: 1px solid #eee; background-color: #fafafa; font-size: 12px;}
+.layui-code-header > .layui-code-header-about{position: absolute; right: 11px; top: 0; color: #B7B7B7;}
+.layui-code-header-about > a{padding-left: 10px;}
+
+.layui-code-wrap{position: relative; display: block; z-index: 1; margin: 0 !important; padding: 11px 0 !important; overflow-x: hidden; overflow-y: auto;}
+.layui-code-line{position: relative; line-height: 19px; margin: 0 !important;}
+.layui-code-line-number{position: absolute; left: 0; top: 0; padding: 0 8px; min-width: 45px; height: 100%; text-align: right; user-select: none; white-space: nowrap; overflow: hidden;}
+.layui-code-line-content{padding: 0 11px; word-wrap: break-word; white-space: pre-wrap;}
+
+.layui-code-ln-mode > .layui-code-wrap > .layui-code-line{padding-left: 45px;}
+.layui-code-ln-side{position: absolute; left: 0; top: 0; bottom: 0; z-index: 0; width: 45px; border-right: 1px solid #eee; border-color: rgb(126 122 122 / 15%); background-color: #fafafa; pointer-events: none;}
+
+/* 不自动换行 */
+.layui-code-nowrap > .layui-code-wrap{overflow: auto;}
+.layui-code-nowrap > .layui-code-wrap > .layui-code-line > .layui-code-line-content{white-space: pre; word-wrap: normal;}
+.layui-code-nowrap > .layui-code-ln-side{border-right-width: 0 !important; background: none !important;}
+
+.layui-code-fixbar{position: absolute; top: 8px; right: 11px; padding-right: 45px; z-index: 5;}
+.layui-code-fixbar > span{position: absolute; right: 0; top: 0; padding: 0 8px; color: #777; transition: all .3s;}
+.layui-code-fixbar > span:hover{color: #16b777;}
+.layui-code-copy{display: none; cursor: pointer;}
+.layui-code-preview > .layui-code-view > .layui-code-fixbar .layui-code-copy{display: none !important;}
+.layui-code-view:hover > .layui-code-fixbar .layui-code-copy{display: block;}
+.layui-code-view:hover > .layui-code-fixbar .layui-code-lang-marker{display: none;}
+
+/* 深色主题 */
+.layui-code-theme-dark,
+.layui-code-theme-dark > .layui-code-header{border-color: rgb(126 122 122 / 15%); background-color: #1f1f1f;}
+.layui-code-theme-dark{border-width: 1px; color: #ccc;}
+.layui-code-theme-dark > .layui-code-ln-side{border-right-color: #2a2a2a; background: none; color: #6e7681;}
-/* 深色风格 */
-.layui-code-dark{border: 1px solid #0C0C0C; border-left-color: #3F3F3F; background-color: #0C0C0C; color: #C2BE9E}
-.layui-code-dark > .layui-code-title{border-bottom: none;}
-.layui-code-dark > .layui-code-ol > li,
-.layui-code-dark > .layui-code-ul > li{background-color: #3F3F3F; border-left: none;}
-.layui-code-dark > .layui-code-ul > li{margin-left: 6px;}
/* 代码预览 */
.layui-code textarea{display: none;}
-.layui-code-preview > .layui-code{margin: 0;}
+.layui-code-preview > .layui-code,
+.layui-code-preview > .layui-code-view{margin: 0;}
.layui-code-preview > .layui-tab{position: relative; z-index: 1; margin-bottom: 0;}
-.layui-code-preview > .layui-tab > .layui-tab-title{border-bottom: none;}
-.layui-code-preview > .layui-code > .layui-code-title{display: none;}
+.layui-code-preview > .layui-tab > .layui-tab-title{border-width: 0;}
.layui-code-preview .layui-code-item{display: none;}
-.layui-code-preview .layui-code-view > .layui-code-ol > li{}
+.layui-code-preview .layui-code-view > .layui-code-lines > .layui-code-line{}
.layui-code-item-preview{position: relative; padding: 16px;}
.layui-code-item-preview > iframe{position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none;}
/* 工具栏 */
-.layui-code-tools{position: absolute; right: 11px; top: 3px;}
+.layui-code-tools{position: absolute; right: 11px; top: 8px; line-height: normal;}
.layui-code-tools > i{display: inline-block; margin-left: 6px; padding: 3px; cursor: pointer;}
.layui-code-tools > i.layui-icon-file-b{color: #999;}
.layui-code-tools > i:hover{color: #16b777;}
-/* 复制 */
-.layui-code-copy{position: absolute; right: 6px; top: 6px; cursor: pointer; display: none;}
-.layui-code-copy .layui-icon{color: #777; transition: all .3s;}
-.layui-code-copy:hover .layui-icon{color: #16b777;}
-.layui-code-view:hover > .layui-code-copy{display: block;}
-.layui-code-copy-offset{margin-right: 17px;}
-.layui-code-preview > .layui-code-view > .layui-code-copy{display: none !important;}
-
/* 全屏风格 */
.layui-code-full{position: fixed; left: 0; top: 0; z-index: 1111111; width: 100%; height: 100%; background-color: #fff;}
.layui-code-full .layui-code-item{width: 100% !important; border-width: 0 !important; border-top-width: 1px !important;}
.layui-code-full .layui-code-item,
-.layui-code-full .layui-code-ol,
-.layui-code-full .layui-code-ul{height: calc(100vh - 51px) !important; box-sizing: border-box;}
\ No newline at end of file
+.layui-code-full .layui-code-view,
+.layui-code-full .layui-code-wrap{height: calc(100vh - 51px) !important; box-sizing: border-box;}
+.layui-code-full .layui-code-item-preview{overflow: auto;}
+
+/* 代码高亮重置 */
+.layui-code-view.layui-code-hl{line-height: 20px !important; border-left-width: 1px;}
+.layui-code-view.layui-code-hl > .layui-code-ln-side{background-color: transparent;}
+.layui-code-theme-dark.layui-code-hl,
+.layui-code-theme-dark.layui-code-hl > .layui-code-ln-side{border-color: rgb(126 122 122 / 15%);}
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/css/modules/laydate.css b/HT.Cloud.Web/wwwroot/lib/layui/css/modules/laydate.css
index 18d163b..155fc5a 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/css/modules/laydate.css
+++ b/HT.Cloud.Web/wwwroot/lib/layui/css/modules/laydate.css
@@ -61,7 +61,7 @@ html #layuicss-laydate{display: none; position: absolute; width: 1989px;}
.laydate-day-mark::after{position: absolute; content:''; right: 2px; top: 2px; width: 5px; height: 5px; border-radius: 50%;}
.laydate-day-holidays:before{position: absolute; left: 0; top: 0; font-size: 12px; transform: scale(.7);}
.laydate-day-holidays:before{content:'\4F11'; color: #FF5722;}
-.laydate-day-holidays[type="work"]:before{content:'\73ED'; color: inherit;}
+.laydate-day-holidays[type="workdays"]:before{content:'\73ED'; color: inherit;}
.layui-laydate .layui-this .laydate-day-holidays:before{color: #fff;}
/* 底部结构 */
@@ -85,12 +85,14 @@ html #layuicss-laydate{display: none; position: absolute; width: 1989px;}
.layui-laydate .layui-laydate-list{position: absolute; left: 0; top: 0; width: 100%; height: 100%; padding: 10px; box-sizing: border-box; background-color: #fff;}
.layui-laydate .layui-laydate-list>li{position: relative; display: inline-block; width: 33.3%; height: 36px; line-height: 36px; margin: 3px 0; vertical-align: middle; text-align: center; cursor: pointer; list-style: none;}
.layui-laydate .laydate-month-list>li{width: 25%; margin: 17px 0;}
-.laydate-time-list{}
-.layui-laydate .laydate-time-list>li{height: 100%; margin: 0; line-height: normal; cursor: default;}
+.laydate-time-list{display: table;}
+.layui-laydate .laydate-time-list>li{display: table-cell; height: 100%; margin: 0; line-height: normal; cursor: default;}
.layui-laydate .laydate-time-list p{position: relative; top: -4px; margin: 0; line-height: 29px;}
.layui-laydate .laydate-time-list ol{height: 181px; overflow: hidden;}
.layui-laydate .laydate-time-list>li:hover ol{overflow-y: auto;}
.layui-laydate .laydate-time-list ol li{width: 130%; padding-left: 33px; height: 30px; line-height: 30px; text-align: left; cursor: pointer;}
+.layui-laydate .laydate-time-list-hide-1 ol li{padding-left: 53px;}
+.layui-laydate .laydate-time-list-hide-2 ol li{padding-left: 117px;}
/* 提示 */
.layui-laydate-hint{position: absolute; top: 115px; left: 50%; width: 250px; margin-left: -125px; line-height: 20px; padding: 15px; text-align: center; font-size: 12px; color: #FF5722;}
@@ -103,6 +105,8 @@ html #layuicss-laydate{display: none; position: absolute; width: 1989px;}
.layui-laydate-range .laydate-main-list-1 .layui-laydate-content{border-left: 1px solid #e2e2e2;}
.layui-laydate-range.layui-laydate-linkage .laydate-main-list-0 .laydate-next-m, .layui-laydate-range.layui-laydate-linkage .laydate-main-list-0 .laydate-next-y,
.layui-laydate-range.layui-laydate-linkage .laydate-main-list-1 .laydate-prev-m, .layui-laydate-range.layui-laydate-linkage .laydate-main-list-1 .laydate-prev-y{display: none;}
+.layui-laydate-range.layui-laydate-linkage .laydate-main-list-1 .layui-laydate-header,
+.layui-laydate-range.layui-laydate-linkage .laydate-main-list-1 .layui-laydate-content{border-left-style: dashed;}
/* 默认简约主题 */
@@ -115,29 +119,30 @@ html #layuicss-laydate{display: none; position: absolute; width: 1989px;}
.layui-laydate-content td{color: #777;}
.layui-laydate-content td.laydate-day-now{color: #16b777;}
.layui-laydate-content td.laydate-day-now:after{content: ''; position: absolute; width: 100%; height: 30px; left: 0; top: 0; border: 1px solid #16b777; box-sizing: border-box;}
-.layui-laydate-linkage .layui-laydate-content td.laydate-selected>div{background-color: #00F7DE;}
-.layui-laydate-linkage .laydate-selected:hover>div{background-color: #00F7DE !important;}
+.layui-laydate-linkage .layui-laydate-content td.laydate-selected>div{background-color: #cffae9; transition: all .3s;}
+.layui-laydate-linkage .laydate-selected:hover>div{background-color: #cffae9 !important;}
.layui-laydate-content td:hover:after,
.layui-laydate-content td.laydate-selected:after{content: none;}
.layui-laydate-content td>div:hover,
.layui-laydate-list li:hover,
-.layui-laydate-shortcut>li:hover{background-color: #eee; color: #333;}
+.layui-laydate-shortcut>li:hover{background-color: #eee; color: #333; transition: all .3s;}
.laydate-time-list li ol{margin: 0; padding: 0; border: 1px solid #e2e2e2; border-left-width: 0;}
.laydate-time-list li:first-child ol{border-left-width: 1px;}
.laydate-time-list>li:hover{background: none;}
.layui-laydate-content .laydate-day-prev,
.layui-laydate-content .laydate-day-next{color: #d2d2d2;}
.layui-laydate-linkage .laydate-selected.laydate-day-prev>div,
-.layui-laydate-linkage .laydate-selected.laydate-day-next>div{background-color: #f8f8f8 !important;}
+.layui-laydate-linkage .laydate-selected.laydate-day-next>div{background: none !important;}
.layui-laydate-footer{border-top: 1px solid #e2e2e2;}
.layui-laydate-hint{color: #FF5722;}
.laydate-day-mark::after{background-color: #16b777;}
.layui-laydate-content td.layui-this .laydate-day-mark::after{display: none;}
.layui-laydate-footer span[lay-type="date"]{color: #16b777;}
-.layui-laydate .layui-this,.layui-laydate .layui-this>div{background-color: #16baaa !important; color: #fff !important;}
+.layui-laydate .layui-this,.layui-laydate .layui-this>div{background-color: #16b777 !important; color: #fff !important;}
.layui-laydate .laydate-disabled,
.layui-laydate .laydate-disabled:hover{background:none !important; color: #d2d2d2 !important; cursor: not-allowed !important; -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none;}
-.layui-laydate-content td>div{padding: 7px 0;height: 100%;}
+.layui-laydate .layui-this.laydate-disabled,.layui-laydate .layui-this.laydate-disabled>div{background-color: #eee !important}
+.layui-laydate-content td>div{padding: 7px 0; height: 100%;}
/* 墨绿/自定义背景色主题 */
.laydate-theme-molv{border: none;}
@@ -150,6 +155,7 @@ html #layuicss-laydate{display: none; position: absolute; width: 1989px;}
.laydate-theme-molv .layui-laydate-header span:hover{color: #fff;}
.laydate-theme-molv .layui-laydate-content{border: 1px solid #e2e2e2; border-top: none; border-bottom: none;}
.laydate-theme-molv .laydate-main-list-1 .layui-laydate-content{border-left: none;}
+.laydate-theme-molv .layui-this, .laydate-theme-molv .layui-this>div{background-color: #16baaa !important;}
.laydate-theme-molv .layui-laydate-footer{border: 1px solid #e2e2e2;}
/* 格子主题 */
@@ -183,3 +189,5 @@ html #layuicss-laydate{display: none; position: absolute; width: 1989px;}
.laydate-theme-fullpanel .laydate-time-show .laydate-set-ym span[lay-type="year"],
.laydate-theme-fullpanel .laydate-time-show .laydate-set-ym span[lay-type="month"] {display: inline-block !important;}
.laydate-theme-fullpanel .laydate-btns-time{display: none;}
+.laydate-theme-fullpanel .laydate-time-list-hide-1 ol li{padding-left: 49px;}
+.laydate-theme-fullpanel .laydate-time-list-hide-2 ol li{padding-left: 107px;}
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/css/modules/layer.css b/HT.Cloud.Web/wwwroot/lib/layui/css/modules/layer.css
index 5b45dd7..4ebfdfd 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/css/modules/layer.css
+++ b/HT.Cloud.Web/wwwroot/lib/layui/css/modules/layer.css
@@ -6,14 +6,14 @@ html #layuicss-layer{display: none; position: absolute; width: 1989px;}
/* common */
.layui-layer-shade, .layui-layer{position:fixed; _position:absolute; pointer-events: auto;}
-.layui-layer-shade{top:0; left:0; width:100%; height:100%; _height:expression(document.body.offsetHeight+"px");}
+.layui-layer-shade{opacity: 0; transition: opacity .35s cubic-bezier(0.34, 0.69, 0.1, 1); top:0; left:0; width:100%; height:100%; _height:expression(document.body.offsetHeight+"px");}
.layui-layer{-webkit-overflow-scrolling: touch;}
.layui-layer{top:150px; left: 0; margin:0; padding:0; background-color:#fff; -webkit-background-clip: content; border-radius: 2px; box-shadow: 1px 1px 50px rgba(0,0,0,.3);}
.layui-layer-close{position:absolute;}
.layui-layer-content{position:relative;}
.layui-layer-border{border: 1px solid #B2B2B2; border: 1px solid rgba(0,0,0,.1); box-shadow: 1px 1px 5px rgba(0,0,0,.2);}
.layui-layer-setwin span,
-.layui-layer-btn a{display:inline-block; *display:inline; *zoom:1; vertical-align:top;}
+.layui-layer-btn a{display: inline-block; vertical-align: middle; *display: inline; *zoom:1; }
.layui-layer-move{display: none; position: fixed; *position: absolute; left: 0px; top: 0px; width: 100%; height: 100%; cursor: move; opacity: 0; filter:alpha(opacity=0); background-color: #fff; z-index: 2147483647;}
.layui-layer-resize{position: absolute; width: 15px; height: 15px; right: 0; bottom: 0; cursor: se-resize;}
@@ -120,8 +120,8 @@ html #layuicss-layer{display: none; position: absolute; width: 1989px;}
/* 标题栏 */
.layui-layer-title{padding: 0 81px 0 16px; height: 50px; line-height: 50px; border-bottom:1px solid #F0F0F0; font-size: 14px; color:#333; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; border-radius: 2px 2px 0 0;}
.layui-layer-setwin{position:absolute; right: 15px; *right:0; top: 16px; font-size:0; line-height: initial;}
-.layui-layer-setwin span{position:relative; width: 16px; height: 16px; line-height: 18px; margin-left: 10px; text-align: center; font-size: 16px; cursor: pointer; color: #000; _overflow:hidden;}
-.layui-layer-setwin .layui-layer-min:before{content: ''; position: absolute; width: 12px; height: 1px; left: 50%; top: 50%; margin: -0.5px 0 0 -6px; background-color: #2E2D3C; cursor: pointer; _overflow:hidden;}
+.layui-layer-setwin span{position:relative; width: 16px; height: 16px; line-height: 18px; margin-left: 10px; text-align: center; font-size: 16px; cursor: pointer; color: #000; _overflow: hidden; box-sizing: border-box;}
+.layui-layer-setwin .layui-layer-min:before{content: ''; position: absolute; width: 12px; border-bottom: 1px solid #2E2D3C; left: 50%; top: 50%; margin: -0.5px 0 0 -6px; cursor: pointer; _overflow:hidden;}
.layui-layer-setwin .layui-layer-min:hover:before{background-color: #2D93CA}
.layui-layer-setwin .layui-layer-max:before,
.layui-layer-setwin .layui-layer-max:after{content: ''; position: absolute; left: 50%; top: 50%; z-index: 1; width: 9px; height: 9px; margin: -5px 0 0 -5px; border: 1px solid #2E2D3C;}
@@ -133,17 +133,19 @@ html #layuicss-layer{display: none; position: absolute; width: 1989px;}
.layui-layer-setwin .layui-layer-maxmin:after{z-index: 0; margin: -5px 0 0 -1px;}
.layui-layer-setwin .layui-layer-close{cursor: pointer;}
.layui-layer-setwin .layui-layer-close:hover{opacity:0.7;}
-.layui-layer-setwin .layui-layer-close2{position:absolute; right: -28px; top: -28px; color: #fff; background-color: #787878; padding: 3px; border: 3px solid; width: 18px; height: 18px; font-size: 18px; font-weight: bolder; border-radius: 50%; margin-left: 0; *right:-18px; _display:none;}
+.layui-layer-setwin .layui-layer-close2{position:absolute; right: -28px; top: -28px; color: #fff; background-color: #787878; padding: 3px; border: 3px solid; width: 28px; height: 28px; font-size: 16px; font-weight: bolder; border-radius: 50%; margin-left: 0; *right:-18px; _display:none;}
.layui-layer-setwin .layui-layer-close2:hover{opacity: unset; background-color: #3888f6;}
/* 按钮栏 */
.layui-layer-btn{text-align: right; padding: 0 15px 12px; pointer-events: auto; user-select: none; -webkit-user-select: none;}
-.layui-layer-btn a{height: 28px; line-height: 28px; margin: 5px 5px 0; padding: 0 15px; border: 1px solid #dedede; background-color:#fff; color: #333; border-radius: 2px; font-weight:400; cursor:pointer; text-decoration: none;}
+.layui-layer-btn a{height: 30px; line-height: 30px; margin: 5px 5px 0; padding: 0 16px; border: 1px solid #dedede; background-color: #fff; color: #333; border-radius: 2px; font-weight: 400; cursor: pointer; text-decoration: none; box-sizing: border-box;}
.layui-layer-btn a:hover{opacity: 0.9; text-decoration: none;}
.layui-layer-btn a:active{opacity: 0.8;}
-.layui-layer-btn .layui-layer-btn0{border-color: #1E9FFF; background-color: #1E9FFF; color:#fff;}
+.layui-layer-btn .layui-layer-btn0{border-color: transparent; background-color: #1E9FFF; color:#fff;}
.layui-layer-btn-l{text-align: left;}
.layui-layer-btn-c{text-align: center;}
+.layui-layer-btn-is-loading{opacity:0.5 !important; cursor:not-allowed !important; cursor:wait !important; overflow:hidden; white-space:nowrap; -webkit-user-select: none; -ms-user-select: none;user-select: none;}
+.layui-layer-btn-is-loading .layui-layer-btn-loading-icon{margin-right: 8px; font-size: 14px;}
/* 定制化 */
.layui-layer-dialog{min-width: 240px;}
@@ -204,14 +206,14 @@ html #layuicss-layer{display: none; position: absolute; width: 1989px;}
.layui-layer-win10{border: 1px solid #aaa; box-shadow: 1px 1px 6px rgba(0,0,0,.3); border-radius: none;}
.layui-layer-win10 .layui-layer-title{height: 32px; line-height: 32px; padding-left: 8px; border-bottom: none; font-size: 12px;}
.layui-layer-win10 .layui-layer-setwin{right: 0; top: 0;}
-.layui-layer-win10 .layui-layer-setwin span{margin-left: 0; padding: 8px;}
-.layui-layer-win10.layui-layer-page .layui-layer-setwin span{padding: 8px 11px;}
+.layui-layer-win10 .layui-layer-setwin span{margin-left: 0; width: 32px; height: 32px; padding: 8px;}
+.layui-layer-win10.layui-layer-page .layui-layer-setwin span{width: 38px;}
.layui-layer-win10 .layui-layer-setwin span:hover{background-color: #E5E5E5;}
.layui-layer-win10 .layui-layer-setwin span.layui-icon-close:hover{background-color: #E81123; color: #fff;}
.layui-layer-win10.layui-layer-dialog .layui-layer-content{padding: 8px 16px 32px; color: #0033BC;}
.layui-layer-win10.layui-layer-dialog .layui-layer-padding{padding-top: 18px; padding-left: 58px;}
.layui-layer-win10 .layui-layer-btn{padding: 5px 5px 10px; border-top:1px solid #DFDFDF; background-color: #F0F0F0;}
-.layui-layer-win10 .layui-layer-btn a{height: 18px; line-height: 18px; background-color: #E1E1E1; border-color: #ADADAD; color: #000; font-size: 12px; transition: all .3s;}
+.layui-layer-win10 .layui-layer-btn a{height: 20px; line-height: 18px; background-color: #E1E1E1; border-color: #ADADAD; color: #000; font-size: 12px; transition: all .3s;}
.layui-layer-win10 .layui-layer-btn a:hover{border-color: #2A8EDD; background-color: #E5F1FB;}
.layui-layer-win10 .layui-layer-btn .layui-layer-btn0{border-color: #0078D7;}
@@ -238,21 +240,27 @@ html #layuicss-layer{display: none; position: absolute; width: 1989px;}
.layui-layer-tabmain .layui-layer-tabli{display:none;}
.layui-layer-tabmain .layui-layer-tabli.layui-this{display: block;}
-/* photo模式 */
+/* photos */
.layui-layer-photos{background: none; box-shadow: none;}
-.layui-layer-photos .layui-layer-content{overflow:hidden; text-align: center;}
-.layui-layer-photos .layui-layer-phimg img{position: relative; width:100%; display: inline-block; *display:inline; *zoom:1; vertical-align:top;}
-.layui-layer-imgprev, .layui-layer-imgnext{position: fixed; top: 50%; width: 52px; height: 52px; line-height: 52px; margin-top: -26px; cursor: pointer; font-size: 52px; color: #717171;}
-.layui-layer-imgprev{left: 32px;}
-.layui-layer-imgnext{right: 32px;}
-.layui-layer-imgprev:hover,
-.layui-layer-imgnext:hover{color: #959595;}
-.layui-layer-imgbar{position: fixed; left:0; right: 0; bottom:0; width:100%; height: 40px; line-height: 40px; background-color:#000\9; filter:Alpha(opacity=60); background-color: rgba(2,0,0,.35); color: #fff; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; font-size:0;}
-.layui-layer-imgtit{/*position:absolute; left:20px;*/}
-.layui-layer-imgtit *{display:inline-block; *display:inline; *zoom:1; vertical-align:top; padding: 0 5px; font-size:12px; color: #fff;}
-.layui-layer-imgtit h3{max-width:65%; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; font-weight: 300;}
-.layui-layer-imgtit a:hover{color: #fff; text-decoration: underline;}
-.layui-layer-imgtit em{font-style: normal;}
+.layui-layer-photos .layui-layer-content{overflow: visible; text-align: center;}
+.layui-layer-photos .layer-layer-photos-main img{position: relative; width:100%; display: inline-block; *display:inline; *zoom:1; vertical-align:top;}
+.layui-layer-photos-prev,
+.layui-layer-photos-next{position: fixed; top: 50%; width: 52px; height: 52px; line-height: 52px; margin-top: -26px; cursor: pointer; font-size: 52px; color: #717171;}
+.layui-layer-photos-prev{left: 32px;}
+.layui-layer-photos-next{right: 32px;}
+.layui-layer-photos-prev:hover,
+.layui-layer-photos-next:hover{color: #959595;}
+
+.layui-layer-photos-toolbar{position: fixed; left: 0; right: 0; bottom: 0; width: 100%; height: 52px; line-height: 52px; background-color: #000\9; filter: Alpha(opacity=60); background-color: rgba(0,0,0,.32); color: #fff; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; font-size:0;}
+.layui-layer-photos-toolbar > *{display:inline-block; vertical-align: top; padding: 0 16px; font-size: 12px; color: #fff; *display:inline; *zoom: 1;}
+.layui-layer-photos-toolbar *{font-size: 12px;}
+.layui-layer-photos-header{top: 0; bottom: auto;}
+.layui-layer-photos-header > span{cursor: pointer;}
+.layui-layer-photos-header > span:hover{background-color: rgba(51,51,51,.32);}
+.layui-layer-photos-header .layui-icon{font-size: 18px;}
+.layui-layer-photos-footer > h3{max-width: 65%; text-overflow: ellipsis; overflow: hidden; white-space: nowrap;}
+.layui-layer-photos-footer a:hover{text-decoration: underline;}
+.layui-layer-photos-footer em{font-style: normal;}
/* 关闭动画 */
@-webkit-keyframes layer-bounceOut {
@@ -266,9 +274,3 @@ html #layuicss-layer{display: none; position: absolute; width: 1989px;}
0% {-webkit-transform: scale(1); -ms-transform: scale(1);transform: scale(1);}
}
.layer-anim-close{-webkit-animation-name: layer-bounceOut; animation-name: layer-bounceOut; -webkit-animation-fill-mode: both; animation-fill-mode: both; -webkit-animation-duration:.2s; animation-duration:.2s;}
-
-@media screen and (max-width: 1100px) {
- .layui-layer-iframe{overflow-y: auto; -webkit-overflow-scrolling: touch;}
-}
-
-
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/layui.js b/HT.Cloud.Web/wwwroot/lib/layui/layui.js
index 8b783a7..b8da36c 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/layui.js
+++ b/HT.Cloud.Web/wwwroot/lib/layui/layui.js
@@ -3,7 +3,7 @@
* Classic modular front-end UI library
* MIT Licensed
*/
-
+
;!function(win){
"use strict";
@@ -16,9 +16,9 @@
};
var Layui = function(){
- this.v = '2.8.11'; // Layui 版本号
+ this.v = '2.9.14'; // Layui 版本号
};
-
+
// 识别预先可能定义的指定全局对象
var GLOBAL = win.LAYUI_GLOBAL || {};
@@ -36,7 +36,7 @@
}
return src || js[last].src;
}();
-
+
return config.dir = GLOBAL.dir || jsPath.substring(0, jsPath.lastIndexOf('/') + 1);
}();
@@ -71,7 +71,7 @@
util: 'util', // 工具块
code: 'code', // 代码修饰器
jquery: 'jquery', // DOM 库(第三方)
-
+
all: 'all',
'layui.all': 'layui.all' // 聚合标识(功能性的,非真实模块)
};
@@ -96,12 +96,12 @@
});
return this;
};
-
+
type && (
factory = deps,
deps = []
);
-
+
that.use(deps, callback, null, 'define');
return that;
};
@@ -115,15 +115,15 @@
apps = function(){
if(typeof apps === 'string'){
return [apps];
- }
+ }
// 当第一个参数为 function 时,则自动加载所有内置模块,且执行的回调即为该 function 参数;
else if(typeof apps === 'function'){
callback = apps;
return ['all'];
- }
+ }
return apps;
}();
-
+
// 如果页面已经存在 jQuery 1.7+ 库且所定义的模块依赖 jQuery,则不加载内部 jquery 模块
if(win.jQuery && jQuery.fn.on){
that.each(apps, function(index, item){
@@ -133,7 +133,7 @@
});
layui.jquery = layui.$ = jQuery;
}
-
+
var item = apps[0];
var timeout = 0;
@@ -141,7 +141,7 @@
// 静态资源host
config.host = config.host || (dir.match(/\/\/([\s\S]+?)\//)||['//'+ location.host +'/'])[0];
-
+
// 加载完毕
function onScriptLoad(e, url){
var readyRegExp = navigator.platform === 'PLaySTATION 3' ? /^complete$/ : /^(complete|loaded)$/
@@ -156,7 +156,7 @@
}());
}
}
-
+
// 回调
function onCallback(){
exports.push(layui[item]);
@@ -172,12 +172,12 @@
callback.apply(layui, exports);
}() );
}
-
+
// 如果引入了聚合板,内置的模块则不必重复加载
if( apps.length === 0 || (layui['layui.all'] && modules[item]) ){
return onCallback(), that;
}
-
+
/*
* 获取加载的模块 URL
* 如果是内置模块,则按照 dir 参数拼接模块路径
@@ -185,12 +185,12 @@
* 如果路径值是 {/} 开头,则模块路径即为后面紧跟的字符。
* 否则,则按照 base 参数拼接模块路径
*/
-
- var url = ( modules[item] ? (dir + 'modules/')
+
+ var url = ( modules[item] ? (dir + 'modules/')
: (/^\{\/\}/.test(that.modules[item]) ? '' : (config.base || ''))
) + (that.modules[item] || item) + '.js';
url = url.replace(/^\{\/\}/, '');
-
+
// 如果扩展模块(即:非内置模块)对象已经存在,则不必再加载
if(!config.modules[item] && layui[item]){
config.modules[item] = url; // 并记录起该扩展模块的 url
@@ -199,18 +199,18 @@
// 首次加载模块
if(!config.modules[item]){
var node = doc.createElement('script');
-
+
node.async = true;
node.charset = 'utf-8';
node.src = url + function(){
- var version = config.version === true
+ var version = config.version === true
? (config.v || (new Date()).getTime())
: (config.version||'');
return version ? ('?v=' + version) : '';
}();
-
+
head.appendChild(node);
-
+
if(node.attachEvent && !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) && !isOpera){
node.attachEvent('onreadystatechange', function(e){
onScriptLoad(e, url);
@@ -220,19 +220,19 @@
onScriptLoad(e, url);
}, false);
}
-
+
config.modules[item] = url;
} else { // 缓存
(function poll() {
if(++timeout > config.timeout * 1000 / 4){
return error(item + ' is not a valid module', 'error');
}
- (typeof config.modules[item] === 'string' && config.status[item])
- ? onCallback()
+ (typeof config.modules[item] === 'string' && config.status[item])
+ ? onCallback()
: setTimeout(poll, 4);
}());
}
-
+
return that;
};
@@ -264,35 +264,35 @@
var that = this;
var head = doc.getElementsByTagName('head')[0];
var link = doc.createElement('link');
-
+
if(typeof fn === 'string') cssname = fn;
-
+
var app = (cssname || href).replace(/\.|\//g, '');
var id = 'layuicss-'+ app;
var STAUTS_NAME = 'creating';
var timeout = 0;
-
+
link.href = href + (config.debug ? '?v='+new Date().getTime() : '');
link.rel = 'stylesheet';
link.id = id;
link.media = 'all';
-
+
if(!doc.getElementById(id)){
head.appendChild(link);
}
-
+
if(typeof fn !== 'function') return that;
-
+
// 轮询 css 是否加载完毕
(function poll(status) {
var delay = 100;
var getLinkElem = doc.getElementById(id); // 获取动态插入的 link 元素
-
+
// 如果轮询超过指定秒数,则视为请求文件失败或 css 文件不符合规范
if(++timeout > config.timeout * 1000 / delay){
return error(href + ' timeout');
}
-
+
// css 加载就绪
if(parseInt(that.getStyle(getLinkElem, 'width')) === 1989){
// 如果参数来自于初始轮询(即未加载就绪时的),则移除 link 标签状态
@@ -306,7 +306,7 @@
}, delay);
}
}());
-
+
// 轮询css是否加载完毕
/*
(function poll() {
@@ -318,31 +318,31 @@
}() : setTimeout(poll, 100);
}());
*/
-
+
return that;
};
-
+
// css 内部加载器
Layui.prototype.addcss = function(firename, fn, cssname){
return layui.link(config.dir + 'css/' + firename, fn, cssname);
};
-
+
// 存储模块的回调
config.callback = {};
-
+
// 重新执行模块的工厂函数
Layui.prototype.factory = function(modName){
if(layui[modName]){
- return typeof config.callback[modName] === 'function'
+ return typeof config.callback[modName] === 'function'
? config.callback[modName]
: null;
}
};
// 图片预加载
- Layui.prototype.img = function(url, callback, error) {
+ Layui.prototype.img = function(url, callback, error) {
var img = new Image();
- img.src = url;
+ img.src = url;
if(img.complete){
return callback(img);
}
@@ -353,7 +353,7 @@
img.onerror = function(e){
img.onerror = null;
typeof error === 'function' && error(e);
- };
+ };
};
// 全局配置
@@ -400,13 +400,13 @@
search: {},
hash: (hash.match(/[^#](#.*$)/) || [])[1] || ''
};
-
+
if(!/^#\//.test(hash)) return data; // 禁止非路由规范
hash = hash.replace(/^#\//, '');
data.href = '/' + hash;
hash = hash.replace(/([^#])(#.*$)/, '$1').split('/') || [];
-
+
// 提取 Hash 结构
that.each(hash, function(index, item){
/^\w+=/.test(item) ? function(){
@@ -414,10 +414,10 @@
data.search[item[0]] = item[1];
}() : data.path.push(item);
});
-
+
return data;
};
-
+
// URL 解析
Layui.prototype.url = function(href){
var that = this;
@@ -432,18 +432,18 @@
: location.pathname;
return pathname.replace(/^\//, '').split('/');
}(),
-
+
// 提取 url 参数
search: function(){
var obj = {};
- var search = (href
+ var search = (href
? function(){
var str = (href.match(/\?.+/) || [])[0] || '';
return str.replace(/\#.+/, '');
}()
: location.search
).replace(/^\?+/, '').split('&'); // 去除 ?,按 & 分割参数
-
+
// 遍历分割后的参数
that.each(search, function(index, item){
var _index = item.indexOf('=')
@@ -455,24 +455,24 @@
} else {
return item.substr(0, _index);
}
- }();
+ }();
// 提取 value
if(key){
obj[key] = _index > 0 ? item.substr(_index + 1) : null;
}
});
-
+
return obj;
}(),
-
+
// 提取 Hash
hash: that.router(function(){
- return href
+ return href
? ((href.match(/#.+/) || [])[0] || '/')
: location.hash;
}())
};
-
+
return data;
};
@@ -480,31 +480,31 @@
Layui.prototype.data = function(table, settings, storage){
table = table || 'layui';
storage = storage || localStorage;
-
+
if(!win.JSON || !win.JSON.parse) return;
-
+
// 如果 settings 为 null,则删除表
if(settings === null){
return delete storage[table];
}
-
- settings = typeof settings === 'object'
- ? settings
+
+ settings = typeof settings === 'object'
+ ? settings
: {key: settings};
-
+
try {
var data = JSON.parse(storage[table]);
} catch(e) {
var data = {};
}
-
+
if('value' in settings) data[settings.key] = settings.value;
if(settings.remove) delete data[settings.key];
storage[table] = JSON.stringify(data);
-
+
return settings.key ? data[settings.key] : data;
};
-
+
// 本地临时存储
Layui.prototype.sessionData = function(table, settings){
return this.data(table, settings, sessionStorage);
@@ -520,7 +520,7 @@
label = (agent.match(exp)||[])[1];
return label || false;
};
-
+
// 返回结果集
var result = {
os: function(){ // 底层操作系统
@@ -532,7 +532,7 @@
return 'ios';
} else if(/mac/.test(agent)){
return 'mac';
- }
+ }
}(),
ie: function(){ // ie 版本
return (!!win.ActiveXObject || "ActiveXObject" in win) ? (
@@ -541,17 +541,17 @@
}(),
weixin: getVersion('micromessenger') // 是否微信
};
-
+
// 任意的 key
if(key && !result[key]){
result[key] = getVersion(key);
}
-
+
// 移动设备
result.android = /android/.test(agent);
result.ios = result.os === 'ios';
result.mobile = (result.android || result.ios);
-
+
return result;
};
@@ -561,33 +561,33 @@
error: error
};
};
-
+
// typeof 类型细分 -> string/number/boolean/undefined/null、object/array/function/…
Layui.prototype._typeof = Layui.prototype.type = function(operand){
if(operand === null) return String(operand);
-
+
// 细分引用类型
return (typeof operand === 'object' || typeof operand === 'function') ? function(){
var type = Object.prototype.toString.call(operand).match(/\s(.+)\]$/) || []; // 匹配类型字符
var classType = 'Function|Array|Date|RegExp|Object|Error|Symbol'; // 常见类型字符
-
+
type = type[1] || 'Object';
-
+
// 除匹配到的类型外,其他对象均返回 object
- return new RegExp('\\b('+ classType + ')\\b').test(type)
- ? type.toLowerCase()
+ return new RegExp('\\b('+ classType + ')\\b').test(type)
+ ? type.toLowerCase()
: 'object';
}() : typeof operand;
};
-
+
// 对象是否具备数组结构(此处为兼容 jQuery 对象)
Layui.prototype._isArray = Layui.prototype.isArray = function(obj){
var that = this;
var len;
var type = that.type(obj);
-
+
if(!obj || (typeof obj !== 'object') || obj === win) return false;
-
+
len = 'length' in obj && obj.length; // 兼容 ie
return type === 'array' || len === 0 || (
typeof len === 'number' && len > 0 && (len - 1) in obj // 兼容 jQuery 对象
@@ -601,10 +601,10 @@
var callFn = function(key, obj){ // 回调
return fn.call(obj[key], key, obj[key])
};
-
+
if(typeof fn !== 'function') return that;
obj = obj || [];
-
+
// 优先处理数组结构
if(that.isArray(obj)){
for(key = 0; key < obj.length; key++){
@@ -615,7 +615,7 @@
if(callFn(key, obj)) break;
}
}
-
+
return that;
};
@@ -632,12 +632,12 @@
} else if(typeof arr !== 'object'){ // 若 arr 非对象
return [clone];
}
-
+
// 开始排序
clone.sort(function(o1, o2){
var v1 = o1[key];
var v2 = o2[key];
-
+
/*
* 特殊数据
* 若比较的成员均非对象
@@ -679,11 +679,11 @@
return v1 - v2;
}
}
-
+
/**
* 字典序排序
*/
-
+
// 若为非数字比较
if(!isNum[0] && !isNum[1]){
// 字典序比较
@@ -695,7 +695,7 @@
return 0;
}
}
-
+
// 若为混合比较
if(isNum[0] || !isNum[1]){ // 数字 vs 非数字
return -1;
@@ -716,13 +716,13 @@
thisEvent.cancelBubble = true;
}
};
-
+
// 字符常理
var EV_REMOVE = 'LAYUI-EVENT-REMOVE';
// 自定义模块事件
Layui.prototype.onevent = function(modName, events, callback){
- if(typeof modName !== 'string'
+ if(typeof modName !== 'string'
|| typeof callback !== 'function') return this;
return Layui.event(modName, events, null, callback);
@@ -739,13 +739,13 @@
var res = item && item.call(that, params);
res === false && result === null && (result = false);
};
-
+
// 如果参数传入特定字符,则执行移除事件
if(params === EV_REMOVE){
delete (that.cache.event[eventName] || {})[filterName];
return that;
}
-
+
// 添加事件
if(fn){
config.event[eventName] = config.event[eventName] || {};
@@ -760,7 +760,7 @@
}
return this;
}
-
+
// 执行事件回调
layui.each(config.event[eventName], function(key, item){
// 执行当前模块的全部事件
@@ -768,21 +768,21 @@
layui.each(item, callback);
return;
}
-
+
// 执行指定事件
key === '' && layui.each(item, callback);
(filterName && key === filterName) && layui.each(item, callback);
});
-
+
return result;
};
-
+
// 新增模块事件
Layui.prototype.on = function(events, modName, callback){
var that = this;
return that.onevent.call(that, modName, events, callback);
}
-
+
// 移除模块事件
Layui.prototype.off = function(events, modName){
var that = this;
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/all.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/all.js
index bcfa718..2a27c87 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/modules/all.js
+++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/all.js
@@ -5,7 +5,8 @@
layui.define(function(){
var mods = []
- ,builtin = layui.cache.builtin;
+ var builtin = layui.cache.builtin;
+
layui.each(builtin, function(modName){
(modName === 'all' || modName === 'layui.all') || mods.push(modName);
});
@@ -15,12 +16,12 @@ layui.define(function(){
}(), function(exports){
"use strict";
- var MOD_NAME = 'all'
+ var MOD_NAME = 'all';
- //外部接口
- ,all = {
- config: {}
- ,time: function(){
+ // 外部接口
+ var all = {
+ config: {},
+ time: function(){
var time = new Date().getTime() - layui.cache.startTime;
delete layui.cache.startTime;
return time;
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/carousel.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/carousel.js
index 765abe9..ee24b77 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/modules/carousel.js
+++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/carousel.js
@@ -12,50 +12,61 @@ layui.define(['jquery', 'lay'], function(exports){
var hint = layui.hint();
var device = layui.device();
- //外部接口
+ // 外部接口
var carousel = {
- config: {} //全局配置项
+ config: {}, // 全局配置项
- //设置全局项
- ,set: function(options){
+ // 设置全局项
+ set: function(options){
var that = this;
that.config = $.extend({}, that.config, options);
return that;
- }
+ },
- //事件
- ,on: function(events, callback){
+ // 事件
+ on: function(events, callback){
return layui.onevent.call(this, MOD_NAME, events, callback);
}
- }
+ };
- //字符常量
- ,MOD_NAME = 'carousel', ELEM = '.layui-carousel', THIS = 'layui-this', SHOW = 'layui-show', HIDE = 'layui-hide', DISABLED = 'layui-disabled'
+ // 字符常量
+ var MOD_NAME = 'carousel';
+ var ELEM = '.layui-carousel';
+ var THIS = 'layui-this';
+ var SHOW = 'layui-show';
+ var HIDE = 'layui-hide';
+ var DISABLED = 'layui-disabled'
- ,ELEM_ITEM = '>*[carousel-item]>*', ELEM_LEFT = 'layui-carousel-left', ELEM_RIGHT = 'layui-carousel-right', ELEM_PREV = 'layui-carousel-prev', ELEM_NEXT = 'layui-carousel-next', ELEM_ARROW = 'layui-carousel-arrow', ELEM_IND = 'layui-carousel-ind'
+ var ELEM_ITEM = '>*[carousel-item]>*';
+ var ELEM_LEFT = 'layui-carousel-left';
+ var ELEM_RIGHT = 'layui-carousel-right';
+ var ELEM_PREV = 'layui-carousel-prev';
+ var ELEM_NEXT = 'layui-carousel-next';
+ var ELEM_ARROW = 'layui-carousel-arrow';
+ var ELEM_IND = 'layui-carousel-ind';
- //构造器
- ,Class = function(options){
+ // 构造器
+ var Class = function(options){
var that = this;
that.config = $.extend({}, that.config, carousel.config, options);
that.render();
};
- //默认配置
+ // 默认配置
Class.prototype.config = {
- width: '600px'
- ,height: '280px'
- ,full: false //是否全屏
- ,arrow: 'hover' //切换箭头默认显示状态:hover/always/none
- ,indicator: 'inside' //指示器位置:inside/outside/none
- ,autoplay: true //是否自动切换
- ,interval: 3000 //自动切换的时间间隔,不能低于800ms
- ,anim: '' //动画类型:default/updown/fade
- ,trigger: 'click' //指示器的触发方式:click/hover
- ,index: 0 //初始开始的索引
+ width: '600px',
+ height: '280px',
+ full: false, // 是否全屏
+ arrow: 'hover', // 切换箭头默认显示状态:hover/always/none
+ indicator: 'inside', // 指示器位置:inside/outside/none
+ autoplay: true, // 是否自动切换
+ interval: 3000, // 自动切换的时间间隔,不能低于800ms
+ anim: '', // 动画类型:default/updown/fade
+ trigger: 'click', // 指示器的触发方式:click/hover
+ index: 0 // 初始开始的索引
};
- //轮播渲染
+ // 轮播渲染
Class.prototype.render = function(){
var that = this;
var options = that.config;
@@ -82,35 +93,37 @@ layui.define(['jquery', 'lay'], function(exports){
if(options.index >= that.elemItem.length) options.index = that.elemItem.length - 1;
if(options.interval < 800) options.interval = 800;
- //是否全屏模式
+ // 是否全屏模式
if(options.full){
options.elem.css({
- position: 'fixed'
- ,width: '100%'
- ,height: '100%'
- ,zIndex: 9999
+ position: 'fixed',
+ width: '100%',
+ height: '100%',
+ zIndex: 9999
});
} else {
options.elem.css({
- width: options.width
- ,height: options.height
+ width: options.width,
+ height: options.height
});
}
options.elem.attr('lay-anim', options.anim);
- //初始焦点状态
+ // 初始焦点状态
that.elemItem.eq(options.index).addClass(THIS);
- //指示器等动作
- if(that.elemItem.length <= 1) return;
+ // 指示器、箭头等动作
that.indicator();
that.arrow();
that.autoplay();
- that.events();
+
+ if (that.elemItem.length > 1) {
+ that.events();
+ }
};
- //重置轮播
+ // 重置轮播
Class.prototype.reload = function(options){
var that = this;
clearInterval(that.timer);
@@ -118,95 +131,101 @@ layui.define(['jquery', 'lay'], function(exports){
that.render();
};
- //获取上一个等待条目的索引
+ // 获取上一个等待条目的索引
Class.prototype.prevIndex = function(){
- var that = this
- ,options = that.config;
-
+ var that = this;
+ var options = that.config;
var prevIndex = options.index - 1;
+
if(prevIndex < 0){
prevIndex = that.elemItem.length - 1;
}
+
return prevIndex;
};
- //获取下一个等待条目的索引
+ // 获取下一个等待条目的索引
Class.prototype.nextIndex = function(){
- var that = this
- ,options = that.config;
-
+ var that = this;
+ var options = that.config;
var nextIndex = options.index + 1;
+
if(nextIndex >= that.elemItem.length){
nextIndex = 0;
}
+
return nextIndex;
};
- //索引递增
+ // 索引递增
Class.prototype.addIndex = function(num){
- var that = this
- ,options = that.config;
+ var that = this;
+ var options = that.config;
num = num || 1;
options.index = options.index + num;
- //index不能超过轮播总数量
+ // index 不能超过轮播总数量
if(options.index >= that.elemItem.length){
options.index = 0;
}
};
- //索引递减
+ // 索引递减
Class.prototype.subIndex = function(num){
- var that = this
- ,options = that.config;
+ var that = this;
+ var options = that.config;
num = num || 1;
options.index = options.index - num;
- //index不能超过轮播总数量
+ // index 不能超过轮播总数量
if(options.index < 0){
options.index = that.elemItem.length - 1;
}
};
- //自动轮播
+ // 自动轮播
Class.prototype.autoplay = function(){
- var that = this
- ,options = that.config;
+ var that = this;
+ var options = that.config;
+ var itemsCount = that.elemItem.length;
if(!options.autoplay) return;
clearInterval(that.timer);
- that.timer = setInterval(function(){
- that.slide();
- }, options.interval);
+ if (itemsCount > 1) {
+ that.timer = setInterval(function(){
+ that.slide();
+ }, options.interval);
+ }
};
- //箭头
+ // 箭头
Class.prototype.arrow = function(){
- var that = this
- ,options = that.config;
+ var that = this;
+ var options = that.config;
+ var itemsCount = that.elemItem.length;
- //模板
+ // 模板
var tplArrow = $([
- '
'+ (options.anim === 'updown' ? '' : '') +' '
- ,'
'+ (options.anim === 'updown' ? '' : '') +' '
+ '
',
+ '
'
].join(''));
- //预设基础属性
+ // 预设基础属性
options.elem.attr('lay-arrow', options.arrow);
- //避免重复插入
+ // 避免重复插入
if(options.elem.find('.'+ELEM_ARROW)[0]){
options.elem.find('.'+ELEM_ARROW).remove();
}
- options.elem.append(tplArrow);
+ itemsCount > 1 ? options.elem.append(tplArrow) : tplArrow.remove();
- //事件
+ // 事件
tplArrow.on('click', function(){
- var othis = $(this)
- ,type = othis.attr('lay-type')
+ var othis = $(this);
+ var type = othis.attr('lay-type')
that.slide(type);
});
};
@@ -223,30 +242,32 @@ layui.define(['jquery', 'lay'], function(exports){
}
}
- //指示器
+ // 指示器
Class.prototype.indicator = function(){
- var that = this
- ,options = that.config;
+ var that = this;
+ var options = that.config;
+ var itemsCount = that.elemItem.length;
- //模板
- var tplInd = that.elemInd = $(['
'
- ,function(){
+ // 模板
+ var tplInd = that.elemInd = $(['',
+ function(){
var li = [];
layui.each(that.elemItem, function(index){
li.push(' ');
});
return li.join('');
- }()
- ,' '].join(''));
+ }(),
+ ' '].join(''));
- //预设基础属性
+ // 预设基础属性
options.elem.attr('lay-indicator', options.indicator);
- //避免重复插入
+ // 避免重复插入
if(options.elem.find('.'+ELEM_IND)[0]){
options.elem.find('.'+ELEM_IND).remove();
}
- options.elem.append(tplInd);
+
+ itemsCount > 1 ? options.elem.append(tplInd) : tplInd.remove();
if(options.anim === 'updown'){
tplInd.css('margin-top', -(tplInd.height()/2));
@@ -258,17 +279,18 @@ layui.define(['jquery', 'lay'], function(exports){
});
};
- //滑动切换
+ // 滑动切换
Class.prototype.slide = function(type, num){
- var that = this
- ,elemItem = that.elemItem
- ,options = that.config
- ,thisIndex = options.index
- ,filter = options.elem.attr('lay-filter');
+ var that = this;
+ var elemItem = that.elemItem;
+ var itemsCount = elemItem.length;
+ var options = that.config;
+ var thisIndex = options.index;
+ var filter = options.elem.attr('lay-filter');
- if(that.haveSlide) return;
+ if (that.haveSlide || itemsCount <= 1) return;
- //滑动方向
+ // 滑动方向
if(type === 'sub'){
that.subIndex(num);
elemItem.eq(options.index).addClass(ELEM_PREV);
@@ -276,7 +298,7 @@ layui.define(['jquery', 'lay'], function(exports){
elemItem.eq(thisIndex).addClass(ELEM_RIGHT);
elemItem.eq(options.index).addClass(ELEM_RIGHT);
}, 50);
- } else { //默认递增滑
+ } else { // 默认递增滑
that.addIndex(num);
elemItem.eq(options.index).addClass(ELEM_NEXT);
setTimeout(function(){
@@ -285,14 +307,14 @@ layui.define(['jquery', 'lay'], function(exports){
}, 50);
}
- //移除过度类
+ // 移除过渡类
setTimeout(function(){
elemItem.removeClass(THIS + ' ' + ELEM_PREV + ' ' + ELEM_NEXT + ' ' + ELEM_LEFT + ' ' + ELEM_RIGHT);
elemItem.eq(options.index).addClass(THIS);
- that.haveSlide = false; //解锁
- }, 300);
+ that.haveSlide = false; // 解锁
+ }, 350);
- //指示器焦点
+ // 指示器焦点
that.elemInd.find('li').eq(options.index).addClass(THIS)
.siblings().removeClass(THIS);
@@ -300,35 +322,50 @@ layui.define(['jquery', 'lay'], function(exports){
// 回调返回的参数
var params = {
- index: options.index
- ,prevIndex: thisIndex
- ,item: elemItem.eq(options.index)
+ index: options.index,
+ prevIndex: thisIndex,
+ item: elemItem.eq(options.index)
};
typeof options.change === 'function' && options.change(params);
layui.event.call(this, MOD_NAME, 'change('+ filter +')', params);
};
- //事件处理
+ // 事件处理
Class.prototype.events = function(){
- var that = this
- ,options = that.config;
+ var that = this;
+ var options = that.config;
if(options.elem.data('haveEvents')) return;
+
- //移入移出容器
- options.elem.on('mouseenter', function(){
+ // 移入移出容器
+ options.elem.on('mouseenter touchstart', function(){
if (that.config.autoplay === 'always') return;
clearInterval(that.timer);
- }).on('mouseleave', function(){
+ }).on('mouseleave touchend', function(){
if (that.config.autoplay === 'always') return;
that.autoplay();
});
+
+ var touchEl = options.elem;
+ var isVertical = options.anim === 'updown';
+ lay.touchSwipe(touchEl, {
+ onTouchEnd: function(e, state){
+ var duration = Date.now() - state.timeStart;
+ var distance = isVertical ? state.distanceY : state.distanceX;
+ var speed = distance / duration;
+ var shouldSwipe = Math.abs(speed) > 0.25 || Math.abs(distance) > touchEl[isVertical ? 'height' : 'width']() / 3;
+ if(shouldSwipe){
+ that.slide(distance > 0 ? '' : 'sub');
+ }
+ }
+ })
options.elem.data('haveEvents', true);
};
- //核心入口
+ // 核心入口
carousel.render = function(options){
return new Class(options);
};
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/code.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/code.js
index 5efd496..9c8ecd9 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/modules/code.js
+++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/code.js
@@ -1,32 +1,37 @@
/**
- * code
+ * code
* Code 预览组件
*/
-
+
layui.define(['lay', 'util', 'element', 'form'], function(exports){
"use strict";
-
+
var $ = layui.$;
var util = layui.util;
var element = layui.element;
var form = layui.form;
var layer = layui.layer;
+ var hint = layui.hint();
// 常量
var CONST = {
ELEM_VIEW: 'layui-code-view',
- ELEM_COPY: 'layui-code-copy',
ELEM_TAB: 'layui-tab',
- ELEM_TITLE: 'layui-code-title',
+ ELEM_HEADER: 'layui-code-header',
ELEM_FULL: 'layui-code-full',
ELEM_PREVIEW: 'layui-code-preview',
ELEM_ITEM: 'layui-code-item',
- ELEM_SHOW: 'layui-show'
+ ELEM_SHOW: 'layui-show',
+ ELEM_LINE: 'layui-code-line',
+ ELEM_LINE_NUM: 'layui-code-line-number',
+ ELEM_LN_MODE: 'layui-code-ln-mode',
+ CDDE_DATA_CLASS: 'LayuiCodeDataClass',
+ LINE_RAW_WIDTH: 45, // 行号初始宽度,需与 css 保持一致
};
// 默认参数项
var config = {
- elem: '.layui-code', // 元素选择器
+ elem: '', // 元素选择器
about: '', // 代码栏右上角信息
ln: true, // 代码区域是否显示行号
header: false, // 是否显示代码栏头部区域
@@ -35,338 +40,557 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
// 默认文本
text: {
code: util.escape('>'),
- preview: 'Preview'
- }
+ preview: 'Preview',
+ },
+ wordWrap: true, // 是否自动换行
+ lang: 'text', // 指定语言类型
+ highlighter: false, // 是否开启语法高亮,'hljs','prism','shiki'
+ langMarker: false, // 代码区域是否显示语言类型标记
};
+ // 初始索引
+ var codeIndex = layui.code ? (layui.code.index + 10000) : 0;
+
+ // 去除尾部空格
+ var trimEnd = function(str){
+ return String(str).replace(/\s+$/, '');
+ }
+ // 保留首行缩进
var trim = function(str){
- return $.trim(str).replace(/^\n|\n$/, '');
+ return trimEnd(str).replace(/^\n|\n$/, '');
};
-
+
// export api
- exports('code', function(options){
- var opts = options = $.extend(true, {}, config, options);
+ exports('code', function(options, mode){
+ options = $.extend(true, {}, config, options);
+
+ // 返回对象
+ var ret = {
+ config: options,
+ reload: function(opts) { // 重载
+ layui.code(this.updateOptions(opts));
+ },
+ updateOptions: function(opts) { // 更新属性(选项)
+ opts = opts || {};
+ delete opts.elem;
+ return $.extend(true, options, opts);
+ },
+ reloadCode: function(opts) { // 仅重载 code
+ layui.code(this.updateOptions(opts), 'reloadCode');
+ }
+ };
+
+ // 若 elem 非唯一
+ var elem = $(options.elem);
+ if(elem.length > 1){
+ // 是否正向渲染
+ layui.each(options.obverse ? elem : elem.get().reverse(), function(){
+ layui.code($.extend({}, options, {
+ elem: this
+ }), mode);
+ });
+ return ret;
+ }
// 目标元素是否存在
- options.elem = $(options.elem);
- if(!options.elem[0]) return;
+ var othis = options.elem = $(options.elem);
+ if(!othis[0]) return ret;
- // 从内至外渲染
- layui.each(options.elem.get().reverse(), function(index, item){
- var othis = $(item);
-
- // 合并属性上的参数,并兼容旧版本属性写法 lay-*
- var options = $.extend(true, {}, opts, lay.options(item), function(obj){
- var attrs = ['title', 'height', 'encode', 'skin', 'about'];
- layui.each(attrs, function(i, attr){
- var value = othis.attr('lay-'+ attr);
- if(typeof value === 'string'){
- obj[attr] = value;
- }
- })
- return obj;
- }({}));
-
- // 最终显示的代码
- var finalCode;
-
- // 获得初始代码
- var codes = othis.data('code') || function(){
- var arr = [];
- var textarea = othis.children('textarea');
-
- // 若内容放置在 textarea 中
- textarea.each(function(){
- arr.push(trim(this.value));
- });
-
- // 内容直接放置在元素外层
- if(arr.length === 0){
- arr.push(trim(othis.html()));
+ // 合并属性上的参数,并兼容旧版本属性写法 lay-*
+ $.extend(true, options, lay.options(othis[0]), function(obj){
+ var attrs = ['title', 'height', 'encode', 'skin', 'about'];
+ layui.each(attrs, function(i, attr){
+ var value = othis.attr('lay-'+ attr);
+ if(typeof value === 'string'){
+ obj[attr] = value;
}
-
- return arr;
- }();
+ })
+ return obj;
+ }({}));
- othis.data('code', codes);
+ // codeRender 需要关闭编码
+ // 未使用 codeRender 时若开启了预览,则强制开启编码
+ options.encode = (options.encode || options.preview) && !options.codeRender;
- // code
- var html = finalCode = codes.join('');
+ // 获得初始 code
+ options.code = options.code || function(){
+ var arr = [];
+ var textarea = othis.children('textarea');
- // 外部重新解析 code
- if(typeof options.codeParse === 'function'){
- html = finalCode = options.codeParse(html);
+ // 若内容放置在 textarea 中
+ textarea.each(function(){
+ arr.push(trim(this.value));
+ });
+
+ // 内容直接放置在元素外层
+ if(arr.length === 0){
+ arr.push(trim(othis.html()));
}
- // 工具栏
- var tools = {
- copy: {
- className: 'file-b',
- title: ['复制代码'],
- event: function(el, type){
- typeof options.onCopy === 'function' ? options.onCopy(finalCode) : function(){
- try {
- navigator.clipboard.writeText(util.unescape(finalCode)).then(function(){
- layer.msg('已复制', {
- icon: 1
- });
- });
- } catch(e) {
- layer.msg('复制失败', {
- icon: 2
- });
- }
- }();
- }
- }
+ return arr.join('');
+ }();
+
+ // 创建 code 行结构
+ var createCode = function(html) {
+ // codeRender
+ if(typeof options.codeRender === 'function') {
+ html = options.codeRender(String(html), options);
+ }
+
+ // code 行
+ var lines = String(html).split(/\r?\n/g);
+
+ // 包裹 code 行结构
+ html = $.map(lines, function(line, num) {
+ return [
+ '
',
+ (
+ options.ln ? [
+ '
',
+ (util.digit(num + 1) + '.'),
+ '
',
+ ].join('') : ''
+ ),
+ '
',
+ (line || ' '),
+ '
',
+ '
'
+ ].join('');
+ });
+
+ return {
+ lines: lines,
+ html: html
};
+ };
- // 是否开启预览
- if(options.preview){
- var FILTER_VALUE = 'LAY-CODE-DF-'+ index;
- var layout = options.layout || ['code', 'preview'];
- var isIframePreview = options.preview === 'iframe';
-
- // 追加 Tab 组件
- var elemView = $('
');
- var elemTabView = $('
');
- var elemHeaderView = $('
');
- var elemPreviewView = $('
');
- var elemToolbar = $('
');
- var elemViewHas = othis.parent('.' + CONST.ELEM_PREVIEW);
- var elemTabHas = othis.prev('.'+ CONST.ELEM_TAB);
- var elemPreviewViewHas = othis.next('.' + CONST.ELEM_ITEM +'-preview');
+ // 原始 code
+ var rawCode = options.code;
- if(options.id) elemView.attr('id', options.id);
- elemView.addClass(options.className);
- elemTabView.attr('lay-filter', FILTER_VALUE);
+ // 最终 code
+ var finalCode = function(code) {
+ return typeof options.codeParse === 'function' ?
+ options.codeParse(code, options) :
+ code;
+ };
- // 若开启预览,则强制对 code 进行编码
- options.encode = true;
+ // 仅重载 code
+ if (mode === 'reloadCode') {
+ return othis.children('.layui-code-wrap').html(
+ createCode(finalCode(rawCode)).html
+ ), ret;
+ }
- // 标签头
- layui.each(layout, function(i, v){
- var li = $('
');
- if(i === 0) li.addClass('layui-this');
- li.html(options.text[v]);
- elemHeaderView.append(li);
- });
+ // 自增索引
+ var index = layui.code.index = ++codeIndex;
+ othis.attr('lay-code-index', index);
- // 工具栏
- $.extend(tools, {
- 'full': {
- className: 'screen-full',
- title: ['最大化显示', '还原显示'],
- event: function(el, type){
- var elemView = el.closest('.'+ CONST.ELEM_PREVIEW);
- var classNameFull = 'layui-icon-'+ this.className;
- var classNameRestore = 'layui-icon-screen-restore';
- var title = this.title;
- var html = $('html,body');
- var ELEM_SCOLLBAR_HIDE = 'layui-scollbar-hide';
+ // 初始化 className
+ var hasDataClass = CONST.CDDE_DATA_CLASS in othis.data();
+ if (hasDataClass) {
+ othis.attr('class', othis.data(CONST.CDDE_DATA_CLASS) || '');
+ }
- if(el.hasClass(classNameFull)){
- elemView.addClass(CONST.ELEM_FULL);
- el.removeClass(classNameFull).addClass(classNameRestore);
- el.attr('title', title[1]);
- html.addClass(ELEM_SCOLLBAR_HIDE);
- } else {
- elemView.removeClass(CONST.ELEM_FULL);
- el.removeClass(classNameRestore).addClass(classNameFull);
- el.attr('title', title[0]);
- html.removeClass(ELEM_SCOLLBAR_HIDE);
- }
+ // 记录初始 className
+ if (!hasDataClass) {
+ othis.data(CONST.CDDE_DATA_CLASS, othis.attr('class'));
+ }
+
+ // 工具栏
+ var tools = {
+ copy: {
+ className: 'file-b',
+ title: ['复制代码'],
+ event: function(obj){
+ var code = util.unescape(finalCode(options.code));
+
+ // 写入剪切板
+ lay.clipboard.writeText({
+ text: code,
+ done: function() {
+ layer.msg('已复制', {icon: 1});
+ },
+ error: function() {
+ layer.msg('复制失败', {icon: 2});
}
- },
- 'window': {
- className: 'release',
- title: ['在新窗口预览'],
- event: function(el, type){
- util.openWin({
- content: finalCode
- });
+ });
+
+ typeof options.onCopy === 'function' && options.onCopy(code);
+ }
+ }
+ };
+
+ // 移除包裹结构
+ var unwrap = (function fn() {
+ var elemViewHas = othis.parent('.' + CONST.ELEM_PREVIEW);
+ var elemTabHas = elemViewHas.children('.'+ CONST.ELEM_TAB);
+ var elemPreviewViewHas = elemViewHas.children('.' + CONST.ELEM_ITEM +'-preview');
+
+ // 移除旧结构
+ elemTabHas.remove(); // 移除 tab
+ elemPreviewViewHas.remove(); // 移除预览区域
+ if (elemViewHas[0]) othis.unwrap(); // 移除外层容器
+
+ return fn;
+ })();
+
+ // 是否开启预览
+ if(options.preview){
+ var FILTER_VALUE = 'LAY-CODE-DF-'+ index;
+ var layout = options.layout || ['code', 'preview'];
+ var isIframePreview = options.preview === 'iframe';
+
+ // 追加 Tab 组件
+ var elemView = $('');
+ var elemTabView = $('
');
+ var elemHeaderView = $('
');
+ var elemPreviewView = $('
');
+ var elemToolbar = $('
');
+
+
+ if(options.id) elemView.attr('id', options.id);
+ elemView.addClass(options.className);
+ elemTabView.attr('lay-filter', FILTER_VALUE);
+
+ // 标签头
+ layui.each(layout, function(i, v){
+ var li = $('
');
+ if(i === 0) li.addClass('layui-this');
+ li.html(options.text[v]);
+ elemHeaderView.append(li);
+ });
+
+ // 工具栏
+ $.extend(tools, {
+ 'full': {
+ className: 'screen-full',
+ title: ['最大化显示', '还原显示'],
+ event: function(obj){
+ var el = obj.elem;
+ var elemView = el.closest('.'+ CONST.ELEM_PREVIEW);
+ var classNameFull = 'layui-icon-'+ this.className;
+ var classNameRestore = 'layui-icon-screen-restore';
+ var title = this.title;
+ var htmlElem = $('html,body');
+ var ELEM_SCROLLBAR_HIDE = 'layui-scrollbar-hide';
+
+ if(el.hasClass(classNameFull)){
+ elemView.addClass(CONST.ELEM_FULL);
+ el.removeClass(classNameFull).addClass(classNameRestore);
+ el.attr('title', title[1]);
+ htmlElem.addClass(ELEM_SCROLLBAR_HIDE);
+ } else {
+ elemView.removeClass(CONST.ELEM_FULL);
+ el.removeClass(classNameRestore).addClass(classNameFull);
+ el.attr('title', title[0]);
+ htmlElem.removeClass(ELEM_SCROLLBAR_HIDE);
}
}
- });
-
- // copy
- if(options.copy){
- if(layui.type(options.tools) === 'array'){
- // 若 copy 未存在于 tools 中,则追加到最前
- if(options.tools.indexOf('copy') === -1){
- options.tools.unshift('copy');
- }
- } else {
- options.tools = ['copy'];
+ },
+ 'window': {
+ className: 'release',
+ title: ['在新窗口预览'],
+ event: function(obj){
+ util.openWin({
+ content: finalCode(options.code)
+ });
}
}
+ });
- // 工具栏事件
- elemToolbar.on('click', '>i', function(){
- var oi = $(this);
- var type = oi.data('type');
- typeof tools[type].event === 'function' && tools[type].event(oi, type);
- typeof options.toolsEvent === 'function' && options.toolsEvent(oi, type);
- });
- layui.each(options.tools, function(i, v){
- var className = (tools[v] && tools[v].className) || v;
- var title = tools[v].title || [''];
- elemToolbar.append(
- ' '
- );
- });
+ // copy
+ if(options.copy){
+ if(layui.type(options.tools) === 'array'){
+ // 若 copy 未存在于 tools 中,则追加到最前
+ if(options.tools.indexOf('copy') === -1){
+ options.tools.unshift('copy');
+ }
+ } else {
+ options.tools = ['copy'];
+ }
+ }
- // 移除旧结构
- if(elemTabHas[0]) elemTabHas.remove(); // 移除 tab
- if(elemPreviewViewHas[0]) elemPreviewViewHas.remove(); // 移除预览区域
- if(elemViewHas[0]) othis.unwrap(); // 移除外层容器
+ // 工具栏事件
+ elemToolbar.on('click', '>i', function(){
+ var oi = $(this);
+ var type = oi.data('type');
+ var parameters = {
+ elem: oi,
+ type: type,
+ options: options, // 当前属性选项
+ rawCode: options.code, // 原始 code
+ finalCode: util.unescape(finalCode(options.code)) // 最终 code
+ };
- elemTabView.append(elemHeaderView); // 追加标签头
- options.tools && elemTabView.append(elemToolbar); // 追加工具栏
- othis.wrap(elemView).addClass(CONST.ELEM_ITEM).before(elemTabView); // 追加标签结构
+ // 内部 tools event
+ tools[type] && typeof tools[type].event === 'function' && tools[type].event(parameters);
-
- // 追加预览
- if(isIframePreview){
- elemPreviewView.html('');
+ // 外部 tools event
+ typeof options.toolsEvent === 'function' && options.toolsEvent(parameters);
+ });
+
+ // 增加工具栏
+ if (options.addTools && options.tools) {
+ options.tools = [].concat(options.tools, options.addTools);
+ }
+
+ // 渲染工具栏
+ layui.each(options.tools, function(i, v){
+ var viso = typeof v === 'object'; // 若为 object 值,则可自定义更多属性
+ var tool = viso ? v : (
+ tools[v] || {
+ className: v,
+ title: [v]
+ }
+ );
+
+ var className = tool.className || tool.type;
+ var title = tool.title || [''];
+ var type = viso ? ( tool.type || className ) : v;
+
+ if (!type) return;
+
+ // 若非内置 tool,则合并到 tools 中
+ if (!tools[type]) {
+ var obj = {};
+ obj[type] = tool;
+ $.extend(tools, obj);
}
- // 执行预览
- var run = function(thisItemBody){
- var iframe = thisItemBody.children('iframe')[0];
- if(isIframePreview && iframe){
- iframe.srcdoc = finalCode;
- } else {
- thisItemBody.html(codes.join(''));
- }
- // 回调的返回参数
- var params = {
+ elemToolbar.append(
+ ' '
+ );
+ });
+
+ othis.addClass(CONST.ELEM_ITEM).wrap(elemView); // 包裹外层容器
+ elemTabView.append(elemHeaderView); // 追加标签头
+ options.tools && elemTabView.append(elemToolbar); // 追加工具栏
+ othis.before(elemTabView); // 追加标签结构
+
+ // 追加预览
+ if(isIframePreview){
+ elemPreviewView.html('');
+ }
+
+ // 执行预览
+ var runPreview = function(thisItemBody){
+ var iframe = thisItemBody.children('iframe')[0];
+
+ // 是否 iframe 方式预览
+ if(isIframePreview && iframe){
+ iframe.srcdoc = finalCode(options.code);
+ } else {
+ thisItemBody.html(options.code);
+ }
+
+ // 当前实例预览完毕后的回调
+ setTimeout(function(){
+ typeof options.done === 'function' && options.done({
container: thisItemBody,
+ options: options,
render: function(){
form.render(thisItemBody.find('.layui-form'));
element.render();
}
- };
- // 当前实例预览完毕后的回调
- setTimeout(function(){
- typeof options.done === 'function' && options.done(params);
- },3);
- };
+ });
+ },3);
+ };
- if(layout[0] === 'preview'){
- elemPreviewView.addClass(CONST.ELEM_SHOW);
- othis.before(elemPreviewView);
- run(elemPreviewView);
- } else {
- othis.addClass(CONST.ELEM_SHOW).after(elemPreviewView);
+ if(layout[0] === 'preview'){
+ elemPreviewView.addClass(CONST.ELEM_SHOW);
+ othis.before(elemPreviewView);
+ runPreview(elemPreviewView);
+ } else {
+ othis.addClass(CONST.ELEM_SHOW).after(elemPreviewView);
+ }
+
+ // 内容项初始化样式
+ options.previewStyle = [options.style, options.previewStyle].join('');
+ elemPreviewView.attr('style', options.previewStyle);
+
+ // tab change
+ element.on('tab('+ FILTER_VALUE +')', function(data){
+ var $this = $(this);
+ var thisElem = $(data.elem).closest('.'+ CONST.ELEM_PREVIEW);
+ var elemItemBody = thisElem.find('.'+ CONST.ELEM_ITEM);
+ var thisItemBody = elemItemBody.eq(data.index);
+
+ elemItemBody.removeClass(CONST.ELEM_SHOW);
+ thisItemBody.addClass(CONST.ELEM_SHOW);
+
+ if($this.attr('lay-id') === 'preview'){
+ runPreview(thisItemBody);
}
- // 内容项初始化样式
- options.codeStyle = [options.style, options.codeStyle].join('');
- options.previewStyle = [options.style, options.previewStyle].join('');
- // othis.attr('style', options.codeStyle);
- elemPreviewView.attr('style', options.previewStyle);
+ setCodeLayout();
+ });
+ }
- // tab change
- element.on('tab('+ FILTER_VALUE +')', function(data){
- var $this = $(this);
- var thisElem = $(data.elem).closest('.'+ CONST.ELEM_PREVIEW);
- var elemItemBody = thisElem.find('.'+ CONST.ELEM_ITEM);
- var thisItemBody = elemItemBody.eq(data.index);
-
- elemItemBody.removeClass(CONST.ELEM_SHOW);
- thisItemBody.addClass(CONST.ELEM_SHOW);
+ // 创建 code 容器
+ var codeElem = $('
'); // 此处的闭合标签是为了兼容 IE8
- if($this.attr('lay-id') === 'preview'){
- run(thisItemBody);
- }
- });
- }
+ // 添加主容器 className
+ othis.addClass(function(arr) {
+ if (!options.wordWrap) arr.push('layui-code-nowrap');
+ return arr.join(' ')
+ }(['layui-code-view layui-border-box']));
- // 有序或无序列表
- var listTag = options.ln ? 'ol' : 'ul';
- var listElem = $('<'+ listTag +' class="layui-code-'+ listTag +'">');
+ // code 主题风格
+ var theme = options.theme || options.skin;
+ if (theme) {
+ othis.removeClass('layui-code-theme-dark layui-code-theme-light');
+ othis.addClass('layui-code-theme-'+ theme);
+ }
- // header
- var headerElem = $('');
+ // 添加高亮必要的 className
+ if (options.highlighter) {
+ othis.addClass([
+ options.highlighter,
+ 'language-' + options.lang,
+ 'layui-code-hl'
+ ].join(' '));
+ }
- // 添加组件 clasName
- othis.addClass('layui-code-view layui-box');
+ // 获取 code 行结构
+ var createCodeRst = createCode(
+ options.encode ? util.escape(finalCode(rawCode)) : rawCode // 是否编码
+ );
+ var lines = createCodeRst.lines;
- // 自定义风格
- if(options.skin){
- if(options.skin === 'notepad') options.skin = 'dark';
- othis.removeClass('layui-code-dark layui-code-light');
- othis.addClass('layui-code-'+ options.skin);
- }
+ // 插入 code
+ othis.html(codeElem.html(createCodeRst.html));
-
-
+ // 插入行号边栏
+ if (options.ln) {
+ othis.append('
');
+ }
- // 转义 HTML 标签
- if(options.encode) html = util.escape(html); // 编码
- html = html.replace(/[\r\t\n]+/g, '
'); // 转义换行符
-
- // 生成列表
- othis.html(listElem.html(' ' + html + ' '));
-
- // 创建 header
- if(options.header && !othis.children('.'+ CONST.ELEM_TITLE)[0]){
- headerElem.html((options.title || options.text.code) + (
- options.about
- ? '
' + options.about + '
'
- : ''
- ));
- othis.prepend(headerElem);
- }
+ // 兼容旧版本 height 属性
+ if (options.height) {
+ codeElem.css('max-height', options.height);
+ }
- // 所有实例渲染完毕后的回调
- if(options.elem.length === index + 1){
- typeof options.allDone === 'function' && options.allDone();
- }
+ // code 区域样式
+ options.codeStyle = [options.style, options.codeStyle].join('');
+ if (options.codeStyle) {
+ codeElem.attr('style', function(i, val) {
+ return (val || '') + options.codeStyle;
+ });
+ }
- // 按行数适配左边距
- (function(autoIncNums){
- if(autoIncNums > 0){
- listElem.css('margin-left', autoIncNums + 'px');
+ // 动态设置样式
+ var cssRules = [
+ {
+ selector: '>.layui-code-wrap>.layui-code-line{}',
+ setValue: function(item, value) {
+ item.style['padding-left'] = value + 'px';
+ }
+ },
+ {
+ selector: '>.layui-code-wrap>.layui-code-line>.layui-code-line-number{}',
+ setValue: function(item, value) {
+ item.style.width = value + 'px';
+ }
+ },
+ {
+ selector: '>.layui-code-ln-side{}',
+ setValue: function(item, value) {
+ item.style.width = value + 'px';
}
- })(Math.floor(listElem.find('li').length/100));
-
- // 限制 Code 最大高度
- if(options.height){ // 兼容旧版本
- listElem.css('max-height', options.height);
}
- // Code 内容区域样式
- listElem.attr('style', options.codeStyle);
+ ];
- // 是否开启代码复制
- if(options.copy && !options.preview){
- var elemCopy = $(['
',
- ' ',
- ' '].join(''));
- var elemCopyHas = othis.children('.'+ CONST.ELEM_COPY);
- var isHeight = listElem[0].style.height || listElem[0].style.maxHeight;
+ // 生成初始 style 元素
+ var styleElem = lay.style({
+ target: othis[0],
+ id: 'DF-code-'+ index,
+ text: $.map($.map(cssRules, function(val){
+ return val.selector;
+ }), function(val, i) {
+ return ['.layui-code-view[lay-code-index="'+ index + '"]', val].join(' ');
+ }).join('')
+ })
- if(isHeight) elemCopy.addClass(CONST.ELEM_COPY + '-offset'); // 偏移
- if(elemCopyHas[0]) elemCopyHas.remove(); // 移除旧的复制元素
- othis.append(elemCopy);
+ // 动态设置 code 布局
+ var setCodeLayout = (function fn() {
+ if (options.ln) {
+ var multiLine = Math.floor(lines.length / 100);
+ var lineElem = codeElem.children('.'+ CONST.ELEM_LINE);
+ var width = lineElem.last().children('.'+ CONST.ELEM_LINE_NUM).outerWidth();
- // 点击复制
- elemCopy.on('click', function(){
- tools.copy.event();
- });
+ othis.addClass(CONST.ELEM_LN_MODE);
+
+ // 若超出 100 行
+ if (multiLine && width > CONST.LINE_RAW_WIDTH) {
+ lay.getStyleRules(styleElem, function(item, i) {
+ try {
+ cssRules[i].setValue(item, width);
+ } catch(e) { }
+ });
+ }
}
- });
-
+ return fn;
+ })();
+
+ // 创建 code header
+ if (options.header) {
+ var headerElem = $('');
+ headerElem.html(options.title || options.text.code);
+ othis.prepend(headerElem);
+ }
+
+ // 创建 code 区域固定条
+ var elemFixbar = $('
');
+
+ // 若开启复制,且未开启预览,则单独生成复制图标
+ if(options.copy && !options.preview){
+ var copyElem = $(['
',
+ ' ',
+ ' '].join(''));
+
+ // 点击复制
+ copyElem.on('click', function(){
+ tools.copy.event();
+ });
+
+ elemFixbar.append(copyElem);
+ }
+
+ // 创建 language marker
+ if (options.langMarker) {
+ elemFixbar.append('
' + options.lang + ' ');
+ }
+
+ // 创建 about 自定义内容
+ if (options.about) {
+ elemFixbar.append(options.about);
+ }
+
+ // 生成 code fixbar
+ othis.append(elemFixbar);
+
+ // code 渲染完毕后的回调
+ if (!options.preview) {
+ setTimeout(function(){
+ typeof options.done === 'function' && options.done({});
+ },3);
+ }
+
+ // 所有实例渲染完毕后的回调
+ if(options.elem.length === index + 1){
+ typeof options.allDone === 'function' && options.allDone();
+ }
+
+ return ret;
});
});
// 若为源码版,则自动加载该组件依赖的 css 文件
if(!layui['layui.all']){
- layui.addcss('modules/code.css?v=3', 'skincodecss');
-}
\ No newline at end of file
+ layui.addcss('modules/code.css?v=6', 'skincodecss');
+}
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/colorpicker.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/colorpicker.js
index 514e35b..c67c7ce 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/modules/colorpicker.js
+++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/colorpicker.js
@@ -214,7 +214,7 @@ layui.define(['jquery', 'lay'], function(exports){
,'
'].join(''))
//初始化颜色选择框
- var elem = options.elem = $(options.elem);
+ elem = options.elem = $(options.elem);
options.size && elemColorBox.addClass('layui-colorpicker-'+ options.size); //初始化颜色选择框尺寸
// 插入颜色选择框
@@ -434,7 +434,7 @@ layui.define(['jquery', 'lay'], function(exports){
}
//回调更改的颜色
- options.change && options.change(that.elemPicker.find('.' + PICKER_INPUT).find('input').val());
+ options.change && options.change($.trim(that.elemPicker.find('.' + PICKER_INPUT).find('input').val()));
}
//拖拽元素
@@ -448,11 +448,16 @@ layui.define(['jquery', 'lay'], function(exports){
elemMove.remove();
});
};
+ // 移动端滑动模拟事件中
+ // 1. 不触发游标上绑定的事件,以提高性能,使滑动更流畅
+ // 2. 游标上的事件需要冒泡到颜色拾取区域,用来模拟拖动游标的效果
+ var needTrigger = true;
+ var needStopPropagation = true;
//右侧主色选择
- slider.on('mousedown', function(e){
- var oldtop = this.offsetTop
- ,oldy = e.clientY;
+ slider.on('mousedown', function(e, triggerEvent){
+ var oldtop = this.offsetTop;
+ var oldy = e.clientY === undefined ? triggerEvent.clientY : e.clientY;
var move = function(e){
var top = oldtop + (e.clientY - oldy)
,maxh = side[0].offsetHeight;
@@ -463,13 +468,12 @@ layui.define(['jquery', 'lay'], function(exports){
change(h, _s, _b, _a);
e.preventDefault();
};
-
+ needStopPropagation && layui.stope(e);
createMoveElem(move);
- //layui.stope(e);
e.preventDefault();
});
- side.on('click', function(e){
+ side.on('mousedown', function(e){
var top = e.clientY - $(this).offset().top + $win.scrollTop();
if(top < 0)top = 0;
if(top > this.offsetHeight) top = this.offsetHeight;
@@ -477,56 +481,57 @@ layui.define(['jquery', 'lay'], function(exports){
_h = h;
change(h, _s, _b, _a);
e.preventDefault();
+ needTrigger && slider.trigger('mousedown', e);
});
//中间小圆点颜色选择
- choose.on('mousedown', function(e){
- var oldtop = this.offsetTop
- ,oldleft = this.offsetLeft
- ,oldy = e.clientY
- ,oldx = e.clientX;
+ choose.on('mousedown', function(e, triggerEvent){
+ var oldtop = this.offsetTop;
+ var oldleft = this.offsetLeft;
+ var oldy = e.clientY === undefined ? triggerEvent.clientY : e.clientY;
+ var oldx = e.clientX === undefined ? triggerEvent.clientX : e.clientX;
var move = function(e){
var top = oldtop + (e.clientY - oldy)
,left = oldleft + (e.clientX - oldx)
- ,maxh = basis[0].offsetHeight - 3
- ,maxw = basis[0].offsetWidth - 3;
- if(top < -3)top = -3;
+ ,maxh = basis[0].offsetHeight
+ ,maxw = basis[0].offsetWidth;
+ if(top < 0)top = 0;
if(top > maxh)top = maxh;
- if(left < -3)left = -3;
+ if(left < 0)left = 0;
if(left > maxw)left = maxw;
- var s = (left + 3)/260*100
- ,b = 100 - (top + 3)/180*100;
+ var s = left/260*100
+ ,b = 100 - top/180*100;
_b = b;
_s = s;
change(_h, s, b, _a);
e.preventDefault();
};
- layui.stope(e);
+ needStopPropagation && layui.stope(e);
createMoveElem(move);
e.preventDefault();
});
basis.on('mousedown', function(e){
- var top = e.clientY - $(this).offset().top - 3 + $win.scrollTop()
- ,left = e.clientX - $(this).offset().left - 3 + $win.scrollLeft()
- if(top < -3)top = -3;
- if(top > this.offsetHeight - 3)top = this.offsetHeight - 3;
- if(left < -3)left = -3;
- if(left > this.offsetWidth - 3)left = this.offsetWidth - 3;
- var s = (left + 3)/260*100
- ,b = 100 - (top + 3)/180*100;
+ var top = e.clientY - $(this).offset().top + $win.scrollTop()
+ ,left = e.clientX - $(this).offset().left + $win.scrollLeft()
+ if(top < 0)top = 0;
+ if(top > this.offsetHeight)top = this.offsetHeight;
+ if(left < 0)left = 0;
+ if(left > this.offsetWidth)left = this.offsetWidth;
+ var s = left/260*100
+ ,b = 100 - top/180*100;
_b = b;
_s = s;
change(_h, s, b, _a);
layui.stope(e);
e.preventDefault();
- choose.trigger(e, 'mousedown');
+ needTrigger && choose.trigger('mousedown', e);
});
//底部透明度选择
- alphaslider.on('mousedown', function(e){
- var oldleft = this.offsetLeft
- ,oldx = e.clientX;
+ alphaslider.on('mousedown', function(e, triggerEvent){
+ var oldleft = this.offsetLeft;
+ var oldx = e.clientX === undefined ? triggerEvent.clientX : e.clientX;
var move = function(e){
var left = oldleft + (e.clientX - oldx)
,maxw = alphacolor[0].offsetWidth;
@@ -538,10 +543,11 @@ layui.define(['jquery', 'lay'], function(exports){
e.preventDefault();
};
+ needStopPropagation && layui.stope(e);
createMoveElem(move);
e.preventDefault();
});
- alphacolor.on('click', function(e){
+ alphacolor.on('mousedown', function(e){
var left = e.clientX - $(this).offset().left
if(left < 0)left = 0;
if(left > this.offsetWidth)left = this.offsetWidth;
@@ -549,6 +555,7 @@ layui.define(['jquery', 'lay'], function(exports){
_a = a;
change(_h, _s, _b, a);
e.preventDefault();
+ needTrigger && alphaslider.trigger('mousedown', e);
});
//预定义颜色选择
@@ -567,6 +574,41 @@ layui.define(['jquery', 'lay'], function(exports){
change(hsb.h, hsb.s, hsb.b, a);
})
});
+
+ if(!lay.touchEventsSupported()) return;
+ // 触摸事件模拟
+ layui.each([
+ {elem: side, eventType: 'mousedown'},
+ {elem: alphacolor, eventType: 'mousedown'},
+ {elem: basis, eventType: 'mousedown'}
+ ], function(i, obj){
+ lay.touchSwipe(obj.elem, {
+ onTouchStart: function(){
+ needTrigger = false;
+ needStopPropagation = false;
+ },
+ onTouchMove: function(e){
+ touchHandler(e, obj.eventType)
+ },
+ onTouchEnd: function(){
+ elemMove.remove();
+ needTrigger = true;
+ needStopPropagation = true;
+ }
+ })
+ })
+
+ function touchHandler(event, eventType) {
+ var pointer = event.touches[0];
+ var simulatedEvent = document.createEvent("MouseEvent");
+
+ simulatedEvent.initMouseEvent(eventType,
+ true, true, window, 1,
+ pointer.screenX, pointer.screenY,pointer.clientX, pointer.clientY,
+ false, false, false, false, 0, null
+ );
+ pointer.target.dispatchEvent(simulatedEvent);
+ }
};
//颜色选择器hsb转换
@@ -576,16 +618,17 @@ layui.define(['jquery', 'lay'], function(exports){
var hex = HSBToHEX({h:h, s:100, b:100});
var color = HSBToHEX({h:h, s:s, b:b});
var sidetop = h/360*180;
- var top = 180 - b/100*180 - 3;
- var left = s/100*260 - 3;
+ var top = 180 - b/100*180;
+ var left = s/100*260;
+ var basisElem = that.elemPicker.find('.' + PICKER_BASIS)[0];
that.elemPicker.find('.' + PICKER_SIDE_SLIDER).css("top", sidetop); //滑块的top
- that.elemPicker.find('.' + PICKER_BASIS)[0].style.background = '#' + hex; //颜色选择器的背景
+ basisElem.style.background = '#' + hex; //颜色选择器的背景
//选择器的top left
that.elemPicker.find('.' + PICKER_BASIS_CUR).css({
- "top": top
- ,"left": left
+ "top": top / basisElem.offsetHeight * 100 + '%',
+ "left": left / basisElem.offsetWidth * 100 + '%'
});
// if(type === 'change') return;
@@ -614,7 +657,7 @@ layui.define(['jquery', 'lay'], function(exports){
//确认
,confirm: function(othis, change){
- var value = elemPickerInput.val()
+ var value = $.trim(elemPickerInput.val())
,colorValue
,hsb;
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/dropdown.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/dropdown.js
index 3fff835..07831fe 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/modules/dropdown.js
+++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/dropdown.js
@@ -3,11 +3,12 @@
* 下拉菜单组件
*/
-layui.define(['jquery', 'laytpl', 'lay'], function(exports){
+layui.define(['jquery', 'laytpl', 'lay', 'util'], function(exports){
"use strict";
var $ = layui.$;
var laytpl = layui.laytpl;
+ var util = layui.util;
var hint = layui.hint();
var device = layui.device();
var clickOrMousedown = (device.mobile ? 'touchstart' : 'mousedown');
@@ -15,10 +16,17 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){
// 模块名
var MOD_NAME = 'dropdown';
var MOD_INDEX = 'layui_'+ MOD_NAME +'_index'; // 模块索引名
+ var MOD_ID = 'lay-' + MOD_NAME + '-id';
// 外部接口
var dropdown = {
- config: {},
+ config: {
+ customName: { // 自定义 data 字段名
+ id: 'id',
+ title: 'title',
+ children: 'child'
+ }
+ },
index: layui[MOD_NAME] ? (layui[MOD_NAME].index + 10000) : 0,
// 设置全局项
@@ -53,6 +61,9 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){
},
close: function () {
that.remove()
+ },
+ open: function () {
+ that.render()
}
}
};
@@ -94,8 +105,9 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){
isAllowSpread: true, // 是否允许菜单组展开收缩
isSpreadItem: true, // 是否初始展开子菜单
data: [], // 菜单数据结构
- delay: 300, // 延迟关闭的毫秒数,若 trigger 为 hover 时才生效
- shade: 0 // 遮罩
+ delay: [200, 300], // 延时显示或隐藏的毫秒数,若为 number 类型,则表示显示和隐藏的延迟时间相同,trigger 为 hover 时才生效
+ shade: 0, // 遮罩
+ accordion: false // 手风琴效果,仅菜单组生效。基础菜单需要在容器上追加 'lay-accordion' 属性。
};
// 重载实例
@@ -125,8 +137,8 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){
$.extend(options, lay.options(elem[0]));
// 若重复执行 render,则视为 reload 处理
- if(!rerender && elem[0] && elem.data(MOD_INDEX)){
- var newThat = thisModule.getThis(elem.data(MOD_INDEX));
+ if(!rerender && elem[0] && elem.attr(MOD_ID)){
+ var newThat = thisModule.getThis(elem.attr(MOD_ID));
if(!newThat) return;
return newThat.reload(options, type);
@@ -139,6 +151,11 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){
elem.attr('id') || that.index
);
+ elem.attr(MOD_ID, options.id);
+
+ // 初始化自定义字段名
+ options.customName = $.extend({}, dropdown.config.customName, options.customName);
+
if(options.show || (type === 'reloadData' && that.elemView && $('body').find(that.elemView.get(0)).length)) that.render(rerender, type); //初始即显示或者面板弹出之后执行了刷新数据
that.events(); // 事件
};
@@ -147,6 +164,7 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){
Class.prototype.render = function(rerender, type){
var that = this;
var options = that.config;
+ var customName = options.customName;
var elemBody = $('body');
// 默认菜单内容
@@ -155,7 +173,7 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){
if(options.data.length > 0 ){
eachItemView(elemUl, options.data)
} else {
- elemUl.html(' ');
+ elemUl.html('');
}
return elemUl;
};
@@ -163,9 +181,10 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){
// 遍历菜单项
var eachItemView = function(views, data){
// var views = [];
+
layui.each(data, function(index, item){
// 是否存在子级
- var isChild = item.child && item.child.length > 0;
+ var isChild = item[customName.children] && item[customName.children].length > 0;
var isSpreadItem = ('isSpreadItem' in item) ? item.isSpreadItem : options.isSpreadItem
var title = function(title){
var templet = item.templet || options.templet;
@@ -175,7 +194,7 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){
: laytpl(templet).render(item);
}
return title;
- }(item.title);
+ }(util.escape(item[customName.title]));
// 初始类型
var type = function(){
@@ -192,7 +211,7 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){
return '';
}();
- if(type !== '-' && (!item.title && !item.id && !isChild)) return;
+ if(type !== '-' && (!item[customName.title] && !item[customName.id] && !isChild)) return;
//列表元素
var viewLi = $(['
')
- ,elemUl = $('
');
+ var elemPanel = $('
');
+ var elemUl = $('
');
if(type === 'parent'){
- elemPanel.append(eachItemView(elemUl, item.child));
+ elemPanel.append(eachItemView(elemUl, item[customName.children]));
viewLi.append(elemPanel);
} else {
- viewLi.append(eachItemView(elemUl, item.child));
+ viewLi.append(eachItemView(elemUl, item[customName.children]));
}
}
@@ -256,7 +275,7 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){
};
// 主模板
- var TPL_MAIN = ['
'
+ var TPL_MAIN = ['
'
,'
'].join('');
// 如果是右键事件,则每次触发事件时,将允许重新渲染
@@ -266,7 +285,7 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){
if(!rerender && options.elem.data(MOD_INDEX +'_opened')) return;
// 记录模板对象
- that.elemView = $('.' + STR_ELEM + '[lay-id="' + options.id + '"]');
+ that.elemView = $('.' + STR_ELEM + '[' + MOD_ID + '="' + options.id + '"]');
if (type === 'reloadData' && that.elemView.length) {
that.elemView.html(options.content || getDefaultView());
} else {
@@ -313,7 +332,7 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){
that.elemView.find('.layui-menu li').on('click', function(e){
var othis = $(this);
var data = othis.data('item') || {};
- var isChild = data.child && data.child.length > 0;
+ var isChild = data[customName.children] && data[customName.children].length > 0;
var isClickAllScope = options.clickScope === 'all'; // 是否所有父子菜单均触发点击事件
if(data.disabled) return; // 菜单项禁用状态
@@ -331,12 +350,12 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){
// 触发菜单组展开收缩
that.elemView.find(STR_GROUP_TITLE).on('click', function(e){
- var othis = $(this)
- ,elemGroup = othis.parent()
- ,data = elemGroup.data('item') || {}
+ var othis = $(this);
+ var elemGroup = othis.parent();
+ var data = elemGroup.data('item') || {};
if(data.type === 'group' && options.isAllowSpread){
- thisModule.spread(elemGroup);
+ thisModule.spread(elemGroup, options.accordion);
}
});
@@ -364,17 +383,33 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){
Class.prototype.remove = function(){
var that = this;
var options = that.config;
- var elemPrev = thisModule.prevElem;
+ var prevContentElem = thisModule.prevElem;
// 若存在已打开的面板元素,则移除
- if(elemPrev){
- elemPrev.data('prevElem') && (
- elemPrev.data('prevElem').data(MOD_INDEX +'_opened', false)
- );
- elemPrev.remove();
+ if(prevContentElem){
+ var prevId = prevContentElem.attr(MOD_ID);
+ var prevTriggerElem = prevContentElem.data('prevElem');
+ var prevInstance = thisModule.getThis(prevId);
+ var prevOnClose = prevInstance.config.close;
+
+ prevTriggerElem && prevTriggerElem.data(MOD_INDEX +'_opened', false);
+ prevContentElem.remove();
+ delete thisModule.prevElem;
+ typeof prevOnClose === 'function' && prevOnClose.call(prevInstance.config, prevTriggerElem);
}
lay('.' + STR_ELEM_SHADE).remove();
};
+
+ Class.prototype.normalizedDelay = function(){
+ var that = this;
+ var options = that.config;
+ var delay = [].concat(options.delay);
+
+ return {
+ show: delay[0],
+ hide: delay[1] !== undefined ? delay[1] : delay[0]
+ }
+ }
// 延迟删除视图
Class.prototype.delayRemove = function(){
@@ -384,7 +419,7 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){
thisModule.timer = setTimeout(function(){
that.remove();
- }, options.delay);
+ }, that.normalizedDelay().hide);
};
// 事件
@@ -397,13 +432,23 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){
// 解除上一个事件
if(that.prevElem) that.prevElem.off(options.trigger, that.prevElemCallback);
+
+ // 是否鼠标移入时触发
+ var isMouseEnter = options.trigger === 'mouseenter';
// 记录被绑定的元素及回调
that.prevElem = options.elem;
that.prevElemCallback = function(e){
clearTimeout(thisModule.timer);
that.e = e;
- that.render();
+
+ // 若为鼠标移入事件,则延迟触发
+ isMouseEnter ? (
+ thisModule.timer = setTimeout(function(){
+ that.render();
+ }, that.normalizedDelay().show)
+ ) : that.render();
+
e.preventDefault();
};
@@ -411,8 +456,8 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){
options.elem.on(options.trigger, that.prevElemCallback);
// 如果是鼠标移入事件
- if(options.trigger === 'mouseenter'){
- // 直行鼠标移出事件
+ if (isMouseEnter) {
+ // 执行鼠标移出事件
options.elem.on('mouseleave', function(){
that.delayRemove();
});
@@ -430,16 +475,33 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){
};
// 设置菜单组展开和收缩状态
- thisModule.spread = function(othis){
- // 菜单组展开和收缩
+ thisModule.spread = function(othis, isAccordion){
+ var contentElem = othis.children('ul');
var needSpread = othis.hasClass(STR_ITEM_UP);
- var elemIcon = othis.children('.'+ STR_MENU_TITLE).find('.layui-icon-' + (needSpread ? 'down' : 'up'));
- if(needSpread){
+ var ANIM_MS = 200;
+
+ // 动画执行完成后的操作
+ var complete = function() {
+ $(this).css({'display': ''}); // 剔除临时 style,以适配外部样式的状态重置;
+ };
+
+ // 动画是否正在执行
+ if (contentElem.is(':animated')) return;
+
+ // 展开
+ if (needSpread) {
othis.removeClass(STR_ITEM_UP).addClass(STR_ITEM_DOWN);
- elemIcon.removeClass('layui-icon-down').addClass('layui-icon-up');
- } else {
+ contentElem.hide().stop().slideDown(ANIM_MS, complete);
+ } else { // 收缩
+ contentElem.stop().slideUp(ANIM_MS, complete);
othis.removeClass(STR_ITEM_DOWN).addClass(STR_ITEM_UP);
- elemIcon.removeClass('layui-icon-up').addClass('layui-icon-down');
+ }
+
+ // 手风琴
+ if (needSpread && isAccordion) {
+ var groupSibs = othis.siblings('.' + STR_ITEM_DOWN);
+ groupSibs.children('ul').stop().slideUp(ANIM_MS, complete);
+ groupSibs.removeClass(STR_ITEM_DOWN).addClass(STR_ITEM_UP);
}
};
@@ -454,7 +516,7 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){
var that = thisModule.getThis(dropdown.thisId);
if(!that) return;
- if(!that.elemView[0] || !$('.'+ STR_ELEM)[0]){
+ if((that.elemView && !that.elemView[0]) || !$('.'+ STR_ELEM)[0]){
return false;
}
@@ -523,9 +585,10 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){
var othis = $(this);
var elemGroup = othis.parents('.'+ STR_ITEM_GROUP +':eq(0)');
var options = lay.options(elemGroup[0]);
+ var isAccordion = typeof othis.parents('.layui-menu').eq(0).attr('lay-accordion') === 'string';
if(('isAllowSpread' in options) ? options.isAllowSpread : true){
- thisModule.spread(elemGroup);
+ thisModule.spread(elemGroup, isAccordion);
}
});
@@ -570,6 +633,15 @@ layui.define(['jquery', 'laytpl', 'lay'], function(exports){
that.remove();
return thisModule.call(that);
};
+
+ // 打开面板
+ dropdown.open = function(id){
+ var that = thisModule.getThis(id);
+ if(!that) return this;
+
+ that.render();
+ return thisModule.call(that);
+ }
// 重载实例
dropdown.reload = function(id, options, type){
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/element.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/element.js
index e3c210b..ddc9edd 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/modules/element.js
+++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/element.js
@@ -48,7 +48,7 @@ layui.define('jquery', function(exports){
}() +'>'+ (options.title || 'unnaming') +'';
barElem[0] ? barElem.before(li) : titElem.append(li);
- contElem.append('
'+ (options.content || '') +'
');
+ contElem.append('
'+ (options.content || '') +'
');
// call.hideTabMore(true);
// 是否添加即切换
options.change && this.tabChange(filter, options.id);
@@ -66,14 +66,21 @@ layui.define('jquery', function(exports){
return this;
};
- // 外部 Tab 切换
- Element.prototype.tabChange = function(filter, layid){
+ /**
+ * 外部 Tab 切换
+ * @param {string} filter - 标签主容器 lay-filter 值
+ * @param {string} layid - 标签头 lay-id 值
+ * @param {boolean} force - 是否强制切换
+ * @returns {this}
+ */
+ Element.prototype.tabChange = function(filter, layid, force){
var tabElem = $('.layui-tab[lay-filter='+ filter +']');
var titElem = tabElem.children(TITLE);
var liElem = titElem.find('>li[lay-id="'+ layid +'"]');
call.tabClick.call(liElem[0], {
- liElem: liElem
+ liElem: liElem,
+ force: force
});
return this;
};
@@ -82,7 +89,7 @@ layui.define('jquery', function(exports){
Element.prototype.tab = function(options){
options = options || {};
dom.on('click', options.headerElem, function(e){
- var index = $(this).index();
+ var index = $(options.headerElem).index($(this));
call.tabClick.call(this, {
index: index,
options: options
@@ -134,21 +141,46 @@ layui.define('jquery', function(exports){
var isJump = elemA.attr('href') !== 'javascript:;' && elemA.attr('target') === '_blank'; // 是否存在跳转
var unselect = typeof othis.attr('lay-unselect') === 'string'; // 是否禁用选中
var filter = parents.attr('lay-filter');
+ var hasId = othis.attr('lay-id');
// 下标
var index = 'index' in obj
? obj.index
: othis.parent().children('li').index(othis);
+
+ // 若非强制切换,则根据 tabBeforeChange 事件的返回结果决定是否切换
+ if (!obj.force) {
+ var liThis = othis.siblings('.' + THIS);
+ var shouldChange = layui.event.call(this, MOD_NAME, 'tabBeforeChange('+ filter +')', {
+ elem: parents,
+ from: {
+ index: othis.parent().children('li').index(liThis),
+ id: liThis.attr('lay-id')
+ },
+ to: {
+ index: index,
+ id: hasId
+ },
+ });
+ if(shouldChange === false) return;
+ }
// 执行切换
if(!(isJump || unselect)){
othis.addClass(THIS).siblings().removeClass(THIS);
- item.eq(index).addClass(SHOW).siblings().removeClass(SHOW);
+ if(hasId){
+ var contentElem = item.filter('[lay-id="' + hasId + '"]');
+ contentElem = contentElem.length ? contentElem : item.eq(index);
+ contentElem.addClass(SHOW).siblings().removeClass(SHOW);
+ }else{
+ item.eq(index).addClass(SHOW).siblings().removeClass(SHOW);
+ }
}
layui.event.call(this, MOD_NAME, 'tab('+ filter +')', {
elem: parents,
- index: index
+ index: index,
+ id: hasId
});
}
@@ -159,6 +191,14 @@ layui.define('jquery', function(exports){
var tabElem = li.closest('.layui-tab');
var item = tabElem.children('.layui-tab-content').children('.layui-tab-item');
var filter = tabElem.attr('lay-filter');
+ var hasId = li.attr('lay-id');
+
+ var shouldClose = layui.event.call(li[0], MOD_NAME, 'tabBeforeDelete('+ filter +')', {
+ elem: tabElem,
+ index: index,
+ id: hasId
+ });
+ if(shouldClose === false) return;
if(li.hasClass(THIS)){
if (li.next()[0] && li.next().is('li')){
@@ -171,14 +211,21 @@ layui.define('jquery', function(exports){
}
li.remove();
- item.eq(index).remove();
+ if(hasId){
+ var contentElem = item.filter('[lay-id="' + hasId + '"]');
+ contentElem = contentElem.length ? contentElem : item.eq(index)
+ contentElem.remove()
+ }else{
+ item.eq(index).remove();
+ }
setTimeout(function(){
call.tabAuto();
}, 50);
layui.event.call(this, MOD_NAME, 'tabDelete('+ filter +')', {
elem: tabElem,
- index: index
+ index: index,
+ id: hasId
});
}
@@ -202,10 +249,11 @@ layui.define('jquery', function(exports){
}
// 开启关闭图标
- if(othis.attr('lay-allowclose')){
+ var allowclose = othis.attr('lay-allowclose');
+ if(allowclose && allowclose !== 'false'){
title.find('li').each(function(){
var li = $(this);
- if(!li.find('.'+CLOSE)[0]){
+ if(!li.find('.'+CLOSE)[0] && li.attr('lay-allowclose') !== 'false'){
var close = $('
');
close.on('click', call.tabDelete);
li.append(close);
@@ -272,31 +320,63 @@ layui.define('jquery', function(exports){
)
*/
- //点击菜单 - a标签触发
- ,clickThis: function(){
- var othis = $(this)
- ,parents = othis.parents(NAV_ELEM)
- ,filter = parents.attr('lay-filter')
- ,parent = othis.parent()
- ,child = othis.siblings('.'+NAV_CHILD)
- ,unselect = typeof parent.attr('lay-unselect') === 'string'; //是否禁用选中
+ // 点击菜单 - a 标签触发
+ ,clickThis: function() {
+ var othis = $(this);
+ var parents = othis.closest(NAV_ELEM);
+ var filter = parents.attr('lay-filter');
+ var parent = othis.parent() ;
+ var child = othis.siblings('.'+ NAV_CHILD);
+ var unselect = typeof parent.attr('lay-unselect') === 'string'; // 是否禁用选中
- if(!(othis.attr('href') !== 'javascript:;' && othis.attr('target') === '_blank') && !unselect){
- if(!child[0]){
- parents.find('.'+THIS).removeClass(THIS);
+ // 满足点击选中的条件
+ if (!(othis.attr('href') !== 'javascript:;' && othis.attr('target') === '_blank') && !unselect) {
+ if (!child[0]) {
+ parents.find('.'+ THIS).removeClass(THIS);
parent.addClass(THIS);
}
}
- //如果是垂直菜单
- if(parents.hasClass(NAV_TREE)){
+ // 若为垂直菜单
+ if (parents.hasClass(NAV_TREE)) {
+ var NAV_ITEMED = NAV_ITEM + 'ed'; // 用于标注展开状态
+ var needExpand = !parent.hasClass(NAV_ITEMED); // 是否执行展开
+ var ANIM_MS = 200; // 动画过渡毫秒数
+
+ // 动画执行完成后的操作
+ var complete = function() {
+ $(this).css({
+ "display": "" // 剔除动画生成的 style display,以适配外部样式的状态重置
+ });
+ // 避免导航滑块错位
+ parents.children('.'+ NAV_BAR).css({
+ opacity: 0
+ })
+ };
+
+ // 是否正处于动画中的状态
+ if (child.is(':animated')) return;
+
+ // 剔除可能存在的 CSS3 动画类
child.removeClass(NAV_ANIM);
-
- //如果有子菜单,则展开
- if(child[0]){
- parent[child.css('display') === 'none' ? 'addClass': 'removeClass'](NAV_ITEM+'ed');
- if(parents.attr('lay-shrink') === 'all'){
- parent.siblings().removeClass(NAV_ITEM + 'ed');
+
+ // 若有子菜单,则对其执行展开或收缩
+ if (child[0]) {
+ if (needExpand) {
+ // 先执行 slideDown 动画,再标注展开状态样式,避免元素 `block` 状态导致动画无效
+ child.slideDown(ANIM_MS, complete);
+ parent.addClass(NAV_ITEMED);
+ } else {
+ // 先取消展开状态样式,再将元素临时显示,避免 `none` 状态导致 slideUp 动画无效
+ parent.removeClass(NAV_ITEMED);
+ child.show().slideUp(ANIM_MS, complete);
+ }
+
+ // 手风琴 --- 收缩兄弟展开项
+ if (typeof parents.attr('lay-accordion') === 'string' || parents.attr('lay-shrink') === 'all') {
+ var parentSibs = parent.siblings('.'+ NAV_ITEMED);
+ parentSibs.removeClass(NAV_ITEMED);
+ parentSibs.children('.'+ NAV_CHILD).show().stop().slideUp(ANIM_MS, complete);
}
}
}
@@ -304,26 +384,16 @@ layui.define('jquery', function(exports){
layui.event.call(this, MOD_NAME, 'nav('+ filter +')', othis);
}
- //点击子菜单选中
- /*
- ,clickChild: function(){
- var othis = $(this), parents = othis.parents(NAV_ELEM)
- ,filter = parents.attr('lay-filter');
- parents.find('.'+THIS).removeClass(THIS);
- othis.addClass(THIS);
- layui.event.call(this, MOD_NAME, 'nav('+ filter +')', othis);
- }
- */
-
- //折叠面板
+ // 折叠面板
,collapse: function(){
- var othis = $(this), icon = othis.find('.layui-colla-icon')
- ,elemCont = othis.siblings('.layui-colla-content')
- ,parents = othis.parents('.layui-collapse').eq(0)
- ,filter = parents.attr('lay-filter')
- ,isNone = elemCont.css('display') === 'none';
+ var othis = $(this);
+ var icon = othis.find('.layui-colla-icon');
+ var elemCont = othis.siblings('.layui-colla-content');
+ var parents = othis.parents('.layui-collapse').eq(0);
+ var filter = parents.attr('lay-filter');
+ var isNone = elemCont.css('display') === 'none';
- //是否手风琴
+ // 是否手风琴
if(typeof parents.attr('lay-accordion') === 'string'){
var show = parents.children('.layui-colla-item').children('.'+SHOW);
show.siblings('.layui-colla-title').children('.layui-colla-icon').html('');
@@ -352,56 +422,65 @@ layui.define('jquery', function(exports){
call.tabAuto.call({});
}
- //导航菜单
+ // 导航菜单
,nav: function(){
- var TIME = 200, timer = {}, timerMore = {}, timeEnd = {}, NAV_TITLE = 'layui-nav-title'
+ var TIME = 200;
+ var timer = {};
+ var timerMore = {};
+ var timeEnd = {};
+ var NAV_TITLE = 'layui-nav-title';
- //滑块跟随
- ,follow = function(bar, nav, index){
- var othis = $(this), child = othis.find('.'+NAV_CHILD);
- if(nav.hasClass(NAV_TREE)){
- //无子菜单时跟随
- if(!child[0]){
+ // 滑块跟随
+ var follow = function(bar, nav, index) {
+ var othis = $(this);
+ var child = othis.find('.'+NAV_CHILD);
+
+ // 是否垂直导航菜单
+ if (nav.hasClass(NAV_TREE)) {
+ // 无子菜单时跟随
+ if (!child[0]) {
var thisA = othis.children('.'+ NAV_TITLE);
bar.css({
- top: othis.offset().top - nav.offset().top
- ,height: (thisA[0] ? thisA : othis).outerHeight()
- ,opacity: 1
+ top: othis.offset().top - nav.offset().top,
+ height: (thisA[0] ? thisA : othis).outerHeight(),
+ opacity: 1
});
}
} else {
child.addClass(NAV_ANIM);
- //若居中对齐
- if(child.hasClass(NAV_CHILD_C)) child.css({
- left: -(child.outerWidth() - othis.width())/2
- });
-
- //滑块定位
- if(child[0]){ //若有子菜单,则滑块消失
- bar.css({
- left: bar.position().left + bar.width()/2
- ,width: 0
- ,opacity: 0
- });
- } else { //bar 跟随
- bar.css({
- left: othis.position().left + parseFloat(othis.css('marginLeft'))
- ,top: othis.position().top + othis.height() - bar.height()
+ // 若居中对齐
+ if (child.hasClass(NAV_CHILD_C)) {
+ child.css({
+ left: -(child.outerWidth() - othis.width()) / 2
});
}
- //渐显滑块并适配宽度
- timer[index] = setTimeout(function(){
+ // 滑块定位
+ if (child[0]) { // 若有子菜单,则滑块消失
bar.css({
- width: child[0] ? 0 : othis.width()
- ,opacity: child[0] ? 0 : 1
+ left: bar.position().left + bar.width() / 2,
+ width: 0,
+ opacity: 0
+ });
+ } else { // bar 跟随
+ bar.css({
+ left: othis.position().left + parseFloat(othis.css('marginLeft')),
+ top: othis.position().top + othis.height() - bar.height()
+ });
+ }
+
+ // 渐显滑块并适配宽度
+ timer[index] = setTimeout(function() {
+ bar.css({
+ width: child[0] ? 0 : othis.width(),
+ opacity: child[0] ? 0 : 1
});
}, device.ie && device.ie < 10 ? 0 : TIME);
- //显示子菜单
+ // 显示子菜单
clearTimeout(timeEnd[index]);
- if(child.css('display') === 'block'){
+ if (child.css('display') === 'block') {
clearTimeout(timerMore[index]);
}
timerMore[index] = setTimeout(function(){
@@ -411,61 +490,64 @@ layui.define('jquery', function(exports){
}
};
- //遍历导航
- $(NAV_ELEM + elemFilter).each(function(index){
- var othis = $(this)
- ,bar = $('
')
- ,itemElem = othis.find('.'+NAV_ITEM);
+ // 遍历导航
+ $(NAV_ELEM + elemFilter).each(function(index) {
+ var othis = $(this);
+ var bar = $('
');
+ var itemElem = othis.find('.'+NAV_ITEM);
- //hover 滑动效果
- if(!othis.find('.'+NAV_BAR)[0]){
+ // hover 滑动效果
+ if (!othis.find('.'+NAV_BAR)[0]) {
othis.append(bar);
- (othis.hasClass(NAV_TREE)
+ ( othis.hasClass(NAV_TREE)
? itemElem.find('dd,>.'+ NAV_TITLE)
- : itemElem).on('mouseenter', function(){
+ : itemElem
+ ).on('mouseenter', function() {
follow.call(this, bar, othis, index);
- }).on('mouseleave', function(){ //鼠标移出
- //是否为垂直导航
- if(othis.hasClass(NAV_TREE)){
+ }).on('mouseleave', function() { // 鼠标移出
+ // 是否为垂直导航
+ if (othis.hasClass(NAV_TREE)) {
bar.css({
- height: 0
- ,opacity: 0
+ height: 0,
+ opacity: 0
});
} else {
- //隐藏子菜单
+ // 隐藏子菜单
clearTimeout(timerMore[index]);
timerMore[index] = setTimeout(function(){
- othis.find('.'+NAV_CHILD).removeClass(SHOW);
- othis.find('.'+NAV_MORE).removeClass(NAV_MORE+'d');
+ othis.find('.'+ NAV_CHILD).removeClass(SHOW);
+ othis.find('.'+ NAV_MORE).removeClass(NAV_MORE +'d');
}, 300);
}
});
- othis.on('mouseleave', function(){
+
+ // 鼠标离开当前菜单时
+ othis.on('mouseleave', function() {
clearTimeout(timer[index])
- timeEnd[index] = setTimeout(function(){
- if(!othis.hasClass(NAV_TREE)){
+ timeEnd[index] = setTimeout(function() {
+ if (!othis.hasClass(NAV_TREE)) {
bar.css({
- width: 0
- ,left: bar.position().left + bar.width()/2
- ,opacity: 0
+ width: 0,
+ left: bar.position().left + bar.width() / 2,
+ opacity: 0
});
}
}, TIME);
});
}
- //展开子菜单
- itemElem.find('a').each(function(){
- var thisA = $(this)
- ,parent = thisA.parent()
- ,child = thisA.siblings('.'+NAV_CHILD);
+ // 展开子菜单
+ itemElem.find('a').each(function() {
+ var thisA = $(this);
+ var parent = thisA.parent();
+ var child = thisA.siblings('.'+ NAV_CHILD);
- //输出小箭头
- if(child[0] && !thisA.children('.'+NAV_MORE)[0]){
+ // 输出小箭头
+ if (child[0] && !thisA.children('.'+ NAV_MORE)[0]) {
thisA.append('
');
}
- thisA.off('click', call.clickThis).on('click', call.clickThis); //点击菜单
+ thisA.off('click', call.clickThis).on('click', call.clickThis); // 点击菜单
});
});
}
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/flow.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/flow.js
index bb4a4bc..6128e27 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/modules/flow.js
+++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/flow.js
@@ -1,11 +1,11 @@
/**
- * flow 流加载组件
+ * flow 流加载组件
*/
-
-
+
+
layui.define('jquery', function(exports){
"use strict";
-
+
var $ = layui.$, Flow = function(options){}
,ELEM_MORE = 'layui-flow-more'
,ELEM_LOAD = '
';
@@ -14,97 +14,118 @@ layui.define('jquery', function(exports){
Flow.prototype.load = function(options){
var that = this, page = 0, lock, isOver, lazyimg, timer;
options = options || {};
-
+
var elem = $(options.elem); if(!elem[0]) return;
- var scrollElem = $(options.scrollElem || document); //滚动条所在元素
- var mb = options.mb || 50; //与底部的临界距离
- var isAuto = 'isAuto' in options ? options.isAuto : true; //是否自动滚动加载
- var end = options.end || '没有更多了'; //“末页”显示文案
-
+ var scrollElem = $(options.scrollElem || document); // 滚动条所在元素
+ var threshold = 'mb' in options ? options.mb : 50; // 临界距离
+ var isAuto = 'isAuto' in options ? options.isAuto : true; // 否自动滚动加载
+ var moreText = options.moreText || "加载更多"; // 手动加载时,加载更多按钮文案
+ var end = options.end || '没有更多了'; // “末页”显示文案
+ var direction = options.direction || 'bottom';
+ var isTop = direction === 'top';
+
+ // 重复执行时清理旧的事件绑定
+ that._cleanup(elem, scrollElem);
+
//滚动条所在元素是否为document
var notDocument = options.scrollElem && options.scrollElem !== document;
-
+
//加载更多
- var ELEM_TEXT = '
加载更多 '
+ var ELEM_TEXT = '
' + moreText + ' '
,more = $('
');
-
+
if(!elem.find('.layui-flow-more')[0]){
- elem.append(more);
+ elem[isTop ? 'prepend' : 'append'](more);
}
-
+
//加载下一个元素
- var next = function(html, over){
+ var next = function(html, over){
+ var scrollHeightStart = notDocument ? scrollElem.prop('scrollHeight') : document.documentElement.scrollHeight;
+ var scrollTopStart = scrollElem.scrollTop();
html = $(html);
- more.before(html);
+ more[isTop ? 'after' : 'before'](html);
over = over == 0 ? true : null;
over ? more.html(end) : more.find('a').html(ELEM_TEXT);
isOver = over;
lock = null;
lazyimg && lazyimg();
+ if(isTop){
+ var scrollHeightEnd = notDocument ? scrollElem.prop('scrollHeight') : document.documentElement.scrollHeight;
+ if(page === 1){
+ // 首次渲染后滑动到底部
+ scrollElem.scrollTop(scrollHeightEnd);
+ }else if(page > 1){
+ var nextElementHeight = scrollHeightEnd - scrollHeightStart;
+ scrollElem.scrollTop(scrollTopStart + nextElementHeight);
+ }
+ }
};
-
+
//触发请求
var done = function(){
lock = true;
more.find('a').html(ELEM_LOAD);
typeof options.done === 'function' && options.done(++page, next);
};
-
+
done();
-
+
//不自动滚动加载
- more.find('a').on('click', function(){
+ more.find('a').on('click.flow', function(){
var othis = $(this);
if(isOver) return;
lock || done();
});
-
+
//如果允许图片懒加载
if(options.isLazyimg){
- var lazyimg = that.lazyimg({
+ lazyimg = that.lazyimg({
elem: options.elem + ' img'
,scrollElem: options.scrollElem
+ ,direction: options.direction
});
}
-
+
if(!isAuto) return that;
-
- scrollElem.on('scroll', function(){
+
+ scrollElem.on('scroll.flow', function(){
var othis = $(this), top = othis.scrollTop();
-
+
if(timer) clearTimeout(timer);
if(isOver || !elem.width()) return; //如果已经结束,或者元素处于隐藏状态,则不执行滚动加载
-
+
timer = setTimeout(function(){
//计算滚动所在容器的可视高度
var height = notDocument ? othis.height() : $(window).height();
-
+
//计算滚动所在容器的实际高度
var scrollHeight = notDocument
? othis.prop('scrollHeight')
: document.documentElement.scrollHeight;
//临界点
- if(scrollHeight - top - height <= mb){
+ if(!isTop ? scrollHeight - top - height <= threshold : top <= threshold){
lock || done();
}
}, 100);
});
-
+
return that;
};
-
+
//图片懒加载
Flow.prototype.lazyimg = function(options){
var that = this, index = 0, haveScroll;
options = options || {};
-
+
var scrollElem = $(options.scrollElem || document); //滚动条所在元素
var elem = options.elem || 'img';
-
+ var direction = options.direction || 'bottom';
+ var isTop = direction === 'top';
+
//滚动条所在元素是否为document
var notDocument = options.scrollElem && options.scrollElem !== document;
-
+
//显示图片
var show = function(item, height){
var start = scrollElem.scrollTop(), end = start + height;
@@ -113,13 +134,13 @@ layui.define('jquery', function(exports){
}() : item.offset().top;
/* 始终只加载在当前屏范围内的图片 */
- if(elemTop >= start && elemTop <= end){
+ if((isTop ? elemTop + item.height() : elemTop) >= start && elemTop <= end){
if(item.attr('lay-src')){
var src = item.attr('lay-src');
layui.img(src, function(){
var next = that.lazyimg.elem.eq(index);
item.attr('src', src).removeAttr('lay-src');
-
+
/* 当前图片加载就绪后,检测下一个图片是否在当前屏 */
next[0] && render(next);
index++;
@@ -130,7 +151,7 @@ layui.define('jquery', function(exports){
}
}
}, render = function(othis, scroll){
-
+
//计算滚动所在容器的可视高度
var height = notDocument ? (scroll||scrollElem).height() : $(window).height();
var start = scrollElem.scrollTop(), end = start + height;
@@ -145,32 +166,39 @@ layui.define('jquery', function(exports){
var item = that.lazyimg.elem.eq(i), elemTop = notDocument ? function(){
return item.offset().top - scrollElem.offset().top + start;
}() : item.offset().top;
-
+
show(item, height);
index = i;
-
+
//如果图片的top坐标,超出了当前屏,则终止后续图片的遍历
if(elemTop > end) break;
}
}
};
-
+
render();
-
+
if(!haveScroll){
var timer;
- scrollElem.on('scroll', function(){
+ scrollElem.on('scroll.lazyimg' , function(){
var othis = $(this);
if(timer) clearTimeout(timer)
timer = setTimeout(function(){
render(null, othis);
}, 50);
- });
+ });
haveScroll = true;
}
return render;
};
-
+
+ // 重复执行时清理旧的事件绑定,私有方法
+ Flow.prototype._cleanup = function(elem, scrollElem){
+ scrollElem.off('scroll.flow').off('scroll.lazyimg');
+ elem.find('.layui-flow-more').find('a').off('click.flow');
+ elem.html('');
+ }
+
//暴露接口
exports('flow', new Flow());
});
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/form.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/form.js
index 538d73c..b8a0813 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/modules/form.js
+++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/form.js
@@ -1,1066 +1,1310 @@
/**
* form 表单组件
*/
-
-layui.define(['lay', 'layer', 'util'], function(exports){
- "use strict";
-
- var $ = layui.$;
- var layer = layui.layer;
- var util = layui.util;
- var hint = layui.hint();
- var device = layui.device();
-
- var MOD_NAME = 'form', ELEM = '.layui-form', THIS = 'layui-this';
- var SHOW = 'layui-show', HIDE = 'layui-hide', DISABLED = 'layui-disabled';
-
- var Form = function(){
- this.config = {
- // 内置的验证规则
- verify: {
- required: [
- /[\S]+/,
- '必填项不能为空'
- ],
- phone: [
- /^1\d{10}$/,
- '请输入正确的手机号'
- ],
- email: [
- /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/,
- '邮箱格式不正确'
- ],
- url: [
- /^(#|(http(s?)):\/\/|\/\/)[^\s]+\.[^\s]+$/,
- '链接格式不正确'
- ],
- number: function(value){
- if(isNaN(value)) return '只能填写数字';
- },
- date: [
- /^(\d{4})[-\/](\d{1}|0\d{1}|1[0-2])([-\/](\d{1}|0\d{1}|[1-2][0-9]|3[0-1]))*$/,
- '日期格式不正确'
- ],
- identity: [
- /(^\d{15}$)|(^\d{17}(x|X|\d)$)/,
- '请输入正确的身份证号'
- ],
- integer: [/^\d*$/
- , "只能填写整数"],
- pass: [
- /^[\S]{6,12}$/
- , '密码必须6到12位,且不能出现空格'
- ],
- ip: [
- /(^$)|^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/
- , 'IP地址不符合规则'
- ]
- },
- verIncludeRequired: false, // 验证规则是否包含必填 --- 为兼容旧版的验证机制
- autocomplete: null // 全局 autocomplete 状态。 null 表示不干预
+
+layui.define(['lay', 'layer', 'util'], function (exports) {
+ "use strict";
+
+ var $ = layui.$;
+ var layer = layui.layer;
+ var util = layui.util;
+ var hint = layui.hint();
+ var device = layui.device();
+
+ var MOD_NAME = 'form';
+ var ELEM = '.layui-form';
+ var THIS = 'layui-this';
+ var SHOW = 'layui-show';
+ var HIDE = 'layui-hide';
+ var DISABLED = 'layui-disabled';
+ var OUT_OF_RANGE = 'layui-input-number-out-of-range';
+
+ var Form = function () {
+ this.config = {
+ // 内置的验证规则
+ verify: {
+ required: function (value) {
+ if (!/[\S]+/.test(value)) {
+ return '必填项不能为空';
+ }
+ },
+ phone: function (value) {
+ var EXP = /^1\d{10}$/;
+ if (value && !EXP.test(value)) {
+ return '手机号格式不正确';
+ }
+ },
+ email: function (value) {
+ var EXP = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
+ if (value && !EXP.test(value)) {
+ return '邮箱格式不正确';
+ }
+ },
+ url: function (value) {
+ var EXP = /^(#|(http(s?)):\/\/|\/\/)[^\s]+\.[^\s]+$/;
+ if (value && !EXP.test(value)) {
+ return '链接格式不正确';
+ }
+ },
+ number: function (value) {
+ if (value && isNaN(value)) {
+ return '只能填写数字';
+ }
+ },
+ date: function (value) {
+ var EXP = /^(\d{4})[-\/](\d{1}|0\d{1}|1[0-2])([-\/](\d{1}|0\d{1}|[1-2][0-9]|3[0-1]))*$/;
+ if (value && !EXP.test(value)) {
+ return '日期格式不正确';
+ }
+ },
+ identity: function (value) {
+ var EXP = /(^\d{15}$)|(^\d{17}(x|X|\d)$)/;
+ if (value && !EXP.test(value)) {
+ return '身份证号格式不正确';
+ }
+ },
+ integer: function (value) {
+ var EXP = /^\d*$/;
+ if (value && !EXP.test(value)) {
+ return '只能填写整数';
+ }
+ }
+ },
+ autocomplete: null // 全局 autocomplete 状态。 null 表示不干预
+ };
};
- };
-
- // 全局设置
- Form.prototype.set = function(options){
- var that = this;
- $.extend(true, that.config, options);
- return that;
- };
-
- // 验证规则设定
- Form.prototype.verify = function(settings){
- var that = this;
- $.extend(true, that.config.verify, settings);
- return that;
- };
- // 获取指定表单对象
- Form.prototype.getFormElem = function(filter){
- return $(ELEM + function(){
- return filter ? ('[lay-filter="' + filter +'"]') : '';
- }());
- };
-
- // 表单事件
- Form.prototype.on = function(events, callback){
- return layui.onevent.call(this, MOD_NAME, events, callback);
- };
-
- // 赋值/取值
- Form.prototype.val = function(filter, object){
- var that = this
- ,formElem = that.getFormElem(filter);
-
- // 遍历
- formElem.each(function(index, item){
- var itemForm = $(this);
-
- // 赋值
- layui.each(object, function(key, value){
- var itemElem = itemForm.find('[name="'+ key +'"]')
- ,type;
-
- // 如果对应的表单不存在,则不执行
- if(!itemElem[0]) return;
- type = itemElem[0].type;
-
- // 如果为复选框
- if(type === 'checkbox'){
- itemElem[0].checked = value;
- } else if(type === 'radio') { // 如果为单选框
- itemElem.each(function(){
- this.checked = this.value == value;
- });
- } else { // 其它类型的表单
- itemElem.val(value);
- }
- });
- });
-
- form.render(null, filter);
-
- // 返回值
- return that.getValue(filter);
- };
-
- // 取值
- Form.prototype.getValue = function(filter, itemForm){
- itemForm = itemForm || this.getFormElem(filter);
-
- var nameIndex = {} // 数组 name 索引
- ,field = {}
- ,fieldElem = itemForm.find('input,select,textarea') // 获取所有表单域
-
- layui.each(fieldElem, function(_, item){
- var othis = $(this)
- ,init_name; // 初始 name
-
- item.name = (item.name || '').replace(/^\s*|\s*&/, '');
- if(!item.name) return;
-
- // 用于支持数组 name
- if(/^.*\[\]$/.test(item.name)){
- var key = item.name.match(/^(.*)\[\]$/g)[0];
- nameIndex[key] = nameIndex[key] | 0;
- init_name = item.name.replace(/^(.*)\[\]$/, '$1['+ (nameIndex[key]++) +']');
- }
-
- if(/^(checkbox|radio)$/.test(item.type) && !item.checked) return; // 复选框和单选框未选中,不记录字段
- field[init_name || item.name] = item.value;
- });
-
- return field;
- };
-
- // 表单控件渲染
- Form.prototype.render = function(type, filter){
- var that = this;
- var options = that.config;
- var elemForm = $(ELEM + function(){
- return filter ? ('[lay-filter="' + filter +'"]') : '';
- }());
- var items = {
- // 输入框
- input: function(elem){
- var inputs = elem || elemForm.find('input,textarea');
+ // 全局设置
+ Form.prototype.set = function (options) {
+ var that = this;
+ $.extend(true, that.config, options);
+ return that;
+ };
- // 初始化全局的 autocomplete
- options.autocomplete && inputs.attr('autocomplete', options.autocomplete);
+ // 验证规则设定
+ Form.prototype.verify = function (settings) {
+ var that = this;
+ $.extend(true, that.config.verify, settings);
+ return that;
+ };
- // 初始化输入框动态点缀
- elemForm.find('input[lay-affix],textarea[lay-affix]').each(function(){
- var othis = $(this);
- var affix = othis.attr('lay-affix');
- var CLASS_WRAP = 'layui-input-wrap';
- var CLASS_SUFFIX = 'layui-input-suffix';
- var CLASS_AFFIX = 'layui-input-affix';
- var disabled = othis.is('[disabled]') || othis.is('[readonly]');
+ // 获取指定表单对象
+ Form.prototype.getFormElem = function (filter) {
+ return $(ELEM + function () {
+ return filter ? ('[lay-filter="' + filter + '"]') : '';
+ }());
+ };
- // 根据是否空值来显示或隐藏元素
- var showAffix = function(elem, value){
- elem = $(elem);
- if(!elem[0]) return;
- elem[$.trim(value) ? 'removeClass' : 'addClass'](HIDE);
- };
+ // 表单事件
+ Form.prototype.on = function (events, callback) {
+ return layui.onevent.call(this, MOD_NAME, events, callback);
+ };
- // 渲染动态点缀内容
- var renderAffix = function(opts){
- opts = $.extend({}, (affixOptions[affix] || {
- value: affix
- }), opts, lay.options(othis[0]));
- var elemAffix = $('
');
- var value = layui.isArray(opts.value) ? opts.value : [opts.value];
- var elemIcon = $(function(){
- var arr = [];
- layui.each(value, function(i, item){
- arr.push('
');
- });
- return arr.join('');
- }());
-
- elemAffix.append(elemIcon); // 插入图标元素
+ // 赋值/取值
+ Form.prototype.val = function (filter, object) {
+ var that = this
+ , formElem = that.getFormElem(filter);
- // 追加 className
- if(opts.split) elemAffix.addClass('layui-input-split');
- if(opts.className) elemAffix.addClass(opts.className);
+ // 遍历
+ formElem.each(function (index, item) {
+ var itemForm = $(this);
- // 移除旧的元素
- var hasElemAffix = othis.next('.'+ CLASS_AFFIX);
- if(hasElemAffix[0]) hasElemAffix.remove();
+ // 赋值
+ layui.each(object, function (key, value) {
+ var itemElem = itemForm.find('[name="' + key + '"]')
+ , type;
- // 是否在规定的容器中
- if(!othis.parent().hasClass(CLASS_WRAP)){
- othis.wrap('
');
+ // 如果对应的表单不存在,则不执行
+ if (!itemElem[0]) return;
+ type = itemElem[0].type;
+
+ // 如果为复选框
+ if (type === 'checkbox') {
+ itemElem[0].checked = value;
+ } else if (type === 'radio') { // 如果为单选框
+ itemElem.each(function () {
+ this.checked = this.value == value + '';
+ });
+ } else { // 其它类型的表单
+ itemElem.val(value);
+ }
+ });
+ });
+
+ form.render(null, filter);
+
+ // 返回值
+ return that.getValue(filter);
+ };
+
+ // 取值
+ Form.prototype.getValue = function (filter, itemForm) {
+ itemForm = itemForm || this.getFormElem(filter);
+
+ var nameIndex = {} // 数组 name 索引
+ , field = {}
+ , fieldElem = itemForm.find('input,select,textarea') // 获取所有表单域
+
+ layui.each(fieldElem, function (_, item) {
+ var othis = $(this)
+ , init_name; // 初始 name
+
+ item.name = (item.name || '').replace(/^\s*|\s*&/, '');
+ if (!item.name) return;
+
+ // 用于支持数组 name
+ if (/^.*\[\]$/.test(item.name)) {
+ var key = item.name.match(/^(.*)\[\]$/g)[0];
+ nameIndex[key] = nameIndex[key] | 0;
+ init_name = item.name.replace(/^(.*)\[\]$/, '$1[' + (nameIndex[key]++) + ']');
}
- // 是否已经存在后缀元素
- var hasElemSuffix = othis.next('.'+ CLASS_SUFFIX);
- if(hasElemSuffix[0]){
- hasElemAffix = hasElemSuffix.find('.'+ CLASS_AFFIX);
- if(hasElemAffix[0]) hasElemAffix.remove();
+ if (/^(checkbox|radio)$/.test(item.type) && !item.checked) return; // 复选框和单选框未选中,不记录字段
+ field[init_name || item.name] = item.value;
+ });
- hasElemSuffix.prepend(elemAffix);
+ return field;
+ };
- othis.css('padding-right', function(){
- var paddingRight = othis.closest('.layui-input-group')[0]
- ? 0
- : hasElemSuffix.outerWidth();
- return paddingRight + elemAffix.outerWidth()
- });
- } else {
- elemAffix.addClass(CLASS_SUFFIX);
- othis.after(elemAffix);
- }
+ // 表单控件渲染
+ Form.prototype.render = function (type, filter) {
+ var that = this;
+ var options = that.config;
+ var elemForm = $(ELEM + function () {
+ return filter ? ('[lay-filter="' + filter + '"]') : '';
+ }());
+ var items = {
+ // 输入框
+ input: function (elem) {
+ var inputs = elem || elemForm.find('input,textarea');
- opts.show === 'auto' && showAffix(elemAffix, othis.val());
-
- // 输入事件
- othis.on('input propertychange', function(){
- var value = this.value;
- opts.show === 'auto' && showAffix(elemAffix, value);
- });
-
- // 点击动态后缀事件
- elemIcon.on('click', function(){
- var inputFilter = othis.attr('lay-filter');
- if($(this).hasClass(DISABLED)) return;
-
- typeof opts.click === 'function' && opts.click.call(this, othis, opts);
-
- // 对外事件
- layui.event.call(this, MOD_NAME, 'input-affix('+ inputFilter +')', {
- elem: othis[0],
- affix: affix,
- options: opts
- });
- });
- };
-
- // 动态点缀配置项
- var affixOptions = {
- eye: { // 密码显隐
- value: 'eye-invisible',
- click: function(elem, opts){ // 事件
- var SHOW_NAME = 'LAY_FORM_INPUT_AFFIX_SHOW';
- var isShow = elem.data(SHOW_NAME);
-
- elem.attr('type', isShow ? 'password' : 'text').data(SHOW_NAME, !isShow);
+ // 初始化全局的 autocomplete
+ options.autocomplete && inputs.attr('autocomplete', options.autocomplete);
- renderAffix({
- value: isShow ? 'eye-invisible' : 'eye'
+ var handleInputNumber = function (elem, eventType) {
+ var that = this;
+ var rawValue = elem.val();
+ var value = Number(rawValue);
+ var step = Number(elem.attr('step')) || 1; // 加减的数字间隔
+ var min = Number(elem.attr('min'));
+ var max = Number(elem.attr('max'));
+ var precision = Number(elem.attr('lay-precision'));
+ var noAction = eventType !== 'click' && rawValue === ''; // 初始渲染和失焦时空值不作处理
+ var isInit = eventType === 'init';
+
+ if (isNaN(value)) return; // 若非数字,则不作处理
+
+ if (eventType === 'click') {
+ var isDecrement = !!$(that).index() // 0: icon-up, 1: icon-down
+ value = isDecrement ? value - step : value + step;
+ }
+
+ // 获取小数点后位数
+ var decimals = function (step) {
+ var decimals = (step.toString().match(/\.(\d+$)/) || [])[1] || '';
+ return decimals.length;
+ };
+
+ precision = precision >= 0 ? precision : Math.max(decimals(step), decimals(rawValue));
+
+ // 赋值
+ if (!noAction) {
+ // 初始渲染时只处理数字精度
+ if (!isInit) {
+ if (value <= min) value = min;
+ if (value >= max) value = max;
+ }
+ // 若 `lay-precision` 为 0, 则表示只保留整数
+ if (precision === 0) {
+ value = parseInt(value);
+ } else if (precision > 0) { // 小数位精度
+ value = value.toFixed(precision);
+ }
+ elem.val(value);
+ }
+
+ // 超出范围的样式
+ var outOfRange = value < min || value > max;
+ elem[outOfRange && !noAction ? 'addClass' : 'removeClass'](OUT_OF_RANGE);
+
+ if (isInit) return;
+
+ // 更新按钮状态
+ var controlBtn = {
+ increment: elem.next().find('.layui-icon-up'),
+ decrement: elem.next().find('.layui-icon-down')
+ }
+ controlBtn.increment[(value >= max && !noAction) ? 'addClass' : 'removeClass'](DISABLED)
+ controlBtn.decrement[(value <= min && !noAction) ? 'addClass' : 'removeClass'](DISABLED)
+ }
+
+ // 初始化输入框动态点缀
+ elemForm.find('input[lay-affix],textarea[lay-affix]').each(function () {
+ var othis = $(this);
+ var affix = othis.attr('lay-affix');
+ var CLASS_WRAP = 'layui-input-wrap';
+ var CLASS_SUFFIX = 'layui-input-suffix';
+ var CLASS_AFFIX = 'layui-input-affix';
+ var disabled = othis.is('[disabled]') || othis.is('[readonly]');
+
+ // 根据是否空值来显示或隐藏元素
+ var showAffix = function (elem, value) {
+ elem = $(elem);
+ if (!elem[0]) return;
+ elem[$.trim(value) ? 'removeClass' : 'addClass'](HIDE);
+ };
+
+ // 渲染动态点缀内容
+ var renderAffix = function (opts) {
+ opts = $.extend({}, (affixOptions[affix] || {
+ value: affix
+ }), opts, lay.options(othis[0]));
+ var elemAffix = $('
');
+ var value = layui.isArray(opts.value) ? opts.value : [opts.value];
+ var elemIcon = $(function () {
+ var arr = [];
+ layui.each(value, function (i, item) {
+ arr.push('
');
+ });
+ return arr.join('');
+ }());
+
+ elemAffix.append(elemIcon); // 插入图标元素
+
+ // 追加 className
+ if (opts.split) elemAffix.addClass('layui-input-split');
+ if (opts.className) elemAffix.addClass(opts.className);
+
+ // 移除旧的元素
+ var hasElemAffix = othis.next('.' + CLASS_AFFIX);
+ if (hasElemAffix[0]) hasElemAffix.remove();
+
+ // 是否在规定的容器中
+ if (!othis.parent().hasClass(CLASS_WRAP)) {
+ othis.wrap('
');
+ }
+
+ // 是否已经存在后缀元素
+ var hasElemSuffix = othis.next('.' + CLASS_SUFFIX);
+ if (hasElemSuffix[0]) {
+ hasElemAffix = hasElemSuffix.find('.' + CLASS_AFFIX);
+ if (hasElemAffix[0]) hasElemAffix.remove();
+
+ hasElemSuffix.prepend(elemAffix);
+
+ othis.css('padding-right', function () {
+ var paddingRight = othis.closest('.layui-input-group')[0]
+ ? 0
+ : hasElemSuffix.outerWidth();
+ return paddingRight + elemAffix.outerWidth()
+ });
+ } else {
+ elemAffix.addClass(CLASS_SUFFIX);
+ othis.after(elemAffix);
+ }
+
+ opts.show === 'auto' && showAffix(elemAffix, othis.val());
+
+ typeof opts.init === 'function' && opts.init.call(this, othis, opts);
+
+ // 输入事件
+ othis.on('input propertychange', function () {
+ var value = this.value;
+ opts.show === 'auto' && showAffix(elemAffix, value);
+ });
+
+ // 失去焦点事件
+ othis.on('blur', function () {
+ typeof opts.blur === 'function' && opts.blur.call(this, othis, opts);
+ });
+
+ // 点击动态后缀事件
+ elemIcon.on('click', function () {
+ var inputFilter = othis.attr('lay-filter');
+ if ($(this).hasClass(DISABLED)) return;
+
+ typeof opts.click === 'function' && opts.click.call(this, othis, opts);
+
+ // 对外事件
+ layui.event.call(this, MOD_NAME, 'input-affix(' + inputFilter + ')', {
+ elem: othis[0],
+ affix: affix,
+ options: opts
+ });
+ });
+ };
+
+ // 动态点缀配置项
+ var affixOptions = {
+ eye: { // 密码显隐
+ value: 'eye-invisible',
+ click: function (elem, opts) { // 事件
+ var SHOW_NAME = 'LAY_FORM_INPUT_AFFIX_SHOW';
+ var isShow = elem.data(SHOW_NAME);
+
+ elem.attr('type', isShow ? 'password' : 'text').data(SHOW_NAME, !isShow);
+
+ renderAffix({
+ value: isShow ? 'eye-invisible' : 'eye'
+ });
+ }
+ },
+ clear: { // 内容清除
+ value: 'clear',
+ click: function (elem) {
+ elem.val('').focus();
+ showAffix($(this).parent(), null);
+ },
+ show: 'auto', // 根据输入框值是否存在来显示或隐藏点缀图标
+ disabled: disabled // 跟随输入框禁用状态
+ },
+ number: { // 数字输入框
+ value: ['up', 'down'],
+ split: true,
+ className: 'layui-input-number',
+ disabled: othis.is('[disabled]'), // 跟随输入框禁用状态
+ init: function (elem) {
+ handleInputNumber.call(this, elem, 'init')
+ },
+ click: function (elem) {
+ handleInputNumber.call(this, elem, 'click')
+ },
+ blur: function (elem) {
+ handleInputNumber.call(this, elem, 'blur')
+ },
+ }
+ };
+
+ renderAffix();
});
- }
- },
- clear: { // 内容清除
- value: 'clear',
- click: function(elem){
- elem.val('').focus();
- showAffix($(this).parent(), null);
- },
- show: 'auto', // 根据输入框值是否存在来显示或隐藏点缀图标
- disabled: disabled // 跟随输入框禁用状态
- },
- number: { // 数字输入框
- value: ['up', 'down'],
- split: true,
- className: 'layui-input-number',
- disabled: othis.is('[disabled]'), // 跟随输入框禁用状态
- click: function(elem){
- var index = $(this).index();
- var value = elem.val();
- var rawValue = value;
- var step = Number(elem.attr('step')) || 1; // 加减的数字间隔
- var min = Number(elem.attr('min'));
- var max = Number(elem.attr('max'));
+ }
- if(isNaN(value)) return; // 若非数字,则不作处理
+ // 下拉选择框
+ , select: function (elem) {
+ var TIPS = '请选择';
+ var CLASS = 'layui-form-select';
+ var TITLE = 'layui-select-title';
+ var NONE = 'layui-select-none';
+ var CREATE_OPTION = 'layui-select-create-option';
+ var PANEL_WRAP = 'layui-select-panel-wrap'
+ var PANEL_ELEM_DATA = 'layui-select-panel-elem-data';
+ var selects = elem || elemForm.find('select');
- value = Number(value);
- value = index ? value - step : value + step;
+ // 各种事件
+ var events = function (reElem, titleElem, disabled, isSearch, isCreatable, isAppendTo) {
+ var select = $(this);
+ var title = titleElem;
+ var input = title.find('input');
+ var dl = reElem.find('dl');
+ var dds = dl.children('dd');
+ var dts = dl.children('dt'); // select 分组dt元素
+ var index = this.selectedIndex; // 当前选中的索引
+ var initValue = '';
+ var removeClickOutsideEvent;
- // min max
- if(value < min) value = min;
- if(value > max) value = max;
+ if (disabled) return;
- // 获取小数点后位数
- var decimals = function(step){
- var decimals = (step.toString().match(/\.(\d+$)/) || [])[1] || '';
- return decimals.length;
+ /**
+ * 搜索项
+ * @typedef searchOption
+ * @prop {boolean} [caseSensitive=false] 是否区分大小写
+ * @prop {boolean} [fuzzy=false] 是否开启模糊匹配,开启后将会忽略模式出现在字符串中的位置。
+ */
+ /** @type {searchOption} */
+ var laySearch = select.attr('lay-search') === 'cs' ? { caseSensitive: true } : lay.options(select, { attr: 'lay-search' });
+ // 目前只支持 body
+ var appendTarget = select.attr('lay-append-to') || 'body';
+ var appendPosition = select.attr('lay-append-position');
+
+ // #1449
+ // IE10 和 11 中,带有占位符的 input 元素获得/失去焦点时,会触发 input 事件
+ // 当鼠标按下时,根据 input 元素上的 __ieph 标识忽略 input 事件
+ var needPlaceholderPatch = !!(lay.ie && (lay.ie === '10' || lay.ie === '11') && input.attr('placeholder'));
+
+ // 展开下拉
+ var showDown = function () {
+ if (isAppendTo) {
+ // 如果追加面板元素后出现滚动条,触发元素宽度可能会有变化,所以先追加面板元素
+ reElem.appendTo(appendTarget).css({ width: title.width() + 'px' });
+
+ var updatePosition = function () {
+ lay.position(title[0], reElem[0], {
+ position: appendPosition,
+ allowBottomOut: true,
+ offset: [0, 5]
+ });
+ }
+
+ updatePosition();
+ $(window).on('resize.lay_select_resize', updatePosition);
+ }
+ var top = reElem.offset().top + reElem.outerHeight() + 5 - $win.scrollTop();
+ var dlHeight = dl.outerHeight();
+ var dds = dl.children('dd');
+
+ index = select[0].selectedIndex; // 获取最新的 selectedIndex
+ title.parent().addClass(CLASS + 'ed');
+ dds.removeClass(HIDE);
+ dts.removeClass(HIDE);
+
+ // 初始选中样式
+ dds.removeClass(THIS);
+ index >= 0 && dds.eq(index).addClass(THIS);
+
+ // 上下定位识别
+ if (top + dlHeight > $win.height() && top >= dlHeight) {
+ reElem.addClass(CLASS + 'up');
+ }
+
+ followScroll();
+
+ if (needPlaceholderPatch) {
+ dl.off('mousedown.lay_select_ieph').on('mousedown.lay_select_ieph', function () {
+ input[0].__ieph = true;
+ setTimeout(function () {
+ input[0].__ieph = false;
+ }, 60)
+ });
+ }
+
+ removeClickOutsideEvent = lay.onClickOutside(
+ isAppendTo ? reElem[0] : dl[0],
+ function () {
+ hideDown();
+ initValue && input.val(initValue);
+ },
+ { ignore: title }
+ );
+ };
+
+ // 隐藏下拉
+ var hideDown = function (choose) {
+ title.parent().removeClass(CLASS + 'ed ' + CLASS + 'up');
+ input.blur();
+ isCreatable && dl.children('.' + CREATE_OPTION).remove();
+ removeClickOutsideEvent && removeClickOutsideEvent();
+ if (isAppendTo) {
+ reElem.detach();
+ $(window).off('resize.lay_select_resize');
+ }
+
+ if (choose) return;
+
+ notOption(input.val(), function (none) {
+ var selectedIndex = select[0].selectedIndex;
+
+ // 未查询到相关值
+ if (none) {
+ initValue = $(select[0].options[selectedIndex]).html(); // 重新获得初始选中值
+
+ // 如果是第一项,且文本值等于 placeholder,则清空初始值
+ if (selectedIndex === 0 && initValue === input.attr('placeholder')) {
+ initValue = '';
+ }
+
+ // 如果有选中值,则将输入框纠正为该值。否则清空输入框
+ input.val(initValue || '');
+ }
+ });
+ };
+
+ // 定位下拉滚动条
+ var followScroll = function () {
+ var thisDd = dl.children('dd.' + THIS);
+
+ if (!thisDd[0]) return;
+
+ var posTop = thisDd.position().top;
+ var dlHeight = dl.height();
+ var ddHeight = thisDd.height();
+
+ // 若选中元素在滚动条不可见底部
+ if (posTop > dlHeight) {
+ dl.scrollTop(posTop + dl.scrollTop() - dlHeight + ddHeight - 5);
+ }
+
+ // 若选择元素在滚动条不可见顶部
+ if (posTop < 0) {
+ dl.scrollTop(posTop + dl.scrollTop() - 5);
+ }
+ };
+
+ // 点击标题区域
+ title.on('click', function (e) {
+ title.parent().hasClass(CLASS + 'ed') ? (
+ hideDown()
+ ) : (
+ showDown()
+ );
+ dl.find('.' + NONE).remove();
+ });
+
+ // 点击箭头获取焦点
+ title.find('.layui-edge').on('click', function () {
+ input.focus();
+ });
+
+ // select 中 input 键盘事件
+ input.on('keyup', function (e) { // 键盘松开
+ var keyCode = e.keyCode;
+
+ // Tab键展开
+ if (keyCode === 9) {
+ showDown();
+ }
+ }).on('keydown', function (e) { // 键盘按下
+ var keyCode = e.keyCode;
+
+ // Tab键隐藏
+ if (keyCode === 9) {
+ hideDown();
+ }
+
+ // 标注 dd 的选中状态
+ var setThisDd = function (prevNext) {
+ e.preventDefault();
+ var allDisplayedElem = dl.children('dd:not(.' + HIDE + ',.' + DISABLED + ')');
+ if (!allDisplayedElem.length) return;
+ var firstIndex = 0;
+ var lastIndex = allDisplayedElem.length - 1;
+ var selectedIndex = -1;
+
+ layui.each(allDisplayedElem, function (index, el) {
+ if ($(el).hasClass(THIS)) {
+ selectedIndex = index;
+ return true;
+ }
+ })
+
+ var nextIndex = prevNext === 'prev'
+ ? (selectedIndex - 1 < firstIndex ? lastIndex : selectedIndex - 1)
+ : (selectedIndex + 1 > lastIndex ? firstIndex : selectedIndex + 1)
+
+ var selectedElem = allDisplayedElem.eq(nextIndex);
+ selectedElem.addClass(THIS).siblings().removeClass(THIS); // 标注样式
+ followScroll(); // 定位滚动条
+ };
+
+ if (keyCode === 38) setThisDd('prev'); // Up 键
+ if (keyCode === 40) setThisDd('next'); // Down 键
+
+ // Enter 键
+ if (keyCode === 13) {
+ e.preventDefault();
+ dl.children('dd.' + THIS).trigger('click');
+ }
+ }).on('paste', function () {
+ showDown();
+ });
+
+ // 检测值是否不属于 select 项
+ var notOption = function (value, callback, origin) {
+ var num = 0;
+ var dds = dl.children('dd');
+ var hasEquals = false;
+ var rawValue = value;
+ var fuzzyMatchRE;
+ if (!laySearch.caseSensitive) {
+ value = value.toLowerCase();
+ }
+ if (laySearch.fuzzy) {
+ fuzzyMatchRE = fuzzyMatchRegExp(value, laySearch.caseSensitive);
+ }
+ layui.each(dds, function () {
+ var othis = $(this);
+ var text = othis.text();
+ var isCreateOption = isCreatable && othis.hasClass(CREATE_OPTION);
+
+ // 需要区分大小写
+ if (isCreatable && !isCreateOption && text === rawValue) {
+ hasEquals = true;
+ }
+
+ // 是否区分大小写
+ if (!laySearch.caseSensitive) {
+ text = text.toLowerCase();
+ }
+
+ // 匹配
+ var not = laySearch.fuzzy ? !fuzzyMatchRE.test(text) : text.indexOf(value) === -1;
+
+ if (value === '' || (origin === 'blur') ? value !== text : not) num++;
+ origin === 'keyup' && othis[(isCreatable ? (not && !isCreateOption) : not) ? 'addClass' : 'removeClass'](HIDE);
+ });
+ // 处理 select 分组元素
+ origin === 'keyup' && layui.each(dts, function () {
+ var othis = $(this);
+ var thisDds = othis.nextUntil('dt').filter('dd'); // 当前分组下的dd元素
+ if (isCreatable) thisDds = thisDds.not('.' + CREATE_OPTION);
+ var allHide = thisDds.length == thisDds.filter('.' + HIDE).length; // 当前分组下所有dd元素都隐藏了
+ othis[allHide ? 'addClass' : 'removeClass'](HIDE);
+ });
+ var none = num === dds.length;
+ return callback(none, hasEquals), none;
+ };
+
+ // 搜索匹配
+ var search = function (e) {
+ var value = this.value, keyCode = e.keyCode;
+
+ if (keyCode === 9 || keyCode === 13
+ || keyCode === 37 || keyCode === 38
+ || keyCode === 39 || keyCode === 40
+ ) {
+ return false;
+ }
+
+ if (needPlaceholderPatch && e.target.__ieph) {
+ e.target.__ieph = false;
+ return false;
+ }
+
+ notOption(value, function (none, hasEquals) {
+ if (isCreatable) {
+ if (hasEquals) {
+ dl.children('.' + CREATE_OPTION).remove();
+ } else {
+ var createOptionElem = dl.children('.' + CREATE_OPTION);
+ if (createOptionElem[0]) {
+ createOptionElem.attr('lay-value', value).html(util.escape(value));
+ } else {
+ // 临时显示在顶部
+ var ddElem = $('
').addClass(CREATE_OPTION).attr('lay-value', value).html(util.escape(value));
+ var firstOptionELem = dl.children().eq(0);
+ var hasTips = firstOptionELem.hasClass('layui-select-tips');
+ firstOptionELem[hasTips ? 'after' : 'before'](ddElem);
+ }
+ }
+ } else {
+ if (none) {
+ dl.find('.' + NONE)[0] || dl.append('无匹配项
');
+ } else {
+ dl.find('.' + NONE).remove();
+ }
+ }
+ }, 'keyup');
+
+ // 当搜索值清空时
+ if (value === '') {
+ // 取消选中项
+ select.val('');
+ dl.find('.' + THIS).removeClass(THIS);
+ (select[0].options[0] || {}).value || dl.children('dd:eq(0)').addClass(THIS);
+ dl.find('.' + NONE).remove();
+ isCreatable && dl.children('.' + CREATE_OPTION).remove();
+ }
+
+ followScroll(); // 定位滚动条
+ };
+
+ if (isSearch) {
+ input.on('input propertychange', layui.debounce(search, 50)).on('blur', function (e) {
+ var selectedIndex = select[0].selectedIndex;
+
+ initValue = $(select[0].options[selectedIndex]).text(); // 重新获得初始选中值
+
+ // 如果是第一项,且文本值等于 placeholder,则清空初始值
+ if (selectedIndex === 0 && initValue === input.attr('placeholder')) {
+ initValue = '';
+ }
+
+ setTimeout(function () {
+ notOption(input.val(), function (none) {
+ initValue || input.val(''); // none && !initValue
+ }, 'blur');
+ }, 200);
+ });
+ }
+
+ // 选择
+ dl.on('click', 'dd', function () {
+ var othis = $(this), value = othis.attr('lay-value');
+ var filter = select.attr('lay-filter'); // 获取过滤器
+
+ if (othis.hasClass(DISABLED)) return false;
+
+ if (othis.hasClass('layui-select-tips')) {
+ input.val('');
+ } else {
+ input.val(othis.text());
+ othis.addClass(THIS);
+ }
+
+ // 将新增的 option 元素添加到末尾
+ if (isCreatable && othis.hasClass(CREATE_OPTION)) {
+ dl.append(othis.removeClass(CREATE_OPTION));
+ var optionElem = $('').attr('value', value).text(othis.text());
+ select.append(optionElem);
+ }
+
+ othis.siblings().removeClass(THIS);
+ select.val(value).removeClass('layui-form-danger');
+
+ layui.event.call(this, MOD_NAME, 'select(' + filter + ')', {
+ elem: select[0]
+ , value: value
+ , othis: reElem
+ });
+
+ hideDown(true);
+ return false;
+ });
+
+ reElem.find('dl>dt').on('click', function (e) {
+ return false;
+ });
+
+ if (isAppendTo) {
+ titleElem.on('_lay-select-destroy', function () {
+ reElem.remove();
+ })
+ }
+ }
+
+ // 仅 appendTo 使用,移除触发元素时,自动移除面板元素
+ $.event.special['_lay-select-destroy'] = {
+ remove: function (handleObj) {
+ handleObj.handler();
+ }
};
- // 位数比较
- var fixed = Math.max(decimals(step), decimals(rawValue));
+ // 初始渲染 select 组件选项
+ selects.each(function (index, select) {
+ var othis = $(this);
+ var hasRender = othis.next('.' + CLASS);
+ var disabled = this.disabled;
+ var value = select.value;
+ var selected = $(select.options[select.selectedIndex]); // 获取当前选中项
+ var optionsFirst = select.options[0];
- if(fixed) value = value.toFixed(fixed);
+ if (typeof othis.attr('lay-ignore') === 'string') return othis.show();
- elem.val(value);
- }
+ var isSearch = typeof othis.attr('lay-search') === 'string'
+ var isCreatable = typeof othis.attr('lay-creatable') === 'string' && isSearch
+ var isAppendTo = typeof othis.attr('lay-append-to') === 'string'
+ var placeholder = optionsFirst
+ ? (optionsFirst.value ? TIPS : (optionsFirst.innerHTML || TIPS))
+ : TIPS;
+
+ // 替代元素
+ var reElem = $(['
'].join(''));
+
+ var triggerElem = $([
+ ''
+ , (' ') // 禁用状态
+ , ' '
+ , '
'].join(''));
+
+ var contentElem = $([''
+ , function (options) {
+ var arr = [];
+ layui.each(options, function (index, item) {
+ var tagName = item.tagName.toLowerCase();
+
+ if (index === 0 && !item.value && tagName !== 'optgroup') {
+ arr.push('' + $.trim(item.innerHTML || TIPS) + ' ');
+ } else if (tagName === 'optgroup') {
+ arr.push('' + item.label + ' ');
+ } else {
+ arr.push('' + $.trim(item.innerHTML) + ' ');
+ }
+ });
+ arr.length === 0 && arr.push('没有选项 ');
+ return arr.join('');
+ }(othis.find('*')) + ' '
+ ].join(''));
+
+ // 如果已经渲染,则Rerender
+ if (hasRender[0]) {
+ if (isAppendTo) {
+ var panelWrapElem = hasRender.data(PANEL_ELEM_DATA);
+ panelWrapElem && panelWrapElem.remove();
+ }
+ hasRender.remove();
+ }
+ if (isAppendTo) {
+ reElem.append(triggerElem);
+ othis.after(reElem);
+ var contentWrapElem = $('
').append(contentElem);
+ reElem.data(PANEL_ELEM_DATA, contentWrapElem); // 将面板元素对象记录在触发元素 data 中,重新渲染时需要清理旧面板元素
+ events.call(this, contentWrapElem, triggerElem, disabled, isSearch, isCreatable, isAppendTo);
+ } else {
+ reElem.append(triggerElem).append(contentElem);
+ othis.after(reElem);
+ events.call(this, reElem, triggerElem, disabled, isSearch, isCreatable, isAppendTo);
+ }
+ });
}
- };
-
- renderAffix();
- });
- }
-
- // 下拉选择框
- ,select: function(elem){
- var TIPS = '请选择';
- var CLASS = 'layui-form-select';
- var TITLE = 'layui-select-title';
- var NONE = 'layui-select-none';
- var initValue = '';
- var thatInput;
- var selects = elem || elemForm.find('select');
- // 隐藏 select
- var hide = function(e, clear){
- if(!$(e.target).parent().hasClass(TITLE) || clear){
- $('.'+CLASS).removeClass(CLASS+'ed ' + CLASS+'up');
- thatInput && initValue && thatInput.val(initValue);
- }
- thatInput = null;
+ // 复选框/开关
+ , checkbox: function (elem) {
+ var CLASS = {
+ "checkbox": ['layui-form-checkbox', 'layui-form-checked', 'checkbox'],
+ "switch": ['layui-form-switch', 'layui-form-onswitch', 'switch'],
+ SUBTRA: 'layui-icon-indeterminate'
+ };
+ var checks = elem || elemForm.find('input[type=checkbox]');
+ // 风格
+ var skins = {
+ "primary": true, // 默认风格
+ "tag": true, // 标签风格
+ "switch": true // 开关风格
+ };
+ // 事件
+ var events = function (reElem, RE_CLASS) {
+ var check = $(this);
+ var skin = check.attr('lay-skin') || 'primary';
+ var isSwitch = skin === 'switch';
+ var isPrimary = skin === 'primary';
+
+ // 勾选
+ reElem.on('click', function () {
+ var filter = check.attr('lay-filter') // 获取过滤器
+
+ // 禁用
+ if (check[0].disabled) return;
+
+ // 半选
+ if (check[0].indeterminate) {
+ check[0].indeterminate = false;
+ }
+
+ // 开关
+ check[0].checked = !check[0].checked
+
+ // 事件
+ layui.event.call(check[0], MOD_NAME, RE_CLASS[2] + '(' + filter + ')', {
+ elem: check[0],
+ value: check[0].value,
+ othis: reElem
+ });
+ });
+
+ that.syncAppearanceOnPropChanged(this, 'checked', function () {
+ if (isSwitch) {
+ var title = (reElem.next('*[lay-checkbox]')[0]
+ ? reElem.next().html()
+ : check.attr('title') || ''
+ ).split('|');
+ reElem.children('div').html(this.checked ? title[0] : title[1] || title[0]);
+ }
+ reElem.toggleClass(RE_CLASS[1], this.checked);
+ });
+
+ if (isPrimary) {
+ that.syncAppearanceOnPropChanged(this, 'indeterminate', function () {
+ if (this.indeterminate) {
+ reElem.children('.layui-icon-ok').removeClass('layui-icon-ok').addClass(CLASS.SUBTRA);
+ } else {
+ reElem.children('.' + CLASS.SUBTRA).removeClass(CLASS.SUBTRA).addClass('layui-icon-ok');
+ }
+ })
+ }
+ };
+
+ // 遍历复选框
+ checks.each(function (index, check) {
+ var othis = $(this);
+ var skin = othis.attr('lay-skin') || 'primary';
+ var title = util.escape($.trim(check.title || function () { // 向下兼容 lay-text 属性
+ return check.title = othis.attr('lay-text') || '';
+ }()));
+ var disabled = this.disabled;
+
+ // if(!skins[skin]) skin = 'primary'; // 若非内置风格,则强制为默认风格
+ var RE_CLASS = CLASS[skin] || CLASS.checkbox;
+
+ // 替代元素
+ var hasRender = othis.next('.' + RE_CLASS[0]);
+ hasRender[0] && hasRender.remove(); // 若已经渲染,则 Rerender
+
+ // 若存在标题模板,则优先读取标题模板
+ var titleTplAttrs = [];
+ if (othis.next('[lay-checkbox]')[0]) {
+ var titleTplElem = othis.next();
+ title = titleTplElem.html() || '';
+ if (titleTplElem[0].attributes.length > 1) {
+ layui.each(titleTplElem[0].attributes, function (i, attr) {
+ if (attr.name !== 'lay-checkbox') {
+ titleTplAttrs.push(attr.name + '="' + attr.value + '"')
+ }
+ })
+ }
+ }
+ titleTplAttrs = titleTplAttrs.join(' ');
+
+ // 若为开关,则对 title 进行分隔解析
+ title = skin === 'switch' ? title.split('|') : [title];
+
+ if (typeof othis.attr('lay-ignore') === 'string') return othis.show();
+
+ // 替代元素
+ var reElem = $(['',
+ function () { // 不同风格的内容
+ var type = {
+ // 复选框
+ "checkbox": [
+ (title[0] ? ('
' + title[0] + '
') : (skin === 'primary' ? '' : '
')),
+ '
'
+ ].join(''),
+ // 开关
+ "switch": '
' + ((check.checked ? title[0] : (title[1] || title[0])) || '') + '
'
+ };
+ return type[skin] || type['checkbox'];
+ }(),
+ '
'].join(''));
+
+ othis.after(reElem);
+ events.call(this, reElem, RE_CLASS);
+ });
+ }
+
+ // 单选框
+ , radio: function (elem) {
+ var CLASS = 'layui-form-radio';
+ var ICON = ['layui-icon-radio', 'layui-icon-circle'];
+ var radios = elem || elemForm.find('input[type=radio]');
+
+ // 事件
+ var events = function (reElem) {
+ var radio = $(this);
+ var ANIM = 'layui-anim-scaleSpring';
+
+ reElem.on('click', function () {
+ var filter = radio.attr('lay-filter'); // 获取过滤器
+
+ if (radio[0].disabled) return;
+
+ radio[0].checked = true;
+
+ layui.event.call(radio[0], MOD_NAME, 'radio(' + filter + ')', {
+ elem: radio[0],
+ value: radio[0].value,
+ othis: reElem
+ });
+ });
+
+ that.syncAppearanceOnPropChanged(this, 'checked', function () {
+ var radioEl = this;
+ if (radioEl.checked) {
+ reElem.addClass(CLASS + 'ed');
+ reElem.children('.layui-icon').addClass(ANIM + ' ' + ICON[0]);
+ var forms = radio.parents(ELEM);
+ var sameRadios = forms.find('input[name=' + radioEl.name.replace(/(\.|#|\[|\])/g, '\\$1') + ']'); // 找到相同name的兄弟
+ layui.each(sameRadios, function () {
+ if (radioEl === this) return;
+ this.checked = false;
+ });
+ } else {
+ reElem.removeClass(CLASS + 'ed');
+ reElem.children('.layui-icon').removeClass(ANIM + ' ' + ICON[0]).addClass(ICON[1]);
+ }
+ })
+ };
+
+ // 初始渲染
+ radios.each(function (index, radio) {
+ var othis = $(this), hasRender = othis.next('.' + CLASS);
+ var disabled = this.disabled;
+ var skin = othis.attr('lay-skin');
+
+ if (typeof othis.attr('lay-ignore') === 'string') return othis.show();
+ hasRender[0] && hasRender.remove(); // 如果已经渲染,则Rerender
+
+ var title = util.escape(radio.title || '');
+ var titleTplAttrs = [];
+ if (othis.next('[lay-radio]')[0]) {
+ var titleTplElem = othis.next();
+ title = titleTplElem.html() || '';
+ if (titleTplElem[0].attributes.length > 1) {
+ layui.each(titleTplElem[0].attributes, function (i, attr) {
+ if (attr.name !== 'lay-radio') {
+ titleTplAttrs.push(attr.name + '="' + attr.value + '"')
+ }
+ })
+ }
+ }
+ titleTplAttrs = titleTplAttrs.join(' ');
+
+ // 替代元素
+ var reElem = $(['',
+ '
',
+ '
' + title + '
',
+ '
'].join(''));
+
+ othis.after(reElem);
+ events.call(this, reElem);
+ });
+ }
};
-
- // 各种事件
- var events = function(reElem, disabled, isSearch){
- var select = $(this);
- var title = reElem.find('.' + TITLE);
- var input = title.find('input');
- var dl = reElem.find('dl');
- var dds = dl.children('dd');
- var dts = dl.children('dt'); // select 分组dt元素
- var index = this.selectedIndex; // 当前选中的索引
- var nearElem; // select 组件当前选中的附近元素,用于辅助快捷键功能
-
- if(disabled) return;
- // 搜索项
- var laySearch = select.attr('lay-search');
-
- // 展开下拉
- var showDown = function(){
- var top = reElem.offset().top + reElem.outerHeight() + 5 - $win.scrollTop();
- var dlHeight = dl.outerHeight();
-
- index = select[0].selectedIndex; // 获取最新的 selectedIndex
- reElem.addClass(CLASS+'ed');
- dds.removeClass(HIDE);
- dts.removeClass(HIDE);
- nearElem = null;
-
- // 初始选中样式
- dds.removeClass(THIS);
- index >= 0 && dds.eq(index).addClass(THIS);
-
- // 上下定位识别
- if(top + dlHeight > $win.height() && top >= dlHeight){
- reElem.addClass(CLASS + 'up');
- }
-
- followScroll();
- };
-
- // 隐藏下拉
- var hideDown = function(choose){
- reElem.removeClass(CLASS+'ed ' + CLASS+'up');
- input.blur();
- nearElem = null;
-
- if(choose) return;
-
- notOption(input.val(), function(none){
- var selectedIndex = select[0].selectedIndex;
-
- // 未查询到相关值
- if(none){
- initValue = $(select[0].options[selectedIndex]).html(); // 重新获得初始选中值
-
- // 如果是第一项,且文本值等于 placeholder,则清空初始值
- if(selectedIndex === 0 && initValue === input.attr('placeholder')){
- initValue = '';
- }
-
- // 如果有选中值,则将输入框纠正为该值。否则清空输入框
- input.val(initValue || '');
- }
+ // 执行所有渲染项
+ var renderItem = function () {
+ layui.each(items, function (index, item) {
+ item();
});
- };
-
- // 定位下拉滚动条
- var followScroll = function(){
- var thisDd = dl.children('dd.'+ THIS);
-
- if(!thisDd[0]) return;
-
- var posTop = thisDd.position().top;
- var dlHeight = dl.height();
- var ddHeight = thisDd.height();
-
- // 若选中元素在滚动条不可见底部
- if(posTop > dlHeight){
- dl.scrollTop(posTop + dl.scrollTop() - dlHeight + ddHeight - 5);
+ };
+
+ // jquery 对象
+ if (layui.type(type) === 'object') {
+ // 若对象为表单域容器
+ if ($(type).is(ELEM)) {
+ elemForm = $(type);
+ renderItem();
+ } else { // 对象为表单项
+ type.each(function (index, item) {
+ var elem = $(item);
+ if (!elem.closest(ELEM).length) {
+ return; // 若不在 layui-form 容器中直接跳过
+ }
+ if (item.tagName === 'SELECT') {
+ items['select'](elem);
+ } else if (item.tagName === 'INPUT') {
+ var itemType = item.type;
+ if (itemType === 'checkbox' || itemType === 'radio') {
+ items[itemType](elem);
+ } else {
+ items['input'](elem);
+ }
+ }
+ });
}
-
- // 若选择玄素在滚动条不可见顶部
- if(posTop < 0){
- dl.scrollTop(posTop + dl.scrollTop() - 5);
- }
- };
-
- // 点击标题区域
- title.on('click', function(e){
- reElem.hasClass(CLASS+'ed') ? (
- hideDown()
- ) : (
- hide(e, true),
- showDown()
- );
- dl.find('.'+NONE).remove();
- });
-
- // 点击箭头获取焦点
- title.find('.layui-edge').on('click', function(){
- input.focus();
- });
-
- // select 中 input 键盘事件
- input.on('keyup', function(e){ // 键盘松开
- var keyCode = e.keyCode;
-
- // Tab键展开
- if(keyCode === 9){
- showDown();
- }
- }).on('keydown', function(e){ // 键盘按下
- var keyCode = e.keyCode;
-
- // Tab键隐藏
- if(keyCode === 9){
- hideDown();
- }
-
- // 标注 dd 的选中状态
- var setThisDd = function(prevNext, thisElem1){
- var nearDd, cacheNearElem
- e.preventDefault();
-
- // 得到当前队列元素
- var thisElem = function(){
- var thisDd = dl.children('dd.'+ THIS);
-
- // 如果是搜索状态,且按 Down 键,且当前可视 dd 元素在选中元素之前,
- // 则将当前可视 dd 元素的上一个元素作为虚拟的当前选中元素,以保证递归不中断
- if(dl.children('dd.'+ HIDE)[0] && prevNext === 'next'){
- var showDd = dl.children('dd:not(.'+ HIDE +',.'+ DISABLED +')')
- ,firstIndex = showDd.eq(0).index();
- if(firstIndex >=0 && firstIndex < thisDd.index() && !showDd.hasClass(THIS)){
- return showDd.eq(0).prev()[0] ? showDd.eq(0).prev() : dl.children(':last');
- }
- }
-
- if(thisElem1 && thisElem1[0]){
- return thisElem1;
- }
- if(nearElem && nearElem[0]){
- return nearElem;
- }
-
- return thisDd;
- // return dds.eq(index);
- }();
-
- cacheNearElem = thisElem[prevNext](); // 当前元素的附近元素
- nearDd = thisElem[prevNext]('dd:not(.'+ HIDE +')'); // 当前可视元素的 dd 元素
-
- // 如果附近的元素不存在,则停止执行,并清空 nearElem
- if(!cacheNearElem[0]) return nearElem = null;
-
- // 记录附近的元素,让其成为下一个当前元素
- nearElem = thisElem[prevNext]();
-
- // 如果附近不是 dd ,或者附近的 dd 元素是禁用状态,则进入递归查找
- if((!nearDd[0] || nearDd.hasClass(DISABLED)) && nearElem[0]){
- return setThisDd(prevNext, nearElem);
- }
-
- nearDd.addClass(THIS).siblings().removeClass(THIS); // 标注样式
- followScroll(); // 定位滚动条
- };
-
- if(keyCode === 38) setThisDd('prev'); // Up 键
- if(keyCode === 40) setThisDd('next'); // Down 键
-
- // Enter 键
- if(keyCode === 13){
- e.preventDefault();
- dl.children('dd.'+THIS).trigger('click');
- }
- });
-
- // 检测值是否不属于 select 项
- var notOption = function(value, callback, origin){
- var num = 0;
- layui.each(dds, function(){
- var othis = $(this);
- var text = othis.text();
-
- // 是否区分大小写
- if(laySearch !== 'cs'){
- text = text.toLowerCase();
- value = value.toLowerCase();
- }
-
- // 匹配
- var not = text.indexOf(value) === -1;
-
- if(value === '' || (origin === 'blur') ? value !== text : not) num++;
- origin === 'keyup' && othis[not ? 'addClass' : 'removeClass'](HIDE);
- });
- // 处理 select 分组元素
- origin === 'keyup' && layui.each(dts, function(){
- var othis = $(this)
- ,thisDds = othis.nextUntil('dt').filter('dd') // 当前分组下的dd元素
- ,allHide = thisDds.length == thisDds.filter('.' + HIDE).length; // 当前分组下所有dd元素都隐藏了
- othis[allHide ? 'addClass' : 'removeClass'](HIDE);
- });
- var none = num === dds.length;
- return callback(none), none;
- };
-
- // 搜索匹配
- var search = function(e){
- var value = this.value, keyCode = e.keyCode;
-
- if(keyCode === 9 || keyCode === 13
- || keyCode === 37 || keyCode === 38
- || keyCode === 39 || keyCode === 40
- ){
- return false;
- }
-
- notOption(value, function(none){
- if(none){
- dl.find('.'+NONE)[0] || dl.append('无匹配项
');
- } else {
- dl.find('.'+NONE).remove();
- }
- }, 'keyup');
-
- // 当搜索值清空时
- if(value === ''){
- // 取消选中项
- select.val('');
- dl.find('.'+ THIS).removeClass(THIS);
- (select[0].options[0] || {}).value || dl.children('dd:eq(0)').addClass(THIS);
- dl.find('.'+ NONE).remove();
- }
-
- followScroll(); // 定位滚动条
- };
-
- if(isSearch){
- input.on('input propertychange', search).on('blur', function(e){
- var selectedIndex = select[0].selectedIndex;
-
- thatInput = input; // 当前的 select 中的 input 元素
- initValue = $(select[0].options[selectedIndex]).text(); // 重新获得初始选中值
-
- // 如果是第一项,且文本值等于 placeholder,则清空初始值
- if(selectedIndex === 0 && initValue === input.attr('placeholder')){
- initValue = '';
- }
-
- setTimeout(function(){
- notOption(input.val(), function(none){
- initValue || input.val(''); // none && !initValue
- }, 'blur');
- }, 200);
- });
- }
-
- // 选择
- dds.on('click', function(){
- var othis = $(this), value = othis.attr('lay-value');
- var filter = select.attr('lay-filter'); // 获取过滤器
-
- if(othis.hasClass(DISABLED)) return false;
-
- if(othis.hasClass('layui-select-tips')){
- input.val('');
- } else {
- input.val(othis.text());
- othis.addClass(THIS);
- }
-
- othis.siblings().removeClass(THIS);
- select.val(value).removeClass('layui-form-danger');
-
- layui.event.call(this, MOD_NAME, 'select('+ filter +')', {
- elem: select[0]
- ,value: value
- ,othis: reElem
- });
-
- hideDown(true);
- return false;
- });
-
- reElem.find('dl>dt').on('click', function(e){
- return false;
- });
-
- $(document).off('click', hide).on('click', hide); // 点击其它元素关闭 select
+ } else {
+ type ? (
+ items[type] ? items[type]() : hint.error('不支持的 "' + type + '" 表单渲染')
+ ) : renderItem();
}
-
- // 初始渲染 select 组件选项
- selects.each(function(index, select){
- var othis = $(this)
- ,hasRender = othis.next('.'+CLASS)
- ,disabled = this.disabled
- ,value = select.value
- ,selected = $(select.options[select.selectedIndex]) // 获取当前选中项
- ,optionsFirst = select.options[0];
-
- if(typeof othis.attr('lay-ignore') === 'string') return othis.show();
-
- var isSearch = typeof othis.attr('lay-search') === 'string'
- ,placeholder = optionsFirst ? (
- optionsFirst.value ? TIPS : (optionsFirst.innerHTML || TIPS)
- ) : TIPS;
+ return that;
+ };
- // 替代元素
- var reElem = $([''
- ,'
'
- ,(' ') // 禁用状态
- ,'
'
- ,'
'
- ,function(options){
- var arr = [];
- layui.each(options, function(index, item){
- var tagName = item.tagName.toLowerCase();
+ /**
+ * checkbox 和 radio 指定属性变化时自动更新 UI
+ * @param {HTMLInputElement} elem - HTMLInput 元素
+ * @param {'checked' | 'indeterminate'} propName - 属性名
+ * @param {() => void} handler - 属性值改变时执行的回调
+ * @see https://learn.microsoft.com/zh-cn/previous-versions//ff382725(v=vs.85)?redirectedfrom=MSDN
+ */
+ Form.prototype.syncAppearanceOnPropChanged = function (elem, propName, handler) {
+ var originProps = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, propName);
- if(index === 0 && !item.value && tagName !== 'optgroup'){
- arr.push(''+ $.trim(item.innerHTML || TIPS) +' ');
- } else if(tagName === 'optgroup'){
- arr.push(''+ item.label +' ');
- } else {
- arr.push(''+ $.trim(item.innerHTML) +' ');
+ Object.defineProperty(elem, propName,
+ lay.extend({}, originProps, {
+ // 此处的 get 是为了兼容 IE<9
+ get: function () {
+ return originProps.get.call(this);
+ },
+ set: function (newValue) {
+ originProps.set.call(this, newValue);
+ handler.call(this);
}
- });
- arr.length === 0 && arr.push('没有选项 ');
- return arr.join('');
- }(othis.find('*')) +' '
- ,'
'].join(''));
-
- hasRender[0] && hasRender.remove(); // 如果已经渲染,则Rerender
- othis.after(reElem);
- events.call(this, reElem, disabled, isSearch);
- });
- }
-
- // 复选框/开关
- ,checkbox: function(elem){
- var CLASS = {
- "checkbox": ['layui-form-checkbox', 'layui-form-checked', 'checkbox'],
- "switch": ['layui-form-switch', 'layui-form-onswitch', 'switch'],
- SUBTRA: 'layui-icon-indeterminate'
- };
- var checks = elem || elemForm.find('input[type=checkbox]');
- // 风格
- var skins = {
- "primary": true, // 默认风格
- "tag": true, // 标签风格
- "switch": true // 开关风格
- };
- // 事件
- var events = function(reElem, RE_CLASS){
- var check = $(this);
-
- // 勾选
- reElem.on('click', function(){
+ })
+ );
+ }
+
+ /**
+ * 主动触发验证
+ * @param {(string|HTMLElement|JQuery)} elem - 要验证的区域表单元素
+ * @return {boolean} 返回结果。若验证通过,返回 `true`, 否则返回 `false`
+ */
+ Form.prototype.validate = function (elem) {
+ var that = this;
+ var intercept; // 拦截标识
+ var options = that.config; // 获取全局配置项
+ var verify = options.verify; // 验证规则
+ var DANGER = 'layui-form-danger'; // 警示样式
+
+ elem = $(elem);
+
+ // 节点不存在可视为 true
+ if (!elem[0]) return !0;
+
+ // 若节点不存在特定属性,则查找容器内有待验证的子节点
+ if (elem.attr('lay-verify') === undefined) {
+ // 若校验的是一个不带验证规则的容器,校验内部的 lay-verify 节点
+ if (that.validate(elem.find('*[lay-verify]')) === false) {
+ return false;
+ }
+ }
+
+ // 开始校验
+ layui.each(elem, function (_, item) {
var othis = $(this);
- var filter = check.attr('lay-filter') // 获取过滤器
- var title = (
- othis.next('*[lay-checkbox]')[0]
- ? othis.next().html()
- : check.attr('title') || ''
- );
- var skin = check.attr('lay-skin') || 'primary';
+ var verifyStr = othis.attr('lay-verify') || '';
+ var vers = verifyStr.split('|');
+ var verType = othis.attr('lay-vertype'); // 提示方式
+ var value = $.trim(othis.val());
- // 开关
- title = skin === 'switch' ? title.split('|') : [title];
+ othis.removeClass(DANGER); // 移除警示样式
- // 禁用
- if(check[0].disabled) return;
-
- // 半选
- if (check[0].indeterminate) {
- check[0].indeterminate = false;
- reElem.find('.'+ CLASS.SUBTRA).removeClass(CLASS.SUBTRA).addClass('layui-icon-ok');
- }
+ // 遍历元素绑定的验证规则
+ layui.each(vers, function (_, thisVer) {
+ var verst; // 校验结果
+ var errorText = ''; // 错误提示文本
+ var rule = verify[thisVer]; // 获取校验规则
- // 开关
- check[0].checked ? (
- check[0].checked = false,
- reElem.removeClass(RE_CLASS[1]),
- skin === 'switch' && reElem.children('div').html(title[1])
- ) : (
- check[0].checked = true,
- reElem.addClass(RE_CLASS[1]),
- skin === 'switch' && reElem.children('div').html(title[0])
- );
-
- // 事件
- layui.event.call(check[0], MOD_NAME, RE_CLASS[2]+'('+ filter +')', {
- elem: check[0],
- value: check[0].value,
- othis: reElem
+ // 匹配验证规则
+ if (rule) {
+ verst = typeof rule === 'function'
+ ? errorText = rule(value, item)
+ : !rule[0].test(value); // 兼容早期数组中的正则写法
+
+ // 是否属于美化替换后的表单元素
+ var isForm2Elem = item.tagName.toLowerCase() === 'select' || (
+ /^(checkbox|radio)$/.test(item.type)
+ );
+
+ errorText = errorText || rule[1];
+
+ // 获取自定义必填项提示文本
+ if (thisVer === 'required') {
+ errorText = othis.attr('lay-reqtext') || errorText;
+ }
+
+ // 若命中校验规则
+ if (verst) {
+ // 提示层风格
+ if (verType === 'tips') {
+ layer.tips(errorText, function () {
+ if (typeof othis.attr('lay-ignore') !== 'string') {
+ if (isForm2Elem) {
+ return othis.next();
+ }
+ }
+ return othis;
+ }(), { tips: 1 });
+ } else if (verType === 'alert') {
+ layer.alert(errorText, { title: '提示', shadeClose: true });
+ }
+ // 若返回的为字符或数字,则自动弹出默认提示框;否则由 verify 方法中处理提示
+ else if (/\b(string|number)\b/.test(typeof errorText)) {
+ layer.msg(errorText, { icon: 5, shift: 6 });
+ }
+
+ setTimeout(function () {
+ (isForm2Elem ? othis.next().find('input') : item).focus();
+ }, 7);
+
+ othis.addClass(DANGER);
+ return intercept = true;
+ }
+ }
});
- });
- };
-
- // 遍历复选框
- checks.each(function(index, check){
- var othis = $(this);
- var skin = othis.attr('lay-skin') || 'primary';
- var title = util.escape($.trim(check.title || function(){ // 向下兼容 lay-text 属性
- return check.title = othis.attr('lay-text') || '';
- }()));
- var disabled = this.disabled;
- // if(!skins[skin]) skin = 'primary'; // 若非内置风格,则强制为默认风格
- var RE_CLASS = CLASS[skin] || CLASS.checkbox;
-
- // 替代元素
- var hasRender = othis.next('.' + RE_CLASS[0]);
- hasRender[0] && hasRender.remove(); // 若已经渲染,则 Rerender
-
- // 若存在标题模板,则优先读取标题模板
- if(othis.next('[lay-checkbox]')[0]){
- title = othis.next().html() || '';
- }
-
- // 若为开关,则对 title 进行分隔解析
- title = skin === 'switch' ? title.split('|') : [title];
-
- if(typeof othis.attr('lay-ignore') === 'string') return othis.show();
-
- // 替代元素
- var reElem = $(['',
- function(){ // 不同风格的内容
- var type = {
- // 复选框
- "checkbox": [
- (title[0] ? ('
'+ title[0] +'
') : (skin === 'primary' ? '' : '
')),
- '
'
- ].join(''),
- // 开关
- "switch": '
'+ ((check.checked ? title[0] : title[1]) || '') +'
'
- };
- return type[skin] || type['checkbox'];
- }(),
- '
'].join(''));
-
- othis.after(reElem);
- events.call(this, reElem, RE_CLASS);
+ if (intercept) return intercept;
});
- }
-
- // 单选框
- ,radio: function(elem){
- var CLASS = 'layui-form-radio';
- var ICON = ['layui-icon-radio', 'layui-icon-circle'];
- var radios = elem || elemForm.find('input[type=radio]');
+
+ return !intercept;
+ };
+
+ // 提交表单并校验
+ var submit = Form.prototype.submit = function (filter, callback) {
+ var field = {}; // 字段集合
+ var button = $(this); // 当前触发的按钮
+
+ // 表单域 lay-filter 属性值
+ var layFilter = typeof filter === 'string'
+ ? filter
+ : button.attr('lay-filter');
+
+ // 当前所在表单域
+ var elem = this.getFormElem
+ ? this.getFormElem(layFilter)
+ : button.parents(ELEM).eq(0);
+
+ // 获取需要校验的元素
+ var verifyElem = elem.find('*[lay-verify]');
+
+ // 开始校验
+ if (!form.validate(verifyElem)) return false;
+
+ // 获取当前表单值
+ field = form.getValue(null, elem);
+
+ // 返回的参数
+ var params = {
+ elem: this.getFormElem ? (window.event && window.event.target) : this // 触发事件的对象
+ , form: this.getFormElem ? elem[0] : button.parents('form')[0] // 当前所在的 form 元素,如果存在的话
+ , field: field // 当前表单数据
+ };
+
+ // 回调
+ typeof callback === 'function' && callback(params);
// 事件
- var events = function(reElem){
- var radio = $(this);
- var ANIM = 'layui-anim-scaleSpring';
-
- reElem.on('click', function(){
- var name = radio[0].name, forms = radio.parents(ELEM);
- var filter = radio.attr('lay-filter'); // 获取过滤器
- var sameRadio = forms.find('input[name='+ name.replace(/(\.|#|\[|\])/g, '\\$1') +']'); // 找到相同name的兄弟
-
- if(radio[0].disabled) return;
-
- layui.each(sameRadio, function(){
- var next = $(this).next('.' + CLASS);
- this.checked = false;
- next.removeClass(CLASS + 'ed');
- next.children('.layui-icon').removeClass(ANIM + ' ' + ICON[0]).addClass(ICON[1]);
- });
-
- radio[0].checked = true;
- reElem.addClass(CLASS + 'ed');
- reElem.children('.layui-icon').addClass(ANIM + ' ' + ICON[0]);
-
- layui.event.call(radio[0], MOD_NAME, 'radio('+ filter +')', {
- elem: radio[0],
- value: radio[0].value,
- othis: reElem
- });
- });
- };
-
- // 初始渲染
- radios.each(function(index, radio){
- var othis = $(this), hasRender = othis.next('.' + CLASS);
- var disabled = this.disabled;
-
- if(typeof othis.attr('lay-ignore') === 'string') return othis.show();
- hasRender[0] && hasRender.remove(); // 如果已经渲染,则Rerender
-
- // 替代元素
- var reElem = $(['', // 禁用状态
- '
',
- '
'+ function(){
- var title = util.escape(radio.title || '');
- if(othis.next('[lay-radio]')[0]){
- title = othis.next().html();
- }
- return title;
- }() +'
',
- '
'].join(''));
-
- othis.after(reElem);
- events.call(this, reElem);
- });
- }
+ return layui.event.call(this, MOD_NAME, 'submit(' + layFilter + ')', params);
};
- // 执行所有渲染项
- var renderItem = function(){
- layui.each(items, function(index, item){
- item();
- });
- };
-
- // jquery 对象
- if (layui.type(type) === 'object') {
- // 若对象为表单域容器
- if($(type).is(ELEM)){
- elemForm = $(type);
- renderItem();
- } else { // 对象为表单项
- type.each(function (index, item) {
- var elem = $(item);
- if (!elem.closest(ELEM).length) {
- return; // 若不在 layui-form 容器中直接跳过
- }
- if (item.tagName === 'SELECT') {
- items['select'](elem);
- } else if (item.tagName === 'INPUT') {
- var itemType = item.type;
- if (itemType === 'checkbox' || itemType === 'radio') {
- items[itemType](elem);
- } else {
- items['input'](elem);
- }
- }
- });
- }
- } else {
- type ? (
- items[type] ? items[type]() : hint.error('不支持的 "'+ type + '" 表单渲染')
- ) : renderItem();
- }
- return that;
- };
-
- // 主动触发验证 -- elem 即要验证的区域表单选择器 / return true or false
- Form.prototype.validate = function(elem){
- var that = this;
- var stop = null; // 验证不通过状态
- var options = that.config; // 获取全局配置项
- var verify = options.verify; // 验证规则
- var DANGER = 'layui-form-danger'; // 警示样式
-
- elem = $(elem);
-
- // 节点不存在可视为 true
- if(!elem[0]) return !0;
-
- // 若节点不存在特定属性,则查找容器内有待验证的子节点
- if(elem.attr('lay-verify') === undefined){
- // 若校验的是一个不带验证规则的容器,校验内部的 lay-verify 节点
- if (that.validate(elem.find('*[lay-verify]')) === false) {
- return false;
- }
- }
-
- // 开始校验
- layui.each(elem, function(_, item){
- var othis = $(this);
- var verifyStr = othis.attr('lay-verify') || '';
- var vers = verifyStr.split('|');
- var verType = othis.attr('lay-vertype'); // 提示方式
- var value = $.trim(othis.val());
-
- othis.removeClass(DANGER); // 移除警示样式
-
- // 遍历元素绑定的验证规则
- layui.each(vers, function(_, thisVer){
- var isTrue; // 是否命中校验
- var errorText = ''; // 错误提示文本
- var rule = verify[thisVer]; // 获取校验规则
-
- // 匹配验证规则
- if(rule){
- isTrue = typeof rule === 'function'
- ? errorText = rule(value, item)
- : !rule[0].test(value);
-
- // 是否属于美化替换后的表单元素
- var isForm2Elem = item.tagName.toLowerCase() === 'select' || (
- /^(checkbox|radio)$/.test(item.type)
- );
-
- errorText = errorText || rule[1];
-
- // 获取自定义必填项提示文本
- if(thisVer === 'required'){
- errorText = othis.attr('lay-reqtext') || errorText;
- }
-
- // 若为必填项或者非空命中校验,则阻止提交,弹出提示
- if(isTrue && (
- options.verIncludeRequired || (
- thisVer === 'required' || (
- value && thisVer !== 'required'
- )
- )
- )){
- // 提示层风格
- if(verType === 'tips'){
- layer.tips(errorText, function(){
- if(typeof othis.attr('lay-ignore') !== 'string'){
- if(isForm2Elem){
- return othis.next();
- }
- }
- return othis;
- }(), {tips: 1});
- } else if(verType === 'alert') {
- layer.alert(errorText, {title: '提示', shadeClose: true});
- }
- // 若返回的为字符或数字,则自动弹出默认提示框;否则由 verify 方法中处理提示
- else if(/\b(string|number)\b/.test(typeof errorText)){
- layer.msg(errorText, {icon: 5, shift: 6});
- }
-
- setTimeout(function(){
- (isForm2Elem ? othis.next().find('input') : item).focus();
- }, 7);
-
- othis.addClass(DANGER);
- return stop = true;
- }
+ function fuzzyMatchRegExp(keyword, caseSensitive) {
+ var wordMap = {};
+ var regexPattern = ['^'];
+ var escapeRegExp = function (str) {
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
- });
- if(stop) return stop;
+ if (!caseSensitive) keyword = keyword.toLowerCase();
+
+ // 统计关键字中各字符出现次数
+ var wordArr = keyword.trim().split('');
+ for (var i = 0; i < wordArr.length; i++) {
+ var c = wordArr[i];
+ wordMap[c] = (wordMap[c] || 0) + 1;
+ }
+
+ // 构建正则表达式模式
+ for (c in wordMap) {
+ regexPattern.push('(?=.*');
+ for (var i = 0; i < wordMap[c]; i++) {
+ regexPattern.push(escapeRegExp(c));
+ if (i !== wordMap[c] - 1) {
+ regexPattern.push('.*'); // 在字符之间添加任意字符匹配
+ }
+ }
+ regexPattern.push(')');
+ }
+ regexPattern.push('.*');
+
+ return new RegExp(regexPattern.join(''), !caseSensitive ? 'i' : undefined);
+ }
+
+ var form = new Form();
+ var $dom = $(document);
+ var $win = $(window);
+
+ // 初始自动完成渲染
+ $(function () {
+ form.render();
});
- return !stop;
- };
+ // 表单 reset 重置渲染
+ $dom.on('reset', ELEM, function () {
+ var filter = $(this).attr('lay-filter');
+ setTimeout(function () {
+ form.render(null, filter);
+ }, 50);
+ });
- // 提交表单并校验
- var submit = Form.prototype.submit = function(filter, callback){
- var field = {}; // 字段集合
- var button = $(this); // 当前触发的按钮
+ // 表单提交事件
+ $dom.on('submit', ELEM, submit)
+ .on('click', '*[lay-submit]', submit);
- // 表单域 lay-filter 属性值
- var layFilter = typeof filter === 'string'
- ? filter
- : button.attr('lay-filter');
-
- // 当前所在表单域
- var elem = this.getFormElem
- ? this.getFormElem(layFilter)
- : button.parents(ELEM).eq(0);
-
- // 获取需要校验的元素
- var verifyElem = elem.find('*[lay-verify]');
-
- // 开始校验
- if(!form.validate(verifyElem)) return false;
-
- // 获取当前表单值
- field = form.getValue(null, elem);
-
- // 返回的参数
- var params = {
- elem: this.getFormElem ? (window.event && window.event.target) : this // 触发事件的对象
- ,form: this.getFormElem ? elem[0] : button.parents('form')[0] // 当前所在的 form 元素,如果存在的话
- ,field: field // 当前表单数据
- };
-
- // 回调
- typeof callback === 'function' && callback(params);
-
- // 事件
- return layui.event.call(this, MOD_NAME, 'submit('+ layFilter +')', params);
- };
-
- var form = new Form();
- var $dom = $(document);
- var $win = $(window);
-
- // 初始自动完成渲染
- $(function(){
- form.render();
- });
-
- // 表单 reset 重置渲染
- $dom.on('reset', ELEM, function(){
- var filter = $(this).attr('lay-filter');
- setTimeout(function(){
- form.render(null, filter);
- }, 50);
- });
-
- // 表单提交事件
- $dom.on('submit', ELEM, submit)
- .on('click', '*[lay-submit]', submit);
-
- exports(MOD_NAME, form);
+ exports(MOD_NAME, form);
});
-
+
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/lay.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/lay.js
index 09f87f6..d9464f5 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/modules/lay.js
+++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/lay.js
@@ -3,15 +3,18 @@
;!function(window){ // gulp build: lay-header
"use strict";
-
+
var MOD_NAME = 'lay'; // 模块名
var document = window.document;
-
- // 元素查找
- var lay = function(selector){
+
+ /**
+ * 元素查找
+ * @param {string | HTMLElement | JQuery} selector
+ */
+ var lay = function(selector){
return new Class(selector);
};
-
+
// 构造器
var Class = function(selector){
var that = this;
@@ -27,15 +30,37 @@
that.push(elem[index]);
});
};
-
+
+ /*
+ * API 兼容
+ */
+ Array.prototype.indexOf = Array.prototype.indexOf || function(searchElement, fromIndex) {
+ var rst = -1;
+ fromIndex = fromIndex || 0;
+ layui.each(this, function(index, val){
+ if (searchElement === val && index >= fromIndex) {
+ rst = index;
+ return !0;
+ }
+ });
+ return rst;
+ };
+
/*
lay 对象操作
*/
-
+
Class.fn = Class.prototype = [];
Class.fn.constructor = Class;
-
- // 普通对象深度扩展
+
+ /**
+ * 将两个或多个对象的内容深度合并到第一个对象中
+ * @callback ExtendFunc
+ * @param {*} target - 一个对象
+ * @param {...*} objectN - 包含额外的属性合并到第一个参数
+ * @returns {*} 返回合并后的对象
+ */
+ /** @type ExtendFunc*/
lay.extend = function(){
var ai = 1;
var length;
@@ -61,20 +86,23 @@
}
return args[0];
};
-
- // ie 版本
+
+ /**
+ * IE 版本
+ * @type {string | boolean} - 如果是 IE 返回版本字符串,否则返回 false
+ */
lay.ie = function(){
var agent = navigator.userAgent.toLowerCase();
return (!!window.ActiveXObject || "ActiveXObject" in window) ? (
(agent.match(/msie\s(\d+)/) || [])[1] || '11' // 由于 ie11 并没有 msie 的标识
) : false;
}();
-
-
- /**
+
+
+ /**
* 获取 layui 常见方法,以便用于组件单独版
*/
-
+
lay.layui = layui || {};
lay.getPath = layui.cache.dir; // 获取当前 JS 所在目录
lay.stope = layui.stope; // 中止冒泡
@@ -83,8 +111,18 @@
return this;
};
-
- // 数字前置补零
+
+ /**
+ * 数字前置补零
+ * @param {number | string} num - 原始数字
+ * @param {number} [length=2] - 数字长度,如果原始数字长度小于 length,则前面补零
+ * @returns {string} 返回补 0 后的数字
+ * @example
+ * ```js
+ * lay.digit(6, 2); // "06"
+ * lay.digit('7', 3); // "007"
+ * ```
+ */
lay.digit = function(num, length){
if(!(typeof num === 'string' || typeof num === 'number')) return '';
@@ -96,8 +134,17 @@
}
return num < Math.pow(10, length) ? str + num : num;
};
-
- // 创建元素
+
+ /**
+ * 创建元素
+ * @param {string} elemName - 元素的标签名
+ * @param {Object.} [attr] - 添加到元素上的属性
+ * @returns {HTMLElement} 返回创建的 HTML 元素
+ * @example
+ * ```js
+ * lay.elem('div', {id: 'test'}) //
+ * ```
+ */
lay.elem = function(elemName, attr){
var elem = document.createElement(elemName);
lay.each(attr || {}, function(key, value){
@@ -106,50 +153,184 @@
return elem;
};
- // 当前页面是否存在滚动条
+ /**
+ * 当前页面是否存在滚动条
+ * @returns {boolean} 是否存在滚动条
+ * @example
+ * ```
+ * lay.hasScrollbar() // true 或 false
+ * ```
+ */
lay.hasScrollbar = function(){
return document.body.scrollHeight > (window.innerHeight || document.documentElement.clientHeight);
};
-
- // 元素定位
- lay.position = function(elem, elemView, obj){
- if(!elemView) return;
- obj = obj || {};
-
+
+ /**
+ * 获取 style rules
+ * @param {HTMLStyleElement} style - HTMLStyle 元素
+ * @param {(ruleItem: CSSStyleRule, index: number) => boolean} [callback] - 用来返回 style 元素中的每个 `style rule` 的函数,返回 true 终止遍历
+ * @returns {CSSRuleList } 返回 `style rules`
+ * @example
+ * ```
+ *
+ *
+ * lay.getStyleRules($('#test')[0], function(rule, index){
+ * if(rule.selectorText === '.lay-card'){
+ * console.log(index, rule.cssText) // 0 '.lay-card{color: #000}'
+ * rule.style.color = '#EEE';
+ * return true; // 终止遍历
+ * }
+ * }) // RuleList
+ * ```
+ */
+ lay.getStyleRules = function(style, callback) {
+ if (!style) return;
+
+ var sheet = style.sheet || style.styleSheet || {};
+ var rules = sheet.cssRules || sheet.rules;
+
+ if (typeof callback === 'function') {
+ layui.each(rules, function(i, item){
+ if (callback(item, i)) return true;
+ });
+ }
+
+ return rules;
+ };
+
+ /**
+ * 创建 style 样式
+ * @param {Object} options - 可配置的选项
+ * @param {string | HTMLElement | JQuery} [options.target] - 目标容器,指定后会将样式追加到目标容器
+ * @param {string} [options.id] - 样式元素的 id,默认自增
+ * @param {string} options.text - 样式内容
+ * @returns {HTMLStyleElement} 返回创建的样式元素
+ * @example
+ * ```html
+ *
+ *
+ *
+ *
+ *
+ * lay.style({
+ * target: '#targetEl',
+ * text: '.card{color: #000}'
+ * }) //
+ * ```
+ */
+ lay.style = function(options){
+ options = options || {};
+
+ var style = lay.elem('style');
+ var styleText = options.text || '';
+ var target = options.target;
+
+ if (!styleText) return;
+
+ // 添加样式
+ if ('styleSheet' in style) {
+ style.setAttribute('type', 'text/css');
+ style.styleSheet.cssText = styleText;
+ } else {
+ style.innerHTML = styleText;
+ }
+
+ // ID
+ style.id = 'LAY-STYLE-'+ (options.id || function(index) {
+ lay.style.index++;
+ return 'DF-'+ index;
+ }(lay.style.index || 0));
+
+ // 是否向目标容器中追加 style 元素
+ if (target) {
+ var styleElem = lay(target).find('#'+ style.id);
+ styleElem[0] && styleElem.remove();
+ lay(target).append(style);
+ }
+
+ return style;
+ };
+
+ /**
+ * 将元素定位到指定目标元素附近
+ * @param {HTMLElement} target - 目标元素
+ * @param {HTMLElement} elem - 定位元素
+ * @param {Object} [opts] - 可配置的选项
+ * @param {'absolute' | 'fixed'} [opts.position] - 元素的定位类型
+ * @param {'left' | 'right'} [opts.clickType="left"] - 点击类型,默认为 'left',如果 {@link target} 是 document 或 body 元素,则为 'right'
+ * @param {'left' | 'right' | 'center'} [opts.align="left"] - 对齐方式
+ * @param {boolean} [opts.allowBottomOut=false] - 顶部没有足够区域显示时,是否允许底部溢出
+ * @param {string | number} [opts.margin=5] - 边距
+ * @param {Event} [opts.e] - 事件对象,仅右键生效
+ * @param {boolean} [opts.SYSTEM_RELOAD] - 是否重载,用于出现滚动条时重新计算位置
+ * @param {[offsetX:number, offsetY:number]} [opts.offset] - 相对于触发元素的额外偏移量[x,y]
+ * @example
+ * ```js
+ * dropdown
+ *
+ *
+ * // 下拉菜单将被定位到按钮附近
+ * lay.position(
+ * $('#targetEl')[0],
+ * $('#contentEl')[0],
+ * {
+ * position: 'fixed',
+ * align: 'center'
+ * }
+ * )
+ * ```
+ */
+ lay.position = function(target, elem, opts){
+ if(!elem) return;
+ opts = opts || {};
+
// 如果绑定的是 document 或 body 元素,则直接获取鼠标坐标
- if(elem === document || elem === lay('body')[0]){
- obj.clickType = 'right';
+ if(target === document || target === lay('body')[0]){
+ opts.clickType = 'right';
}
// 绑定绑定元素的坐标
- var rect = obj.clickType === 'right' ? function(){
- var e = obj.e || window.event || {};
+ var rect = opts.clickType === 'right' ? function(){
+ var e = opts.e || window.event || {};
return {
- left: e.clientX
- ,top: e.clientY
- ,right: e.clientX
- ,bottom: e.clientY
+ left: e.clientX,
+ top: e.clientY,
+ right: e.clientX,
+ bottom: e.clientY
}
- }() : elem.getBoundingClientRect()
- ,elemWidth = elemView.offsetWidth // 控件的宽度
- ,elemHeight = elemView.offsetHeight // 控件的高度
-
+ }() : target.getBoundingClientRect();
+ var elemWidth = elem.offsetWidth; // 控件的宽度
+ var elemHeight = elem.offsetHeight; // 控件的高度
+
// 滚动条高度
- ,scrollArea = function(type){
+ var scrollArea = function(type){
type = type ? 'scrollLeft' : 'scrollTop';
return document.body[type] | document.documentElement[type];
- }
-
+ };
+
// 窗口宽高
- ,winArea = function(type){
+ var winArea = function(type){
return document.documentElement[type ? 'clientWidth' : 'clientHeight']
- }, margin = 5, left = rect.left, top = rect.bottom;
-
+ };
+ var margin = 'margin' in opts ? opts.margin : 5;
+ var left = rect.left;
+ var top = rect.bottom;
+
// 相对元素居中
- if(obj.align === 'center'){
- left = left - (elemWidth - elem.offsetWidth)/2;
- } else if(obj.align === 'right'){
- left = left - elemWidth + elem.offsetWidth;
+ if(opts.align === 'center'){
+ left = left - (elemWidth - target.offsetWidth) / 2;
+ } else if(opts.align === 'right'){
+ left = left - elemWidth + target.offsetWidth;
}
// 判断右侧是否超出边界
@@ -158,8 +339,19 @@
}
// 左侧是否超出边界
if(left < margin) left = margin;
-
+
+
// 判断底部和顶部是否超出边界
+ if(rect.bottom + elemHeight + margin > winArea()){ // 底部超出边界
+ // 优先判断顶部是否有足够区域显示完全,且底部不能超出边界
+ if(rect.top > elemHeight + margin && rect.top <= winArea() ){
+ top = rect.top - elemHeight - margin*2; // 顶部有足够的区域显示
+ } else if(!opts.allowBottomOut){ // 顶部没有足够区域显示时,是否允许底部溢出
+ top = winArea() - elemHeight - margin*2; // 面板向底部靠齐
+ if(top < 0) top = 0; // 如果面板底部靠齐时,又溢出窗口顶部,则只能将顶部靠齐
+ }
+ }
+ /*
if(top + elemHeight + margin > winArea()){
// 优先顶部是否有足够区域显示完全
if(rect.top > elemHeight + margin){
@@ -174,29 +366,50 @@
}
}
}
-
+ */
+
// 定位类型
- var position = obj.position;
- if(position) elemView.style.position = position;
-
+ var position = opts.position;
+ if(position) elem.style.position = position;
+ var offsetX = opts.offset ? opts.offset[0] : 0;
+ var offsetY = opts.offset ? opts.offset[1] : 0;
+
// 设置坐标
- elemView.style.left = left + (position === 'fixed' ? 0 : scrollArea(1)) + 'px';
- elemView.style.top = top + (position === 'fixed' ? 0 : scrollArea()) + 'px';
+ elem.style.left = left + (position === 'fixed' ? 0 : scrollArea(1)) + offsetX + 'px';
+ elem.style.top = top + (position === 'fixed' ? 0 : scrollArea()) + offsetY + 'px';
// 防止页面无滚动条时,又因为弹出面板而出现滚动条导致的坐标计算偏差
if(!lay.hasScrollbar()){
- var rect1 = elemView.getBoundingClientRect();
+ var rect1 = elem.getBoundingClientRect();
// 如果弹出面板的溢出窗口底部,则表示将出现滚动条,此时需要重新计算坐标
- if(!obj.SYSTEM_RELOAD && (rect1.bottom + margin) > winArea()){
- obj.SYSTEM_RELOAD = true;
+ if(!opts.SYSTEM_RELOAD && (rect1.bottom + margin) > winArea()){
+ opts.SYSTEM_RELOAD = true;
setTimeout(function(){
- lay.position(elem, elemView, obj);
+ lay.position(target, elem, opts);
}, 50);
}
}
};
-
- // 获取元素上的属性配置项
+
+ /**
+ * 获取元素上的属性配置项
+ * @param {string | HTMLElement | JQuery} elem - HTML 元素
+ * @param {{attr: string} | string} [opts="lay-options"] - 可配置的选项,string 类型指定属性名
+ * @returns {Object.} 返回元素上的属性配置项
+ * @example
+ * ```js
+ *
+ *
+ * var elem = $('#testEl')
+ * lay.options(elem) // {color:red}
+ * lay.options(elem[0]) // {color:red}
+ * lay.options('#testEl') // {color:red}
+ * lay.options('#testEl', {attr: 'lay-toc'}) // {hot: true}
+ * lay.options('#testEl', 'lay-toc') // {hot: true}
+ *
+ * $('#testEl').attr('lay-toc') // '{hot: true}'
+ * ```
+ */
lay.options = function(elem, opts){
opts = typeof opts === 'object' ? opts : {attr: opts};
@@ -207,17 +420,30 @@
var attrValue = othis.attr(attrName);
try {
+ /**
+ * 请注意: 开发者在使用 lay-options="{}" 配置组件选项时,需确保属性值不来自于网页用户,
+ * 即属性值必须在网页开发者自身的可控范围内,否则请勿在 HTML 标签属性中获取组件选项。
+ */
return new Function('return '+ (attrValue || '{}'))();
} catch(ev) {
layui.hint().error(opts.errorText || [
- attrName + '="'+ attrValue + '"',
+ attrName + '="'+ attrValue + '"',
'\n parseerror: '+ ev
].join('\n'), 'error');
return {};
}
};
-
- // 元素是否属于顶级元素(document 或 body)
+
+
+ /**
+ * 元素是否属于顶级元素(document 或 body)
+ * @param {HTMLElement} elem - HTML 元素
+ * @returns {boolean} 是否属于顶级元素
+ * @example
+ * ```js
+ * lay.isTopElem(document) // true
+ * ```
+ */
lay.isTopElem = function(elem){
var topElems = [document, lay('body')[0]]
,matched = false;
@@ -229,11 +455,328 @@
return matched;
};
+ // 剪切板
+ lay.clipboard = {
+ /**
+ * 写入文本
+ * @param {Object} options - 可配置的选项
+ * @param {string} options.text - 写入剪贴板的文本
+ * @param {() => void} [options.done] - 写入成功/完成回调
+ * @param {(err?: any) => void} [options.error] - 写入失败回调
+ * @example
+ * ```js
+ * lay.clipboard.writeText({
+ * text: '测试文本',
+ * done: function(){ layer.msg('copied')},
+ * error: function(){ layer.msg('error')}
+ * })
+ * ```
+ */
+ writeText: function(options) {
+ var text = String(options.text);
+
+ if(navigator && 'clipboard' in navigator){
+ navigator.clipboard.writeText(text)
+ .then(options.done, function(){
+ legacyCopy();
+ });
+ }else{
+ legacyCopy();
+ }
+
+ function legacyCopy(){
+ var elem = document.createElement('textarea');
+
+ elem.value = text;
+ elem.style.position = 'fixed';
+ elem.style.opacity = '0';
+ elem.style.top = '0px';
+ elem.style.left = '0px';
+
+ document.body.appendChild(elem);
+ elem.select();
+
+ try {
+ document.execCommand('copy');
+ typeof options.done === 'function' && options.done();
+ } catch(err) {
+ typeof options.error === 'function' && options.error(err);
+ } finally {
+ elem.remove ? elem.remove() : document.body.removeChild(elem);
+ }
+ }
+ }
+ };
+
+ /**
+ * 检测是否支持 Passive Event Listeners
+ * 引用自 https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md
+ * @type {boolean}
+ */
+ lay.passiveSupported = function(){
+ var passiveSupported = false;
+ try {
+ var opts = Object.defineProperty({}, 'passive', {
+ get: function() {
+ passiveSupported = true;
+ }
+ });
+ window.addEventListener('test', null, opts);
+ window.removeEventListener('test', null, opts);
+ } catch (err) {}
+ return passiveSupported;
+ }();
+
+ /**
+ * 是否支持 touch 事件
+ */
+ lay.touchEventsSupported = function(){
+ return 'ontouchstart' in window;
+ };
+
+ /**
+ * @typedef touchSwipeState
+ * @prop {{x: number,y: number}} pointerStart - 初始坐标
+ * @prop {{x: number,y: number}} pointerEnd - 结束坐标
+ * @prop {number} distanceX - X 轴移动距离
+ * @prop {number} distanceY - Y 轴移动距离
+ * @prop {'none'|'right'|'left'|'up'|'down'} direction - 滑动方向
+ * @prop {Date} timeStart 开始时间
+ */
+ /**
+ * @callback touchSwipeCallback
+ * @param {TouchEvent} e 滑动事件
+ * @param {touchSwipeState} state 滑动相关的状态
+ */
+ /**
+ * 基于 touch 事件的触摸滑动
+ * @param {string | HTMLElement | JQuery} elem - HTML 元素
+ * @param {{onTouchStart?: touchSwipeCallback, onTouchMove?: touchSwipeCallback, onTouchEnd?: touchSwipeCallback}} opts - 配置项
+ */
+ lay.touchSwipe = function(elem, opts){
+ var options = opts
+ var targetElem = lay(elem)[0];
+
+ if(!targetElem || !lay.touchEventsSupported()) return;
+
+ var state = {
+ pointerStart: {x:0, y:0},
+ pointerEnd: {x:0, y:0},
+ distanceX: 0,
+ distanceY: 0,
+ direction:'none', // 'up','down','left','right','none
+ timeStart: null
+ }
+
+ var onStart = function(e){
+ if(e.touches.length !== 1) return;
+ bindEvents();
+ // 重置状态
+ state.timeStart = Date.now();
+ state.pointerStart.x = state.pointerEnd.x = e.touches[0].clientX;
+ state.pointerStart.y = state.pointerEnd.y = e.touches[0].clientY;
+ state.distanceX = state.distanceY = 0;
+ state.direction = 'none'
+
+ options.onTouchStart && options.onTouchStart(e, state);
+ }
+
+ var onMove = function(e){
+ e.preventDefault();
+ state.pointerEnd.x = e.touches[0].clientX;
+ state.pointerEnd.y = e.touches[0].clientY;
+ state.distanceX = state.pointerStart.x - state.pointerEnd.x;
+ state.distanceY = state.pointerStart.y - state.pointerEnd.y;
+ if(Math.abs(state.distanceX) > Math.abs(state.distanceY)){
+ state.direction = state.distanceX > 0 ? 'left' : 'right';
+ }else{
+ state.direction = state.distanceY > 0 ? 'up' : 'down';
+ }
+ options.onTouchMove && options.onTouchMove(e, state);
+ }
+
+ var onEnd = function(e){
+ options.onTouchEnd && options.onTouchEnd(e, state);
+ unbindEvents();
+ }
+
+ var bindEvents = function(){
+ targetElem.addEventListener('touchmove', onMove, lay.passiveSupported ? { passive: false} : false);
+ targetElem.addEventListener('touchend', onEnd);
+ targetElem.addEventListener('touchcancel', onEnd);
+ }
+
+ var unbindEvents = function(){
+ targetElem.removeEventListener('touchmove', onMove);
+ targetElem.removeEventListener('touchend', onEnd, lay.passiveSupported ? { passive: false} : false);
+ targetElem.removeEventListener('touchcancel', onEnd);
+ }
+
+ // 防止事件重复绑定
+ if(targetElem.__lay_touchswipe_cb_){
+ targetElem.removeEventListener('touchstart', targetElem.__lay_touchswipe_cb_);
+ }
+ targetElem.__lay_touchswipe_cb_ = onStart;
+ targetElem.addEventListener('touchstart', onStart);
+ }
+
+ /** @type {(elem: Element|Document|Window,eventName: string,fn:EventListenerOrEventListenerObject,options: boolean | AddEventListenerOptions) => any}*/
+ lay.addEvent = function(){
+ if(document.addEventListener){
+ return function(elem, eventName, fn, options){
+ elem.addEventListener(eventName, fn, options);
+ }
+ }else{
+ return function(elem, eventName, fn){
+ var prefix = '_lay_on_';
+ var eventsCacheName = prefix + eventName;
+ var listener = function(e){
+ e.target = e.srcElement;
+ fn.call(elem, e);
+ }
+ listener._rawFn = fn;
+ if(!elem[eventsCacheName]){
+ elem[eventsCacheName] = [];
+ }
+ var include = false;
+ lay.each(elem[eventsCacheName], function(_, listener){
+ if(listener._rawFn === fn){
+ include = true;
+ return true;
+ }
+ })
+ if(!include){
+ elem[eventsCacheName].push(listener);
+ elem.attachEvent('on' + eventName, listener);
+ }
+ }
+ }
+ }();
+
+ /** @type {(elem: Element|Document|Window,eventName: string,fn:EventListenerOrEventListenerObject,options: boolean | EventListenerOptions) => any}*/
+ lay.removeEvent = function(){
+ if(document.removeEventListener){
+ return function(elem, eventName, fn, options){
+ elem.removeEventListener(eventName, fn, options);
+ }
+ }else{
+ return function(elem, eventName, fn){
+ var prefix = '_lay_on_';
+ var eventsCacheName = prefix + eventName;
+ var events = elem[eventsCacheName];
+ if(layui.isArray(events)){
+ var newEvents = [];
+ lay.each(events, function(_, listener){
+ if(listener._rawFn === fn){
+ elem.detachEvent('on'+ eventName, listener);
+ }else{
+ newEvents.push(listener);
+ }
+ })
+ elem[eventsCacheName] = newEvents;
+ }
+ }
+ }
+ }();
+
+ /**
+ * 监听指定元素外部的点击
+ * @param {HTMLElement} target - 被监听的元素
+ * @param {(e: Event) => void} handler - 事件触发时执行的函数
+ * @param {object} [options] - 选项
+ * @param {string} [options.event="pointerdown"] - 监听的事件类型
+ * @param {HTMLElement | Window} [options.scope=document] - 监听范围
+ * @param {Array} [options.ignore] - 忽略监听的元素或选择器字符串
+ * @param {boolean} [options.capture=true] - 对内部事件侦听器使用捕获阶段
+ * @returns {() => void} - 返回一个停止事件监听的函数
+ */
+ lay.onClickOutside = function(target, handler, options){
+ options = options || {};
+ var eventType = options.event || ('onpointerdown' in window ? 'pointerdown' : 'mousedown');
+ var scopeTarget = options.scope || document;
+ var ignore = options.ignore || [];
+ var useCapture = 'capture' in options ? options.capture : true;
+
+ var listener = function(event){
+ var el = target;
+ var eventTarget = event.target || event.srcElement;
+ var eventPath = getEventPath(event);
+
+ if (!el || el === eventTarget || eventPath.indexOf(el) !== -1){
+ return;
+ }
+ if(shouldIgnore(event, eventPath)){
+ return;
+ }
+
+ handler(event);
+ };
+
+ function shouldIgnore(event, eventPath){
+ var eventTarget = event.target || event.srcElement;
+ for(var i = 0; i < ignore.length; i++){
+ var target = ignore[i];
+ if(typeof target === 'string'){
+ var targetElements = document.querySelectorAll(target);
+ for(var j = 0; j < targetElements.length; j++){
+ var targetEl = targetElements[i];
+ if(targetEl === eventTarget || eventPath.indexOf(targetEl) !== -1){
+ return true;
+ }
+ }
+ }else{
+ if(target && (target === eventTarget || eventPath.indexOf(target) !== -1)){
+ return true;
+ }
+ }
+ }
+ }
+
+ function getEventPath(event){
+ var path = (event.composedPath && event.composedPath()) || event.path;
+ var eventTarget = event.target || event.srcElement;
+
+ if (path !== null && path !== undefined){
+ return path;
+ }
+
+ function getParents(node, memo){
+ memo = memo || [];
+ var parentNode = node.parentNode;
+
+ return parentNode
+ ? getParents(parentNode, memo.concat([parentNode]))
+ : memo;
+ }
+
+ return [eventTarget].concat(getParents(eventTarget));
+ }
+
+ function bindEventListener(elem, eventName, handler, opts){
+ elem.addEventListener
+ ? elem.addEventListener(eventName, handler, opts)
+ : elem.attachEvent('on' + eventName, handler);
+
+ return function(){
+ elem.removeEventListener
+ ? elem.removeEventListener(eventName, handler, opts)
+ : elem.detachEvent('on' + eventName, handler);
+ }
+ }
+
+ return bindEventListener(
+ scopeTarget,
+ eventType,
+ listener,
+ lay.passiveSupported ? { passive: true, capture: useCapture } : useCapture
+ );
+ };
+
/*
* lay 元素操作
*/
-
+
// 追加字符
Class.addStr = function(str, new_str){
@@ -246,7 +789,7 @@
});
return str.replace(/^\s|\s$/, '');
};
-
+
// 移除值
Class.removeStr = function(str, new_str){
str = str.replace(/\s+/, ' ');
@@ -259,7 +802,7 @@
});
return str.replace(/\s+/, ' ').replace(/^\s|\s$/, '');
};
-
+
// 查找子元素
Class.fn.find = function(selector){
var that = this;
@@ -267,7 +810,7 @@
var isObject = typeof selector === 'object';
this.each(function(i, item){
- var children = isObject && item.contains(selector)
+ var children = isObject && item.contains(selector)
? selector
: item.querySelectorAll(selector || null);
@@ -278,24 +821,24 @@
return lay(elem);
};
-
+
// 元素遍历
Class.fn.each = function(fn){
return lay.each.call(this, this, fn);
};
-
+
// 添加 className
Class.fn.addClass = function(className, type){
return this.each(function(index, item){
item.className = Class[type ? 'removeStr' : 'addStr'](item.className, className)
});
};
-
+
// 移除 className
Class.fn.removeClass = function(className){
return this.addClass(className, true);
};
-
+
// 是否包含 css 类
Class.fn.hasClass = function(className){
var has = false;
@@ -306,7 +849,7 @@
});
return has;
};
-
+
// 添加或获取 css style
Class.fn.css = function(key, value){
var that = this;
@@ -319,9 +862,9 @@
typeof key === 'object' ? lay.each(key, function(thisKey, thisValue){
item.style[thisKey] = parseValue(thisValue);
}) : item.style[key] = parseValue(value);
- });
+ });
};
-
+
// 添加或获取宽度
Class.fn.width = function(value){
var that = this;
@@ -329,9 +872,9 @@
if(that.length > 0) return that[0].offsetWidth; // 此处还需做兼容
}() : that.each(function(index, item){
that.css('width', value);
- });
+ });
};
-
+
// 添加或获取高度
Class.fn.height = function(value){
var that = this;
@@ -339,9 +882,9 @@
if(that.length > 0) return that[0].offsetHeight; // 此处还需做兼容
}() : that.each(function(index, item){
that.css('height', value);
- });
+ });
};
-
+
// 添加或获取属性
Class.fn.attr = function(key, value){
var that = this;
@@ -349,16 +892,16 @@
if(that.length > 0) return that[0].getAttribute(key);
}() : that.each(function(index, item){
item.setAttribute(key, value);
- });
+ });
};
-
+
// 移除属性
Class.fn.removeAttr = function(key){
return this.each(function(index, item){
item.removeAttribute(key);
});
};
-
+
// 设置或获取 HTML 内容
Class.fn.html = function(html){
var that = this;
@@ -368,7 +911,7 @@
item.innerHTML = html;
});
};
-
+
// 设置或获取值
Class.fn.val = function(value){
var that = this;
@@ -378,50 +921,45 @@
item.value = value;
});
};
-
+
// 追加内容
Class.fn.append = function(elem){
return this.each(function(index, item){
- typeof elem === 'object'
+ typeof elem === 'object'
? item.appendChild(elem)
: item.innerHTML = item.innerHTML + elem;
});
};
-
+
// 移除内容
Class.fn.remove = function(elem){
return this.each(function(index, item){
elem ? item.removeChild(elem) : item.parentNode.removeChild(item);
});
};
-
+
// 事件绑定
- Class.fn.on = function(eventName, fn){
+ Class.fn.on = function(eventName, fn, options){
return this.each(function(index, item){
- item.attachEvent ? item.attachEvent('on' + eventName, function(e){
- e.target = e.srcElement;
- fn.call(item, e);
- }) : item.addEventListener(eventName, fn, false);
+ lay.addEvent(item, eventName, fn, options)
});
};
-
+
// 解除事件
- Class.fn.off = function(eventName, fn){
+ Class.fn.off = function(eventName, fn, options){
return this.each(function(index, item){
- item.detachEvent
- ? item.detachEvent('on'+ eventName, fn)
- : item.removeEventListener(eventName, fn, false);
+ lay.removeEvent(item, eventName, fn, options)
});
};
-
+
// export
window.lay = lay;
-
+
// 输出为 layui 模块
if(window.layui && layui.define){
layui.define(function(exports){
exports(MOD_NAME, lay);
});
}
-
-}(window, window.document); // gulp build: lay-footer
\ No newline at end of file
+
+}(window, window.document); // gulp build: lay-footer
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/laydate.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/laydate.js
index 0725bfb..8cfed9c 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/modules/laydate.js
+++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/laydate.js
@@ -1,69 +1,69 @@
-/** laydate 日期与时间控件 | MIT Licensed */
-
+/** laydate 日期与时间控件 | MIT Licensed */
+// @ts-expect-error
;!function(window, document){ // gulp build: laydate-header
"use strict";
- var isLayui = window.layui && layui.define, ready = {
- getPath: (window.lay && lay.getPath) ? lay.getPath : ''
-
+ var isLayui = window.layui && layui.define;
+ var ready = {
+ getPath: window.lay && lay.getPath ? lay.getPath : '',
+
// 载入 CSS 依赖
- ,link: function(href, fn, cssname){
-
+ link: function (href, fn, cssname) {
// 未设置路径,则不主动加载 css
- if(!laydate.path) return;
-
+ if (!laydate.path) return;
+
// 加载 css
- if(window.lay && lay.layui){
+ if (window.lay && lay.layui) {
lay.layui.link(laydate.path + href, fn, cssname);
}
}
};
-
+
// 识别预先可能定义的指定全局对象
var GLOBAL = window.LAYUI_GLOBAL || {};
// 模块名
var MOD_NAME = 'laydate';
- var MOD_ID = 'layui-'+ MOD_NAME +'-id' // 已渲染过的索引标记名
-
+ var MOD_ID = 'lay-' + MOD_NAME + '-id'; // 已渲染过的索引标记名
+
// 外部调用
var laydate = {
- v: '5.5.0' // layDate 版本号
- ,config: {
- weekStart: 0, // 默认周日一周的开始
- } // 全局配置项
- ,index: (window.laydate && window.laydate.v) ? 100000 : 0
- ,path: GLOBAL.laydate_dir || ready.getPath
-
+ v: '5.6.0', // layDate 版本号
+ config: {
+ weekStart: 0 // 默认周日一周的开始
+ }, // 全局配置项
+ index: window.laydate && window.laydate.v ? 100000 : 0,
+ path: GLOBAL.laydate_dir || ready.getPath,
+
// 设置全局项
- ,set: function(options){
+ set: function (options) {
var that = this;
that.config = lay.extend({}, that.config, options);
return that;
- }
-
+ },
+
// 主体 CSS 等待事件
- ,ready: function(callback){
+ ready: function (callback) {
var cssname = 'laydate';
- var ver = ''
- var path = (isLayui ? 'modules/' : '') + 'laydate.css?v='+ laydate.v + ver;
+ var ver = '';
+ var path = (isLayui ? 'modules/' : '') + 'laydate.css?v=' + laydate.v + ver;
isLayui ? (
- layui['layui.all']
- ? (typeof callback === 'function' && callback())
- : layui.addcss(path, callback, cssname)
+ layui['layui.all'] ?
+ (typeof callback === 'function' && callback()) :
+ layui.addcss(path, callback, cssname)
) : ready.link(path, callback, cssname);
return this;
}
};
-
+
// 操作当前实例
var thisModule = function(){
var that = this;
var options = that.config;
var id = options.id;
-
+
thisModule.that[id] = that; // 记录当前实例对象
return that.inst = {
@@ -80,14 +80,13 @@
};
// 字符常量
- var MOD_NAME = 'laydate';
var ELEM = '.layui-laydate';
var THIS = 'layui-this';
var SHOW = 'layui-show';
var HIDE = 'layui-hide';
var DISABLED = 'laydate-disabled';
var LIMIT_YEAR = [100, 200000];
-
+
var ELEM_STATIC = 'layui-laydate-static';
var ELEM_LIST = 'layui-laydate-list';
var ELEM_SELECTED = 'laydate-selected';
@@ -121,7 +120,7 @@
});
return that;
}
-
+
// 初始化属性
options = lay.extend(that.config, lay.options(elem[0])); // 继承节点上的属性
@@ -139,30 +138,30 @@
// 自增索引
options.index = that.index;
-
+
// 初始化
laydate.ready(function(){
that.init();
});
};
-
+
// 日期格式字符
var dateType = 'yyyy|y|MM|M|dd|d|HH|H|mm|m|ss|s';
-
+
// 将日期格式字符转换为数组
thisModule.formatArr = function(format){
return (format || '').match(new RegExp(dateType + '|.', 'g')) || []
};
-
+
/*
组件操作
*/
-
+
// 是否闰年
Class.isLeapYear = function(year){
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
};
-
+
// 默认配置
Class.prototype.config = {
type: 'date' //控件类型,支持:year/month/date/time/datetime
@@ -189,7 +188,7 @@
,autoConfirm: true //是否自动确认(日期|年份|月份选择器非range下是否自动确认)
,shade: 0
};
-
+
//多语言
Class.prototype.lang = function(){
var that = this
@@ -235,13 +234,27 @@
return text[options.lang] || text['cn'];
};
+ Class.prototype.markerOfChineseFestivals = {
+ '0-1-1': '元旦',
+ '0-2-14': '情人' ,
+ '0-3-8': '妇女',
+ '0-3-12': '植树',
+ '0-4-1': '愚人',
+ '0-5-1': '劳动',
+ '0-5-4': '青年',
+ '0-6-1': '儿童',
+ '0-9-10': '教师',
+ '0-10-1': '国庆',
+ '0-12-25': '圣诞'
+ }
+
// 重载实例
Class.prototype.reload = function(options){
var that = this;
that.config = lay.extend({}, that.config, options);
that.init();
};
-
+
//初始准备
Class.prototype.init = function(){
var that = this
@@ -254,10 +267,10 @@
,time: 'HH:mm:ss'
,datetime: 'yyyy-MM-dd HH:mm:ss'
};
-
+
options.elem = lay(options.elem);
options.eventElem = lay(options.eventElem);
-
+
if(!options.elem[0]) return;
layui.type(options.theme) !== 'array' && (options.theme = [options.theme]);
@@ -296,18 +309,18 @@
lay(options.range[1])
];
}
-
+
//若 type 设置非法,则初始化为 date 类型
if(!format[options.type]){
window.console && console.error && console.error('laydate type error:\''+ options.type + '\' is not supported')
options.type = 'date';
}
-
+
//根据不同 type,初始化默认 format
if(options.format === format.date){
options.format = format[options.type] || format.date;
}
-
+
//将日期格式转化成数组
that.format = thisModule.formatArr(options.format);
@@ -321,10 +334,10 @@
}
//生成正则表达式
- that.EXP_IF = '';
- that.EXP_SPLIT = '';
+ that.EXP_IF = '';
+ that.EXP_SPLIT = '';
lay.each(that.format, function(i, item){
- var EXP = new RegExp(dateType).test(item)
+ var EXP = new RegExp(dateType).test(item)
? '\\d{'+ function(){
if(new RegExp(dateType).test(that.format[i === 0 ? i + 1 : i - 1]||'')){
if(/^yyyy|y$/.test(item)) return 4;
@@ -333,7 +346,7 @@
if(/^yyyy$/.test(item)) return '1,4';
if(/^y$/.test(item)) return '1,308';
return '1,2';
- }() +'}'
+ }() +'}'
: '\\' + item;
that.EXP_IF = that.EXP_IF + EXP;
that.EXP_SPLIT = that.EXP_SPLIT + '(' + EXP + ')';
@@ -341,39 +354,25 @@
//验证日期格式正则
that.EXP_IF_ONE = new RegExp('^'+ that.EXP_IF +'$'); //验证单个日期格式
that.EXP_IF = new RegExp('^'+ (
- options.range ?
+ options.range ?
that.EXP_IF + '\\s\\'+ that.rangeStr + '\\s' + that.EXP_IF
: that.EXP_IF
) +'$');
that.EXP_SPLIT = new RegExp('^'+ that.EXP_SPLIT +'$', '');
-
+
//如果不是 input|textarea 元素,则默认采用 click 事件
if(!that.isInput(options.elem[0])){
if(options.trigger === 'focus'){
options.trigger = 'click';
}
}
-
+
// 设置唯一 KEY
options.elem.attr('lay-key', that.index);
options.eventElem.attr('lay-key', that.index);
options.elem.attr(MOD_ID, options.id); // 渲染过的标记
- //记录重要日期
- options.mark = lay.extend({}, (options.calendar && options.lang === 'cn') ? {
- '0-1-1': '元旦'
- ,'0-2-14': '情人'
- ,'0-3-8': '妇女'
- ,'0-3-12': '植树'
- ,'0-4-1': '愚人'
- ,'0-5-1': '劳动'
- ,'0-5-4': '青年'
- ,'0-6-1': '儿童'
- ,'0-9-10': '教师'
- ,'0-10-1': '国庆'
- ,'0-12-25': '圣诞'
- } : {}, options.mark);
-
+
//获取限制内日期
lay.each(['min', 'max'], function(i, item){
var ymd = [];
@@ -388,7 +387,7 @@
,hours: i ? 23 : 0
,minutes: i ? 59 : 0
,seconds: i ? 59 : 0
- }).getTime()
+ }).getTime()
,STAMP = 86400000 //代表一天的毫秒数
,thisDate = new Date(
day ? (
@@ -412,29 +411,42 @@
,seconds: hms[2] | 0
};
});
-
+
that.elemID = 'layui-laydate'+ options.elem.attr('lay-key');
-
+
if(options.show || isStatic) that.render();
isStatic || that.events();
-
+
+ // 重定义 input 元素的 get set
+ if(typeof options.formatToDisplay === 'function'){
+ if(that.isInput(options.elem[0])){
+ that.formatToDisplay(options.elem[0], options.formatToDisplay);
+ } else {
+ var rangeElem = that.rangeElem;
+ if(rangeElem){
+ that.formatToDisplay(rangeElem[0][0], options.formatToDisplay);
+ that.formatToDisplay(rangeElem[1][0], options.formatToDisplay);
+ }
+ }
+ }
+
//默认赋值
if(options.value && options.isInitValue){
if(layui.type(options.value) === 'date'){
- that.setValue(that.parse(0, that.systemDate(options.value)));
+ that.setValue(that.parse(0, that.systemDate(options.value)));
} else {
- that.setValue(options.value);
+ that.setValue(options.value);
}
}
};
-
+
//控件主体渲染
Class.prototype.render = function(){
var that = this
,options = that.config
,lang = that.lang()
,isStatic = options.position === 'static'
-
+
//主面板
,elem = that.elem = lay.elem('div', {
id: that.elemID
@@ -456,7 +468,7 @@
})()
].join('')
})
-
+
//主区域
,elemMain = that.elemMain = []
,elemHeader = that.elemHeader = []
@@ -472,9 +484,9 @@
,divShortcut = that.shortcut = lay.elem('ul', {
"class": ELEM_SHORTCUT
});
-
+
if(options.zIndex) elem.style.zIndex = options.zIndex;
-
+
//单双日历区域
lay.each(new Array(2), function(i){
if(!options.range && i > 0){
@@ -485,7 +497,7 @@
var divHeader = lay.elem('div', {
"class": 'layui-laydate-header'
})
-
+
//左右切换
,headerChild = [function(){ //上一年
var elem = lay.elem('i', {
@@ -519,19 +531,19 @@
elem.innerHTML = '';
return elem;
}()]
-
+
//日历内容区域
,divContent = lay.elem('div', {
"class": 'layui-laydate-content'
})
,table = lay.elem('table')
,thead = lay.elem('thead'), theadTr = lay.elem('tr');
-
+
//生成年月选择
lay.each(headerChild, function(i, item){
divHeader.appendChild(item);
});
-
+
//生成表格
thead.appendChild(theadTr);
lay.each(new Array(6), function(i){ //表体
@@ -547,19 +559,19 @@
});
table.insertBefore(thead, table.children[0]); //表头
divContent.appendChild(table);
-
+
elemMain[i] = lay.elem('div', {
"class": ELEM_MAIN + ' laydate-main-list-'+ i
});
-
+
elemMain[i].appendChild(divHeader);
elemMain[i].appendChild(divContent);
-
+
elemHeader.push(headerChild);
elemCont.push(divContent);
elemTable.push(table);
});
-
+
//生成底部栏
lay(divFooter).html(function(){
var html = [], btns = [];
@@ -569,7 +581,7 @@
if(!(!options.range && options.type === 'datetime') || options.fullPanel){
html.push(' ')
}
-
+
lay.each(options.btns, function(i, item){
var title = lang.tools[item] || 'btn';
if(options.range && item === 'now') return;
@@ -591,7 +603,9 @@
return shortcutBtns.join('');
}()).find('li').on('click', function (event) {
var btnSetting = options.shortcuts[this.dataset['index']] || {};
- var value = btnSetting.value || [];
+ var value = (typeof btnSetting.value === 'function'
+ ? btnSetting.value()
+ : btnSetting.value) || [];
if (!layui.isArray(value)) {
value = [value];
}
@@ -656,7 +670,7 @@
elem.appendChild(main);
});
options.showBottom && elem.appendChild(divFooter);
-
+
// 生成自定义主题
var style = lay.elem('style');
var styleText = [];
@@ -712,30 +726,30 @@
document.body.appendChild(elem)
,that.position() //定位
);
-
+
var shade = options.shade ? ('
') : '';
elem.insertAdjacentHTML('beforebegin', shade);
that.checkDate().calendar(null, 0, 'init'); //初始校验
that.changeEvent(); //日期切换
-
+
Class.thisElemDate = that.elemID;
that.renderAdditional()
typeof options.ready === 'function' && options.ready(lay.extend({}, options.dateTime, {
month: options.dateTime.month + 1
}));
-
+
that.preview();
};
-
+
//控件移除
Class.prototype.remove = function(prev){
var that = this
,options = that.config
,elem = lay('#'+ (prev || that.elemID));
if(!elem[0]) return that;
-
+
if(!elem.hasClass(ELEM_STATIC)){
that.checkDate(function(){
elem.remove();
@@ -752,7 +766,7 @@
lay('.' + ELEM_SHADE).remove();
return that;
};
-
+
//定位算法
Class.prototype.position = function(){
var that = this
@@ -762,7 +776,7 @@
});
return that;
};
-
+
// 提示
Class.prototype.hint = function(opts){
var that = this;
@@ -770,7 +784,7 @@
var div = lay.elem('div', {
"class": ELEM_HINT
});
-
+
if(!that.elem) return;
// 兼容旧版参数
@@ -781,7 +795,7 @@
content: opts
}
}
-
+
div.innerHTML = opts.content || '';
lay(that.elem).find('.'+ ELEM_HINT).remove();
that.elem.appendChild(div);
@@ -791,7 +805,7 @@
lay(that.elem).find('.'+ ELEM_HINT).remove();
}, 'ms' in opts ? opts.ms : 3000);
};
-
+
//获取递增/减后的年月
Class.prototype.getAsYM = function(Y, M, type){
type ? M-- : M++;
@@ -805,7 +819,7 @@
}
return [Y, M];
};
-
+
//系统日期
Class.prototype.systemDate = function(newDate){
var thisDate = newDate || new Date();
@@ -818,7 +832,7 @@
,seconds: newDate ? newDate.getSeconds() : 0 //秒
}
};
-
+
//日期校验
Class.prototype.checkDate = function(fn){
var that = this
@@ -827,7 +841,7 @@
,lang = that.lang()
,dateTime = options.dateTime = options.dateTime || that.systemDate()
,thisMaxDate, error
-
+
,elem = options.elem[0]
,valType = that.isInput(elem) ? 'val' : 'html'
,value = function(){
@@ -839,11 +853,11 @@
return vals.join(' ' + that.rangeStr + ' ');
}
}
- return that.isInput(elem)
- ? elem.value
+ return that.isInput(elem)
+ ? elem.value
: (options.position === 'static' ? '' : lay(elem).attr('lay-date'));
}()
-
+
//校验日期有效数字
,checkValid = function(dateTime){
if (!dateTime) {
@@ -859,13 +873,13 @@
thisMaxDate = laydate.getEndDate(dateTime.month + 1, dateTime.year);
if(dateTime.date > thisMaxDate) dateTime.date = thisMaxDate, error = true;
}
-
+
//获得初始化日期值
,initDate = function(dateTime, value, index){
var startEnd = ['startTime', 'endTime'];
value = (value.match(that.EXP_SPLIT) || []).slice(1);
index = index || 0;
-
+
if(options.range){
that[startEnd[index]] = that[startEnd[index]] || {};
}
@@ -900,7 +914,7 @@
});
checkValid(dateTime);
};
-
+
if(fn === 'limit') {
if (options.range) {
checkValid(that.rangeLinked ? that.startDate : dateTime); // 校验开始时间
@@ -910,7 +924,7 @@
}
return that;
}
-
+
value = value || options.value;
if(typeof value === 'string'){
value = value.replace(/\s+/g, ' ').replace(/^\s|\s$/g, '');
@@ -923,7 +937,7 @@
var obj = {}
,dateTime = options.dateTime
,EYM = that.getAsYM(dateTime.year, dateTime.month);
-
+
//初始右侧面板的年月
if(options.type === 'year'){
obj.year = dateTime.year + 1;
@@ -931,19 +945,19 @@
obj.year = EYM[0];
obj.month = EYM[1];
}
-
+
//初始右侧面板的时间
if(options.type === 'datetime' || options.type === 'time'){
obj.hours = 23;
obj.minutes = obj.seconds = 59;
}
-
+
return obj;
}());
}
};
getEndDate();
-
+
if(typeof value === 'string' && value){
if(that.EXP_IF.test(value)){ //校验日期格式
if(options.range){
@@ -967,13 +981,13 @@
//重置开始日期
options.dateTime = that.systemDate();
delete that.startTime;
-
+
//重置结束日期
delete that.endDate; //删除原有的结束日期
getEndDate(); //并重新获得新的结束日期
delete that.endTime;
}
-
+
//从日期范围表单中获取初始值
(function(){
if(that.rangeElem){
@@ -986,18 +1000,18 @@
});
}
})();
-
- //校验日期有效数字
+
+ // 校验日期有效数字
checkValid(dateTime);
if(options.range) checkValid(that.endDate);
- //如果初始值格式错误,则纠正初始值
+ // 如果初始值格式错误,则纠正初始值
if(error && value){
that.setValue(
options.range ? (that.endDate ? that.parse() : '') : that.parse()
);
}
-
+
//如果当前日期不在设定的最大小日期区间,则自动纠正在可选区域
//校验主面板是否在可选日期区间
var minMaxError;
@@ -1008,7 +1022,7 @@
dateTime = options.dateTime = lay.extend({}, options.min);
minMaxError = true;
}
-
+
//校验右侧面板是否在可选日期区间
if(options.range){
if(that.getDateTime(that.endDate) < that.getDateTime(options.min) || that.getDateTime(that.endDate) > that.getDateTime(options.max)){
@@ -1039,6 +1053,7 @@
that.hint('value ' + lang.invalidDate + lang.formatError[1]);
}
+ // 初始赋值 startDate,endState
that.startDate = that.startDate || value && lay.extend({}, options.dateTime); // 有默认值才初始化startDate
that.autoCalendarModel.auto && that.autoCalendarModel();
that.endState = !options.range || !that.rangeLinked || !!(that.startDate && that.endDate); // 初始化选中范围状态
@@ -1046,46 +1061,334 @@
fn && fn();
return that;
};
-
- // 公历重要日期与自定义备注
+
+ /**
+ * 渲染备注
+ * @param {JQuery} tdElem td 元素
+ * @param {[number, number, number]} YMD 年月日
+ * @param {object | string} markers 备注信息
+ */
+ Class.prototype.markRender = function(tdElem, YMD, markers){
+ var markText;
+
+ if(typeof markers === 'object'){
+ lay.each(markers || {}, function(key, title){
+ var keys = key.split('-');
+ if((keys[0] == YMD[0] || keys[0] == 0) //每年的每月
+ && (keys[1] == YMD[1] || keys[1] == 0) //每月的每日
+ && keys[2] == YMD[2]){ //特定日
+ markText = title || YMD[2];
+ }
+ });
+ }else if(typeof markers === 'string'){
+ markText = markers || YMD[2];
+ }
+
+ markText && tdElem.find('div').html(''+ markText +' ');
+ }
+
+ /**
+ * 公历重要日期与自定义备注
+ * @param {JQuery} td
+ * @param {[number, number, number]} YMD
+ * @returns Class
+ */
Class.prototype.mark = function(td, YMD){
- var that = this
- ,mark, options = that.config;
- lay.each(options.mark, function(key, title){
- var keys = key.split('-');
- if((keys[0] == YMD[0] || keys[0] == 0) //每年的每月
- && (keys[1] == YMD[1] || keys[1] == 0) //每月的每日
- && keys[2] == YMD[2]){ //特定日
- mark = title || YMD[2];
- }
- });
- mark && td.find('div').html(''+ mark +' ');
-
+ var that = this;
+ var options = that.config;
+
+ var render = function(markers){
+ that.markRender(td, YMD, markers);
+ }
+
+ if(options.calendar && options.lang === 'cn'){
+ render(that.markerOfChineseFestivals);
+ }
+
+ if(typeof options.mark === 'function'){
+ options.mark({year: YMD[0], month: YMD[1], date: YMD[2]}, render);
+ }else if(typeof options.mark === 'object'){
+ render(options.mark);
+ }
+
return that;
};
- // 标注法定节假日或补假上班
+ /**
+ * 渲染法定节假日或补假上班标记
+ * @param {JQuery} tdElem td 元素
+ * @param {[number, number, number]} YMD 年月日
+ * @param {[Array, Array] | string} markers 标记信息
+ */
+ Class.prototype.holidaysRender = function(tdElem, YMD, markers){
+ var type = ['holidays', 'workdays'];
+
+ var isEquals = function(ymdStr1, ymdStr2){
+ var ymd1 = ymdStr1.split('-');
+ var ymd2 = ymdStr2.split('-');
+
+ lay.each(ymd1, function(i,v){
+ ymd1[i] = parseInt(v, 10);
+ })
+ lay.each(ymd2, function(i,v){
+ ymd2[i] = parseInt(v, 10);
+ })
+
+ return ymd1.join('-') === ymd2.join('-');
+ }
+
+ var insertHtml = function(el, type, text){
+ el.find('div').html([
+ '',
+ text,
+ ' '
+ ].join(''));
+ }
+
+ if(layui.type(markers) === 'array'){
+ lay.each(markers, function(idx, item) {
+ lay.each(item, function(i, dayStr) {
+ if(isEquals(dayStr, tdElem.attr('lay-ymd'))){
+ insertHtml(tdElem, type[idx], YMD[2])
+ }
+ });
+ });
+ }else if(typeof markers === 'string'){
+ if(type.indexOf(markers) !== -1){
+ insertHtml(tdElem, markers, YMD[2])
+ }
+ }
+ }
+
+ /**
+ * 标注法定节假日或补假上班
+ * @param {JQuery} td
+ * @param {[number, number, number]} YMD
+ * @returns Class
+ */
Class.prototype.holidays = function(td, YMD) {
var that = this;
var options = that.config;
- var type = ['', 'work'];
- if(layui.type(options.holidays) !== 'array') return that;
-
- lay.each(options.holidays, function(idx, item) {
- lay.each(item, function(i, dayStr) {
- if(dayStr === td.attr('lay-ymd')){
- td.find('div').html('' + YMD[2] + ' ');
- }
- });
- });
+ var render = function(markers){
+ that.holidaysRender(td, YMD, markers);
+ }
+
+ if(typeof options.holidays === 'function'){
+ options.holidays({year: YMD[0], month: YMD[1], date: YMD[2]}, render);
+ }else if(layui.type(options.holidays) === 'array'){
+ render(options.holidays);
+ }
return that;
};
-
- // 无效日期范围的标记
+
+ /**
+ * 自定义单元格
+ * @param {HTMLElement|Array} el - 单元格元素
+ * @param {{year:number, month:number, date:number}} dateObj - 当前单元格对应的日期信息
+ * @param {'year' | 'month' | 'date'} panelMode - 面板模式
+ * @returns
+ */
+ Class.prototype.cellRender = function(el, dateObj, panelMode){
+ var that = this;
+ var options = that.config;
+
+ if(typeof options.cellRender === 'function'){
+ var render = function(content){
+ if(typeof content === 'string'){
+ lay(el).html(content);
+ }else if(typeof content === 'object'){
+ lay(el).html('').append(lay(content)[0]);
+ }
+ }
+ options.cellRender(dateObj, render, {originElem: el, type: panelMode})
+ }
+
+ return that;
+ }
+
+ /**
+ * 给定年份的开始日期
+ * @param {Date} date
+ */
+ Class.prototype.startOfYear = function(date){
+ var newDate = new Date(date);
+ newDate.setFullYear(newDate.getFullYear(), 0, 1);
+ newDate.setHours(0, 0, 0, 0);
+ return newDate;
+ }
+
+ /**
+ * 给定年份的结束日期
+ * @param {Date} date
+ */
+ Class.prototype.endOfYear = function(date){
+ var newDate = new Date(date);
+ var year = newDate.getFullYear();
+ newDate.setFullYear(year + 1, 0, 0);
+ newDate.setHours(23, 59, 59, 999);
+ return newDate;
+ }
+
+ /**
+ * 给定月份的开始日期
+ * @param {Date} date
+ */
+ Class.prototype.startOfMonth = function(date){
+ var newDate = new Date(date);
+ newDate.setDate(1);
+ newDate.setHours(0, 0, 0, 0);
+ return newDate;
+ }
+
+ /**
+ * 给定月份的结束日期
+ * @param {Date} date
+ */
+ Class.prototype.endOfMonth = function(date){
+ var newDate = new Date(date);
+ var month = newDate.getMonth();
+ newDate.setFullYear(newDate.getFullYear(), month + 1, 0);
+ newDate.setHours(23, 59, 59, 999);
+ return newDate;
+ }
+
+ /**
+ * 将指定的天数添加到给定日期
+ * @param {Date} date 要更改的日期
+ * @param {number} amount 天数
+ */
+ Class.prototype.addDays = function(date, amount){
+ var newDate = new Date(date);
+ if(!amount) return newDate;
+ newDate.setDate(newDate.getDate() + amount);
+ return newDate;
+ }
+
+ /**
+ * 不可选取的年或月。年或月中的所有日期都禁用时,才判定为不可选取。
+ * @param {Date} date 要检测的年或月
+ * @param {'year' | 'month'} type 面板类型
+ * @param {'start' | 'end'} position 面板位置
+ */
+ Class.prototype.isDisabledYearOrMonth = function(date, type, position){
+ var that = this;
+ var options = that.config;
+ var millisecondsInDay = 24 * 60 * 60 * 1000;
+
+ var startDay = type === 'year' ? that.startOfYear(date) : that.startOfMonth(date);
+ var endDay = type === 'year' ? that.endOfYear(date) : that.endOfMonth(date);
+ var numOfDays = Math.floor((endDay.getTime() - startDay.getTime()) / millisecondsInDay) + 1;
+ var disabledCount = 0;
+
+ for(var i = 0; i < numOfDays; i++){
+ var day = that.addDays(startDay, i);
+ if(options.disabledDate.call(options, day, position)){
+ disabledCount++;
+ }
+ }
+
+ return disabledCount === numOfDays;
+ }
+
+ /**
+ * @typedef limitOptions
+ * @prop {JQuery} [elem] - 检测的元素, 例如面板中年月日时分秒元素,“现在”,“确认” 按钮等
+ * @prop {number} [index] - 元素集合中,当前检测元素的索引,years:0,month:0,date:0-41,hms:0
+ * @prop {['hours', 'minutes', 'seconds'] | ['hours', 'minutes'] | ['hours']} [time] - 是否比较时分秒
+ * @prop {'year'|'month'|string} [type] - 面板类型?
+ * @prop {0 | 1} [rangeType] - 面板索引, 0 表示 start, 1 表示 end
+ * @prop {Partial<{year:number,month: number,date:number,hours:number,minutes:number,seconds:number}>} [date] - 检测的日期时间对象
+ * @prop {'date' | 'time' | 'datetime'} disabledType - 禁用类型,按钮应使用 datetime
+ */
+ /**
+ * 不可选取的日期
+ * @param {number} date 当前检测的日期的时间戳
+ * @param {limitOptions} opts
+ * @returns {boolean}
+ */
+ Class.prototype.isDisabledDate = function(date, opts){
+ opts = opts || {};
+
+ var that = this;
+ var options = that.config;
+ var position = options.range ? (opts.rangeType === 0 ? 'start' : 'end') : 'start';
+
+ if(!options.disabledDate) return false;
+ if(options.type === 'time') return false;
+ if(!(opts.disabledType === 'date' || opts.disabledType === 'datetime')) return false;
+
+ // 不需要时分秒
+ var normalizedDate = new Date(date);
+ normalizedDate.setHours(0, 0, 0, 0);
+
+ return opts.type === 'year' || opts.type === 'month'
+ ? that.isDisabledYearOrMonth(normalizedDate, opts.type, position)
+ : options.disabledDate.call(options, normalizedDate, position);
+ }
+
+ /**
+ * 不可选取的时间
+ * @param {number} date 当前检测的日期的时间戳
+ * @param {limitOptions} opts
+ * @returns {boolean}
+ */
+ Class.prototype.isDisabledTime = function(date, opts){
+ opts = opts || {};
+
+ var that = this;
+ var options = that.config;
+ var position = options.range ? (opts.rangeType === 0 ? 'start' : 'end') : 'start';
+
+ if(!options.disabledTime) return false;
+ if(!(options.type === "time" || options.type === "datetime")) return false;
+ if(!(opts.disabledType === 'time' || opts.disabledType === 'datetime')) return false;
+
+ var isDisabledItem = function(compareVal, rangeFn, rangeFnParam){
+ return function(){
+ return (typeof rangeFn === 'function' && rangeFn.apply(options, rangeFnParam) || []).indexOf(compareVal) !== -1;
+ }
+ }
+
+ var dateObj = that.systemDate(new Date(date));
+ var disabledTime = options.disabledTime.call(options, that.newDate(dateObj), position) || {};
+
+ // 面板中的时分秒 HTML 元素需要分别检测是否禁用
+ // 按钮检测任意一项是否禁用即可
+ return opts.disabledType === 'datetime'
+ ? isDisabledItem(dateObj.hours, disabledTime.hours)()
+ || isDisabledItem(dateObj.minutes, disabledTime.minutes, [dateObj.hours])()
+ || isDisabledItem(dateObj.seconds, disabledTime.seconds, [dateObj.hours, dateObj.minutes])()
+ : [isDisabledItem(dateObj.hours, disabledTime.hours),
+ isDisabledItem(dateObj.minutes, disabledTime.minutes, [dateObj.hours]),
+ isDisabledItem(dateObj.seconds, disabledTime.seconds, [dateObj.hours, dateObj.minutes])][opts.time.length - 1]();
+ }
+
+ /**
+ * 不可选取的日期时间
+ * @param {number} timestamp 当前检测的日期的时间戳
+ * @param {limitOptions} opts
+ * @returns
+ */
+ Class.prototype.isDisabledDateTime = function(timestamp, opts){
+ opts = opts || {};
+
+ var that = this;
+ var options = that.config;
+
+ return that.isDisabledDate(timestamp, opts) || that.isDisabledTime(timestamp, opts);
+ }
+
+
+ /**
+ * 无效日期范围的标记
+ * @param {limitOptions} opts
+ *
+ */
Class.prototype.limit = function(opts){
opts = opts || {};
@@ -1112,51 +1415,51 @@
return hms;
}())).getTime(); //time:是否比较时分秒
});
-
- isOut = timestamp.now < timestamp.min || timestamp.now > timestamp.max;
+
+ isOut = timestamp.now < timestamp.min || timestamp.now > timestamp.max || that.isDisabledDateTime(timestamp.now, opts);
opts.elem && opts.elem[isOut ? 'addClass' : 'removeClass'](DISABLED);
return isOut;
};
-
+
//当前日期对象
Class.prototype.thisDateTime = function(index){
var that = this
,options = that.config;
return index ? that.endDate: options.dateTime;
};
-
+
//日历表
Class.prototype.calendar = function(value, index, type){
+ index = index ? 1 : 0;
var that = this
,options = that.config
- ,index = index ? 1 : 0
,dateTime = value || that.thisDateTime(index)
,thisDate = new Date(), startWeek, prevMaxDate, thisMaxDate
,lang = that.lang()
-
+
,isAlone = options.type !== 'date' && options.type !== 'datetime'
,tds = lay(that.table[index]).find('td')
,elemYM = lay(that.elemHeader[index][2]).find('span');
-
+
if(dateTime.year < LIMIT_YEAR[0]) dateTime.year = LIMIT_YEAR[0], that.hint(lang.invalidDate);
if(dateTime.year > LIMIT_YEAR[1]) dateTime.year = LIMIT_YEAR[1], that.hint(lang.invalidDate);
-
+
//记录初始值
if(!that.firstDate){
that.firstDate = lay.extend({}, dateTime);
}
-
+
//计算当前月第一天的星期
thisDate.setFullYear(dateTime.year, dateTime.month, 1);
startWeek = (thisDate.getDay() + (7 - options.weekStart)) % 7;
prevMaxDate = laydate.getEndDate(dateTime.month || 12, dateTime.year); //计算上个月的最后一天
thisMaxDate = laydate.getEndDate(dateTime.month + 1, dateTime.year); //计算当前月的最后一天
-
+
//赋值日
lay.each(tds, function(index_, item){
- var YMD = [dateTime.year, dateTime.month], st = 0;
+ var YMD = [dateTime.year, dateTime.month], st;
item = lay(item);
item.removeAttr("class");
if(index_ < startWeek){
@@ -1183,14 +1486,19 @@
month: YMD[1] - 1,
date: YMD[2]
},
- index: index_
+ index: index_,
+ rangeType: index,
+ disabledType: 'date' // 日面板,检测当前日期是否禁用
});
- });
-
+ that.cellRender(item, {year: YMD[0], month: YMD[1], date: YMD[2]}, 'date');
+ });
+
//同步头部年月
lay(elemYM[0]).attr('lay-ym', dateTime.year + '-' + (dateTime.month + 1));
lay(elemYM[1]).attr('lay-ym', dateTime.year + '-' + (dateTime.month + 1));
-
+ if(!that.panelYM) that.panelYM = {};
+ that.panelYM[index] = {year: dateTime.year, month: dateTime.month};
+
if(options.lang === 'cn'){
lay(elemYM[0]).attr('lay-type', 'year').html(dateTime.year + ' 年')
lay(elemYM[1]).attr('lay-type', 'month').html((dateTime.month + 1) + ' 月');
@@ -1206,21 +1514,21 @@
that.listYM = [
[(that.startDate || options.dateTime).year, (that.startDate || options.dateTime).month + 1]
,[that.endDate.year, that.endDate.month + 1]
- ];
+ ];
that.list(options.type, 0).list(options.type, 1);
-
+
//同步按钮可点状态
options.type === 'time' ? that.setBtnStatus('时间'
,lay.extend({}, that.systemDate(), that.startTime)
,lay.extend({}, that.systemDate(), that.endTime)
) : that.setBtnStatus(true);
- }
+ }
} else {
that.listYM = [[dateTime.year, dateTime.month + 1]];
that.list(options.type, 0);
}
}
-
+
//初始赋值双日历
if(options.range && type === 'init'){
//执行渲染第二个日历
@@ -1234,7 +1542,7 @@
that.calendar(null, 1 - index);
}
}
-
+
// 通过检测当前有效日期,来设定底部按钮状态
if(!options.range){
var timeParams = ['hours', 'minutes', 'seconds'];
@@ -1242,18 +1550,20 @@
// 现在按钮
that.limit({
elem: lay(that.footer).find(ELEM_NOW),
- date: that.systemDate(),
+ date: that.systemDate(/^(datetime|time)$/.test(options.type) ? new Date() : null),
index: 0,
- time: timeParams
+ time: timeParams,
+ disabledType: 'datetime' // 按钮,检测日期和时间
});
// 确认按钮
that.limit({
elem: lay(that.footer).find(ELEM_CONFIRM),
index: 0,
- time: timeParams
+ time: timeParams,
+ disabledType: 'datetime' // 按钮,检测日期和时间
});
}
-
+
//同步按钮可点状态
that.setBtnStatus();
@@ -1273,7 +1583,7 @@
,dateTime = that.rangeLinked ? options.dateTime : [options.dateTime, that.endDate][index]
,lang = that.lang()
,isAlone = options.range && options.type !== 'date' && options.type !== 'datetime' //独立范围选择器
-
+
,ul = lay.elem('ul', {
"class": ELEM_LIST + ' ' + ({
year: 'laydate-year-list'
@@ -1287,13 +1597,13 @@
,haveList = lay(elemCont).find('.'+ ELEM_LIST)[0]
,isCN = options.lang === 'cn'
,text = isCN ? '年' : ''
-
+
,listYM = that.listYM[index] || {}
,hms = ['hours', 'minutes', 'seconds']
,startEnd = ['startTime', 'endTime'][index];
if(listYM[0] < 1) listYM[0] = 1;
-
+
//生成年列表
if(type === 'year'){
var yearNum, startY = yearNum = listYM[0] - 7;
@@ -1326,15 +1636,18 @@
elem: lay(li),
date: ymd,
index: index,
- type: type
+ type: type,
+ rangeType: index,
+ disabledType: 'date' // 年面板,检测当前年份中的所有日期是否禁用
});
+ that.cellRender(li, {year: yearNum, month: 1, date: 1}, 'year');
yearNum++;
});
lay(elemYM[isCN ? 0 : 1]).attr('lay-ym', (yearNum - 8) + '-' + listYM[1])
.html((startY + text) + ' - ' + (yearNum - 1 + text));
}
-
+
//生成月列表
else if(type === 'month'){
lay.each(new Array(12), function(i){
@@ -1363,14 +1676,17 @@
elem: lay(li),
date: ymd,
index: index,
- type: type
+ type: type,
+ rangeType: index,
+ disabledType: 'date' // 月面板,检测当前月份中的所有日期是否禁用
});
+ that.cellRender(li, {year: listYM[0], month: i + 1, date: 1}, 'month');
});
lay(elemYM[isCN ? 0 : 1]).attr('lay-ym', listYM[0] + '-' + listYM[1])
.html(listYM[0] + text);
- }
-
+ }
+
//生成时间列表
else if(type === 'time'){
//检测时分秒状态是否在有效日期时间范围内
@@ -1390,9 +1706,11 @@
,seconds: ii
}][i],
index: index,
+ rangeType: index,
+ disabledType: 'time', // 时间面板,分别检测时分秒列表是否禁用
time: [
- ['hours'],
- ['hours', 'minutes'],
+ ['hours'],
+ ['hours', 'minutes'],
['hours', 'minutes', 'seconds']
][i]
});
@@ -1402,12 +1720,29 @@
that.limit({
elem: lay(that.footer).find(ELEM_CONFIRM),
date: that[startEnd],
- inedx: 0,
- time: ['hours', 'minutes', 'seconds']
+ index: 0,
+ time: ['hours', 'minutes', 'seconds'],
+ disabledType: 'datetime' // 确认按钮,检测时分秒列表任意一项是否禁用
});
}
};
-
+
+ var setTimeListVisibility = function(){
+ var showHour = options.format.indexOf('H') !== -1;
+ var showMinute = options.format.indexOf('m') !== -1;
+ var showSecond = options.format.indexOf('s') !== -1;
+ var liElem = ul.children;
+ var hideCount = 0;
+
+ lay.each([showHour, showMinute, showSecond], function(i, isShow){
+ if(!isShow){
+ liElem[i].className += ' layui-hide';
+ hideCount++;
+ }
+ })
+ ul.className += (' laydate-time-list-hide-' + hideCount);
+ }
+
//初始化时间对象
if(options.range){
if(!that[startEnd]){
@@ -1416,7 +1751,7 @@
} else {
that[startEnd] = dateTime;
}
-
+
//生成时分秒
lay.each([24, 60, 60], function(i, item){
var li = lay.elem('li'), childUL = [''+ lang.time[i] +'
'];
@@ -1427,17 +1762,18 @@
ul.appendChild(li);
});
setTimeStatus();
+ setTimeListVisibility();
}
-
+
//插入容器
if(haveList) elemCont.removeChild(haveList);
elemCont.appendChild(ul);
-
+
//年月面板 - 选择事件
- if(type === 'year' || type === 'month'){
+ if(type === 'year' || type === 'month'){
//显示切换箭头
lay(that.elemMain[index]).addClass('laydate-ym-show');
-
+
//选中
lay(ul).find('li').on('click', function(){
var ym = lay(this).attr('lay-ym') | 0;
@@ -1450,13 +1786,13 @@
} else {
dateTime[type] = ym;
}
-
+
//当为年选择器或者年月选择器
var isYearOrMonth = options.type === 'year' || options.type === 'month';
if(isYearOrMonth){
lay(ul).find('.'+ THIS).removeClass(THIS);
lay(this).addClass(THIS);
-
+
//如果为年月选择器,点击了年列表,则切换到月选择器
if(options.type === 'month' && type === 'year'){
that.listYM[index][0] = ym;
@@ -1469,7 +1805,7 @@
}
that.setBtnStatus(); //同步按钮可点状态
-
+
//若为月选择器,只有当选择月份时才自动关闭;
//若为年选择器,选择年份即自动关闭
//且在范围未开启时
@@ -1486,7 +1822,7 @@
var span = lay.elem('span', {
"class": ELEM_TIME_TEXT
})
-
+
//滚动条定位
,scroll = function(){
lay(ul).find('ol').each(function(i){
@@ -1504,21 +1840,22 @@
});
}
,haveSpan = lay(elemHeader[2]).find('.'+ ELEM_TIME_TEXT);
-
+
scroll();
span.innerHTML = options.range ? [lang.startTime,lang.endTime][index] : lang.timeTips;
lay(that.elemMain[index]).addClass('laydate-time-show');
-
+
if(haveSpan[0]) haveSpan.remove();
elemHeader[2].appendChild(span);
- lay(ul).find('ol').each(function(i){
+ var olElem = lay(ul).find('ol');
+ olElem.each(function(i){
var ol = this;
//选择时分秒
lay(ol).find('li').on('click', function(){
var value = this.innerHTML | 0;
if(lay(this).hasClass(DISABLED)) return;
-
+
if(options.range){
that[startEnd][hms[i]] = value;
} else {
@@ -1529,80 +1866,96 @@
setTimeStatus();
scroll();
- (that.endDate || options.type === 'time' || (options.type === 'datetime' && options.fullPanel)) && that.done(null, 'change');
-
+ (that.endDate || options.type === 'time' || options.type === 'datetime') && that.done(null, 'change');
+
//同步按钮可点状态
that.setBtnStatus();
});
});
+
+ if(layui.device().mobile){
+ olElem.css({
+ overflowY: 'auto',
+ touchAction: 'pan-y'
+ })
+ }
}
-
+
return that;
};
-
+
//记录列表切换后的年月
Class.prototype.listYM = [];
-
+
//关闭列表
Class.prototype.closeList = function(){
var that = this
,options = that.config;
-
+
lay.each(that.elemCont, function(index, item){
lay(this).find('.'+ ELEM_LIST).remove();
lay(that.elemMain[index]).removeClass('laydate-ym-show laydate-time-show');
});
lay(that.elem).find('.'+ ELEM_TIME_TEXT).remove();
};
-
+
//检测结束日期是否超出开始日期
Class.prototype.setBtnStatus = function(tips, start, end){
var that = this
,options = that.config
,lang = that.lang()
- ,isOut, elemBtn = lay(that.footer).find(ELEM_CONFIRM);
- if(options.range && options.type !== 'time'){
+ ,isOut
+ ,elemBtn = lay(that.footer).find(ELEM_CONFIRM)
+ ,timeParams = options.type === 'datetime' || options.type === 'time' ? ['hours', 'minutes', 'seconds'] : undefined;
+ if(options.range){
start = start || (that.rangeLinked ? that.startDate : options.dateTime);
end = end || that.endDate;
isOut = !that.endState || that.newDate(start).getTime() > that.newDate(end).getTime();
//如果不在有效日期内,直接禁用按钮,否则比较开始和结束日期
(that.limit({
- date: start
+ date: start,
+ disabledType: 'datetime', // 按钮,检测日期和时间
+ time: timeParams,
+ rangeType: 0
}) || that.limit({
- date: end
- }))
+ date: end,
+ disabledType: 'datetime', // 按钮,检测日期和时间
+ time: timeParams,
+ rangeType: 1
+ }))
? elemBtn.addClass(DISABLED)
: elemBtn[isOut ? 'addClass' : 'removeClass'](DISABLED);
-
+
//是否异常提示
if(tips && isOut) that.hint(
typeof tips === 'string' ? lang.timeout.replace(/日期/g, tips) : lang.timeout
);
}
};
-
- //转义为规定格式的日期字符
- Class.prototype.parse = function(state, date){
- var that = this
- ,options = that.config
- ,dateTime = date || (state == 'end'
- ? lay.extend({}, that.endDate, that.endTime)
- : (
- options.range
- ? lay.extend({}, that.rangeLinked ? that.startDate : options.dateTime, that.startTime)
- : options.dateTime)
- )
- ,format = laydate.parse(dateTime, that.format, 1);
-
- //返回日期范围字符
- if(options.range && state === undefined){
+
+ // 转义为规定格式的日期字符
+ Class.prototype.parse = function(state, date) {
+ var that = this;
+ var options = that.config;
+ var startDate = (that.rangeLinked ? that.startDate : options.dateTime)
+ var dateTime = date || (
+ state == 'end' ? lay.extend({}, that.endDate, that.endTime) : (
+ options.range
+ ? lay.extend({}, startDate || options.dateTime, that.startTime)
+ : options.dateTime
+ )
+ );
+ var format = laydate.parse(dateTime, that.format, 1);
+
+ // 返回日期范围字符
+ if (options.range && state === undefined) {
return format + ' '+ that.rangeStr +' ' + that.parse('end');
}
return format;
};
-
+
//创建指定日期时间对象
Class.prototype.newDate = function(dateTime){
dateTime = dateTime || {};
@@ -1621,17 +1974,41 @@
return this.newDate(obj).getTime();
}
+ /**
+ * 格式化输入框显示值
+ * @param {HTMLInputElement} elem HTML input 元素
+ * @param {(value: string) => string} displayValueCallback
+ */
+ Class.prototype.formatToDisplay = function (elem, displayValueCallback) {
+ var that = this;
+ var props = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,'value');
+
+ Object.defineProperty(
+ elem,
+ 'value',
+ lay.extend({}, props, {
+ get: function () {
+ return this.getAttribute('lay-date');
+ },
+ set: function (value) {
+ props.set.call(this, displayValueCallback.call(that, value));
+ this.setAttribute('lay-date', value);
+ },
+ })
+ );
+ };
+
//赋值
Class.prototype.setValue = function(value){
var that = this
,options = that.config
,elem = options.elem[0];
-
+
//静态展现则不作默认赋值
if(options.position === 'static') return that;
-
+
value = value || '';
-
+
//绑定的元素是否为 input
if(that.isInput(elem)){
lay(elem).val(value);
@@ -1646,28 +2023,29 @@
rangeElem[1].val(value[1] || '');
} else {
if(lay(elem).find('*').length === 0){
- lay(elem).html(value);
+ var displayValue = typeof options.formatToDisplay === 'function' ? options.formatToDisplay(value) : value;
+ lay(elem).html(displayValue);
}
lay(elem).attr('lay-date', value);
}
}
-
+
return that;
};
-
+
//预览
Class.prototype.preview = function(){
var that = this
,options = that.config;
-
+
if(!options.isPreview) return;
-
+
var elemPreview = lay(that.elem).find('.'+ ELEM_PREVIEW)
,value = options.range ? ((that.rangeLinked ? that.endState : that.endDate) ? that.parse() : '') : that.parse();
-
+
// 显示预览
elemPreview.html(value);
-
+
// 预览颜色渐变
var oldValue = elemPreview.html();
oldValue && (elemPreview.css({
@@ -1733,7 +2111,7 @@
);
}
}
-
+
/*
* 标注区间
*/
@@ -1754,28 +2132,69 @@
});
};
- //执行 done/change 回调
+ // 执行 done/change 回调
Class.prototype.done = function(param, type){
- var that = this
- ,options = that.config
- ,start = lay.extend({}, lay.extend(options.dateTime, that.startTime))
- ,end = lay.extend({}, lay.extend(that.endDate, that.endTime))
-
+ var that = this;
+ var options = that.config;
+ var start = lay.extend({},
+ lay.extend(that.rangeLinked ? that.startDate : options.dateTime, that.startTime)
+ );
+ var end = lay.extend({}, lay.extend(that.endDate, that.endTime));
+
lay.each([start, end], function(i, item){
if(!('month' in item)) return;
lay.extend(item, {
month: item.month + 1
});
});
-
+
that.preview();
-
+
param = param || [that.parse(), start, end];
type === 'change' && that.renderAdditional();
typeof options[type || 'done'] === 'function' && options[type || 'done'].apply(options, param);
-
+
return that;
};
+
+ /**
+ * 判断日期是否存在面板,用于处理日期范围选择的一些边缘情况
+ * @param {object} datetime 日期时间对象
+ * @param {number} index - 面板索引
+ * @returns
+ */
+ Class.prototype.checkPanelDate = function(datetime, index){
+ var that = this;
+ var options = that.config;
+ // 年月范围选择不需要处理
+ if(options.type !== 'date' && options.type !== 'datetime') return;
+
+ var startPanel = index === 0;
+ var month = datetime.month + 1; // 点击的日期所在月份
+ var panelMonth = that.panelYM[index].month + 1; // 当前面板头部月份
+
+ // 边缘日期的处理
+ var firstRenderIndex = that.endState
+ // 二次点击(一般为结束日期)任意一侧面板时:
+ // 1. 左侧面板中,点击的月份属于下一个月时,应渲染右侧面板而不是左侧面板;
+ // 2. 左侧面板中,点击的月份属于上一个月时,应将两个面板都重新渲染(等效点击 prevMonth);
+ // 3. 右侧面板同理。
+ ? function() {
+ return (startPanel && month > panelMonth) || (!startPanel && month < panelMonth)
+ ? 1 - index
+ : index;
+ }()
+ // 初次点击(一般为开始日期)任意一侧面板时:
+ // 1. 让该面板自行切换,以保持日期的「选中状态」在该侧;
+ // 2. 另一侧面板则根据点击的面板进行响应式切换,以保持左右面板始终为连续月份。
+ : index;
+
+ // 为简化实现,只要点击的月份不等于当前面板顶部显示的月份时,就重新渲染两侧面板
+ return {
+ needFullRender: month !== panelMonth,
+ index: firstRenderIndex
+ }
+ }
//选择日期
Class.prototype.choose = function(td, index){
@@ -1790,7 +2209,6 @@
// 重新选择或者第一次选择
index = 0;
that.endState = false;
- that.endDate = {};
} else {
index = 1;
that.endState = true;
@@ -1801,7 +2219,7 @@
,tds = lay(that.elem).find('td')
,YMD = td.attr('lay-ymd').split('-');
-
+
YMD = {
year: YMD[0] | 0
,month: (YMD[1] | 0) - 1
@@ -1842,38 +2260,39 @@
that.startDate = lay.extend({}, dateTime); // 同步startDate
}
// 校验另外一个日期是否在有效的范围内
- if (that.endState && !that.limit({date: that.thisDateTime(1 - index)})) {
+ // 此处为范围选择的日期面板点击选中处理,所以 disabledType 为 date
+ if (that.endState && !that.limit({date: that.rangeLinked ? that.startDate : that.thisDateTime(1 - index), disabledType:'date'})) {
// 根据选择之后判断是否需要切换模式
var isChange;
if (that.endState && that.autoCalendarModel.auto) {
isChange = that.autoCalendarModel();
}
- if ((isChange || that.rangeLinked && that.endState) && that.newDate(that.startDate) > that.newDate(that.endDate)) {
+ // 判断是否反选
+ var needSwapDate = (isChange || that.rangeLinked && that.endState) && that.newDate(that.startDate) > that.newDate(that.endDate);
+ if (needSwapDate){
var isSameDate = that.startDate.year === that.endDate.year && that.startDate.month === that.endDate.month && that.startDate.date === that.endDate.date;
- // 判断是否反选
- var startDate = that.startDate;
- that.startDate = lay.extend({}, that.endDate, isSameDate ? {} : that.startTime);
+ var startDate;
+ // 如果是同一天并且出现了反选证明是时分秒出现开始时间大于结束时间的现象
+ if(isSameDate){
+ startDate = that.startTime;
+ that.startTime = that.endTime;
+ that.endTime = startDate;
+ }
+ // 当出现反向选择时(即“后点击”的日期比“先点击”的日期小),重新提取区间
+ startDate = that.startDate;
+ that.startDate = lay.extend({}, that.endDate, that.startTime);
options.dateTime = lay.extend({}, that.startDate);
- that.endDate = lay.extend({}, startDate, isSameDate ? {} : that.endTime);
- isSameDate && ( // 如果是同一天并且出现了反选证明是时分秒出现开始时间大于结束时间的现象
- startDate = that.startTime,
- that.startTime = that.endTime,
- that.endTime = startDate
- )
+ that.endDate = lay.extend({}, startDate, that.endTime);
}
isChange && (options.dateTime = lay.extend({}, that.startDate));
}
if (that.rangeLinked) {
+ // 处理日期范围选择的一些边缘情况
+ var checkState = that.checkPanelDate(dateTime, panelIndex);
var dateTimeTemp = lay.extend({}, dateTime);
- if (panelIndex && !index && !isChange) { // 处理可能出现的联动面板中点击右面板但是判定为开始日期这个时候点击头部的切换上下月第一次没有反应的问题
- // 选择了右面板但是判断之后作为开始时间
- var YM = that.getAsYM(dateTime.year, dateTime.month, 'sub');
- lay.extend(options.dateTime, {
- year: YM[0]
- ,month: YM[1]
- });
- }
- that.calendar(dateTimeTemp, panelIndex, isChange ? 'init' : null);
+ var renderMode = (isChange || (checkState && checkState.needFullRender)) ? 'init' : null;
+ var panelIdx = checkState ? checkState.index : panelIndex;
+ that.calendar(dateTimeTemp, panelIdx, renderMode);
} else {
that.calendar(null, index, isChange ? 'init' : null);
}
@@ -1886,7 +2305,7 @@
that.calendar().done(null, 'change');
}
};
-
+
//底部按钮
Class.prototype.tool = function(btn, type){
var that = this
@@ -1902,13 +2321,13 @@
options.range && that.list('time', 1);
lay(btn).attr('lay-type', 'date').html(that.lang().dateTips);
}
-
+
//选择日期
,date: function(){
that.closeList();
lay(btn).attr('lay-type', 'datetime').html(that.lang().timeTips);
}
-
+
//清空、重置
,clear: function(){
isStatic && (
@@ -1924,7 +2343,7 @@
that.setValue('');
that.done(null, 'onClear').done(['', {}, {}]).remove();
}
-
+
// 现在
,now: function(){
var thisDate = new Date();
@@ -1944,69 +2363,76 @@
isStatic && that.calendar();
that.done(null, 'onNow').done().remove();
}
-
+
//确定
,confirm: function(){
if(options.range){
- if(lay(btn).hasClass(DISABLED)) return that.hint(
- options.type === 'time' ? lang.timeout.replace(/日期/g, '时间') : lang.timeout
- );
+ if(lay(btn).hasClass(DISABLED)){
+ var isTimeout = options.type === 'time'
+ ? that.startTime && that.endTime && that.newDate(that.startTime) > that.newDate(that.endTime)
+ : that.startDate && that.endDate && that.newDate(lay.extend({},that.startDate, that.startTime || {})) > that.newDate(lay.extend({},that.endDate, that.endTime || {}));
+
+ return isTimeout
+ ? that.hint(options.type === 'time' ? lang.timeout.replace(/日期/g, '时间') : lang.timeout)
+ : that.hint(lang.invalidDate);
+ }
} else {
if(lay(btn).hasClass(DISABLED)) return that.hint(lang.invalidDate);
}
-
+
that.setValue(that.parse());
that.done(null, 'onConfirm').done().remove();
}
};
active[type] && active[type]();
};
-
+
//统一切换处理
Class.prototype.change = function(index){
var that = this
,options = that.config
,dateTime = that.thisDateTime(index)
,isAlone = options.range && (options.type === 'year' || options.type === 'month')
-
+
,elemCont = that.elemCont[index || 0]
,listYM = that.listYM[index]
- ,addSubYeay = function(type){
+ ,addSubYear = function(type){
var isYear = lay(elemCont).find('.laydate-year-list')[0]
,isMonth = lay(elemCont).find('.laydate-month-list')[0];
-
+
//切换年列表
if(isYear){
listYM[0] = type ? listYM[0] - 15 : listYM[0] + 15;
that.list('year', index);
}
-
+
if(isMonth){ //切换月面板中的年
type ? listYM[0]-- : listYM[0]++;
that.list('month', index);
}
-
+
if(isYear || isMonth){
lay.extend(dateTime, {
year: listYM[0]
});
if(isAlone) dateTime.year = listYM[0];
- options.range || that.done(null, 'change');
+ options.range || that.done(null, 'change');
options.range || that.limit({
elem: lay(that.footer).find(ELEM_CONFIRM),
date: {
year: listYM[0]
- }
+ },
+ disabledType: 'datetime' // 按钮,检测日期和时间
});
}
-
+
that.setBtnStatus();
return isYear || isMonth;
};
-
+
return {
prevYear: function(){
- if(addSubYeay('sub')) return;
+ if(addSubYear('sub')) return;
if (that.rangeLinked) {
options.dateTime.year--;
that.checkDate('limit').calendar(null, null, 'init');
@@ -2018,37 +2444,42 @@
}
}
,prevMonth: function(){
- if (that.rangeLinked) {
- dateTime = options.dateTime;
- }
- var YM = that.getAsYM(dateTime.year, dateTime.month, 'sub');
- lay.extend(dateTime, {
- year: YM[0]
- ,month: YM[1]
- });
+ // rangeLinked 模式非实时选择日期,不需要同步 options.dateTime,应根据面板显示日期切换
+ if(that.rangeLinked){
+ var panelYM = that.panelYM[0];
+ var YM = that.getAsYM(panelYM.year, panelYM.month, 'sub');
+ var dateTimeTemp = lay.extend({}, options.dateTime, that.panelYM[0], {year: YM[0], month: YM[1]});
+ that.checkDate('limit').calendar(dateTimeTemp, null, 'init');
+ }else{
+ var YM = that.getAsYM(dateTime.year, dateTime.month, 'sub');
+ lay.extend(dateTime, {
+ year: YM[0]
+ ,month: YM[1]
+ });
- that.checkDate('limit').calendar(null, null, 'init');
- if (!that.rangeLinked) {
+ that.checkDate('limit').calendar(null, null, 'init');
that.autoCalendarModel.auto ? that.choose(lay(elemCont).find('td.layui-this'), index) : that.done(null, 'change');
}
}
,nextMonth: function(){
- if (that.rangeLinked) {
- dateTime = options.dateTime;
- }
- var YM = that.getAsYM(dateTime.year, dateTime.month);
- lay.extend(dateTime, {
- year: YM[0]
- ,month: YM[1]
- });
-
- that.checkDate('limit').calendar(null, null, 'init');
- if (!that.rangeLinked) {
+ if(that.rangeLinked){
+ var panelYM = that.panelYM[0];
+ var YM = that.getAsYM(panelYM.year, panelYM.month);
+ var dateTimeTemp = lay.extend({}, options.dateTime, that.panelYM[0], {year: YM[0],month: YM[1]});
+ that.checkDate('limit').calendar(dateTimeTemp, null, 'init');
+ }else{
+ var YM = that.getAsYM(dateTime.year, dateTime.month);
+ lay.extend(dateTime, {
+ year: YM[0]
+ ,month: YM[1]
+ });
+
+ that.checkDate('limit').calendar(null, null, 'init');
that.autoCalendarModel.auto ? that.choose(lay(elemCont).find('td.layui-this'), index) : that.done(null, 'change');
}
}
,nextYear: function(){
- if(addSubYeay()) return;
+ if(addSubYear()) return;
if (that.rangeLinked) {
options.dateTime.year++;
that.checkDate('limit').calendar(null, 0, 'init');
@@ -2060,7 +2491,7 @@
}
};
};
-
+
//日期切换事件
Class.prototype.changeEvent = function(){
var that = this
@@ -2072,27 +2503,27 @@
}).on('mousedown', function(e){
lay.stope(e);
});
-
+
//年月切换
lay.each(that.elemHeader, function(i, header){
//上一年
lay(header[0]).on('click', function(e){
that.change(i).prevYear();
});
-
+
//上一月
lay(header[1]).on('click', function(e){
that.change(i).prevMonth();
});
-
+
//选择年月
lay(header[2]).find('span').on('click', function(e){
var othis = lay(this)
,layYM = othis.attr('lay-ym')
,layType = othis.attr('lay-type');
-
+
if(!layYM) return;
-
+
layYM = layYM.split('-');
that.listYM[i] = [layYM[0] | 0, layYM[1] | 0];
@@ -2104,13 +2535,13 @@
lay(header[3]).on('click', function(e){
that.change(i).nextMonth();
});
-
+
//下一年
lay(header[4]).on('click', function(e){
that.change(i).nextYear();
});
});
-
+
//点击日期
lay.each(that.table, function(i, table){
var tds = lay(table).find('td');
@@ -2118,14 +2549,14 @@
that.choose(lay(this), i);
});
});
-
+
//点击底部按钮
lay(that.footer).find('span').on('click', function(){
var type = lay(this).attr('lay-type');
that.tool(this, type);
});
};
-
+
//是否输入框
Class.prototype.isInput = function(elem){
return /input|textarea/.test(elem.tagName.toLocaleLowerCase()) || /INPUT|TEXTAREA/.test(elem.tagName);
@@ -2161,40 +2592,41 @@
delete thisModule.that[options.id];
};
};
-
+
//记录所有实例
thisModule.that = {}; //记录所有实例对象
-
+
//获取当前实例对象
thisModule.getThis = function(id){
var that = thisModule.that[id];
if(!that && isLayui) layui.hint().error(id ? (MOD_NAME +' instance with ID \''+ id +'\' not found') : 'ID argument required');
return that;
};
-
- //初始执行
+
+ // 初始执行
ready.run = function(lay){
- //绑定关闭控件事件
+ // 绑定关闭控件事件
lay(document).on('mousedown', function(e){
if(!laydate.thisId) return;
var that = thisModule.getThis(laydate.thisId);
if(!that) return;
-
+
var options = that.config;
-
+
if(
- e.target === options.elem[0] ||
+ e.target === options.elem[0] ||
e.target === options.eventElem[0] ||
- e.target === lay(options.closeStop)[0]
+ e.target === lay(options.closeStop)[0] ||
+ (options.elem[0] && options.elem[0].contains(e.target))
) return;
-
+
that.remove();
-
+
}).on('keydown', function(e){
if(!laydate.thisId) return;
var that = thisModule.getThis(laydate.thisId);
if(!that) return;
-
+
// 回车触发确认
if(that.config.position === 'static') return;
if(e.keyCode === 13){
@@ -2204,21 +2636,21 @@
}
}
});
-
+
//自适应定位
lay(window).on('resize', function(){
if(!laydate.thisId) return;
var that = thisModule.getThis(laydate.thisId);
if(!that) return;
-
+
if(!that.elem || !lay(ELEM)[0]){
return false;
}
-
+
that.position();
});
};
-
+
// 渲染 - 核心接口
laydate.render = function(options){
var inst = new Class(options);
@@ -2264,14 +2696,14 @@
// 将指定对象转化为日期值
laydate.parse = function(dateTime, format, one){
dateTime = dateTime || {};
-
+
//如果 format 是字符型,则转换为数组格式
if(typeof format === 'string'){
format = thisModule.formatArr(format);
}
-
+
format = (format || []).concat();
-
+
//转义为规定格式
lay.each(format, function(i, item){
if(/yyyy|y/.test(item)){ //年
@@ -2288,10 +2720,10 @@
format[i] = lay.digit(dateTime.seconds, item.length);
}
});
-
+
return format.join('');
};
-
+
// 得到某月的最后一天
laydate.getEndDate = function(month, year){
var thisDate = new Date();
@@ -2324,4 +2756,3 @@
);
}(window, window.document);
-
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/layer.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/layer.js
index 4b19374..f6c1fb8 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/modules/layer.js
+++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/layer.js
@@ -1,8 +1,8 @@
-/**
+/**
* layer
* 通用 Web 弹出层组件
*/
-
+//@ts-ignore
;!function(window, undefined){
"use strict";
@@ -30,10 +30,11 @@ var ready = {
removeFocus: true
},
end: {},
+ beforeEnd: {},
events: {resize: {}},
minStackIndex: 0,
minStackArr: [],
- btn: ['确定', '取消'],
+ btn: ['确定', '取消'],
// 五种原始层模式
type: ['dialog', 'page', 'iframe', 'loading', 'tips'],
@@ -258,13 +259,16 @@ doms.anim = {
doms.SHADE = 'layui-layer-shade';
doms.MOVE = 'layui-layer-move';
+var SHADE_KEY = 'LAYUI-LAYER-SHADE-KEY';
+var RECORD_HEIGHT_KEY = 'LAYUI_LAYER_CONTENT_RECORD_HEIGHT';
+
// 默认配置
Class.pt.config = {
type: 0,
shade: 0.3,
fixed: true,
move: doms[1],
- title: '信息',
+ title: '信息',
offset: 'auto',
area: 'auto',
closeBtn: 1,
@@ -377,7 +381,11 @@ Class.pt.vessel = function(conType, callback){
for(var i = 0, len = config.btn.length; i < len; i++){
button += ''+ config.btn[i] +' '
}
- return ''+ button +'
'
+ return ''+ button +'
'
}() : '')
+ (config.resize ? ' ' : '')
+ ' '
@@ -393,7 +401,22 @@ Class.pt.creat = function(){
var content = config.content;
var conType = typeof content === 'object';
var body = $('body');
-
+
+ var setAnim = function(layero){
+ // anim 兼容旧版 shift
+ if(config.shift){
+ config.anim = config.shift;
+ }
+
+ // 为兼容 jQuery3.0 的 css 动画影响元素尺寸计算
+ if(doms.anim[config.anim]){
+ var animClass = 'layer-anim '+ doms.anim[config.anim];
+ layero.addClass(animClass).one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function(){
+ $(this).removeClass(animClass);
+ });
+ }
+ }
+
// 若 id 对应的弹层已经存在,则不重新创建
if(config.id && $('.'+ doms[0]).find('#'+ config.id)[0]){
return (function(){
@@ -409,12 +432,16 @@ Class.pt.creat = function(){
} else if(options.hideOnClose){
elemShade.show();
layero.show();
+ setAnim(layero);
+ setTimeout(function(){
+ elemShade.css({opacity: elemShade.data(SHADE_KEY)});
+ }, 10);
}
})();
}
// 是否移除活动元素的焦点
- if(config.removeFocus) {
+ if(config.removeFocus && document.activeElement) {
document.activeElement.blur(); // 将原始的聚焦节点失焦
}
@@ -423,11 +450,6 @@ Class.pt.creat = function(){
config.area = config.area === 'auto' ? ['', ''] : [config.area, ''];
}
- // anim 兼容旧版 shift
- if(config.shift){
- config.anim = config.shift;
- }
-
if(layer.ie == 6){
config.fixed = false;
}
@@ -475,14 +497,16 @@ Class.pt.creat = function(){
that.layero = $('#'+ doms[0] + times);
that.shadeo = $('#'+ doms.SHADE + times);
- config.scrollbar || doms.html.css('overflow', 'hidden').attr('layer-full', times);
+ config.scrollbar || ready.setScrollbar(times);
}).auto(times);
// 遮罩
that.shadeo.css({
'background-color': config.shade[1] || '#000'
,'opacity': config.shade[0] || config.shade
+ ,'transition': config.shade[2] || ''
});
+ that.shadeo.data(SHADE_KEY, config.shade[0] || config.shade);
config.type == 2 && layer.ie == 6 && that.layero.find('iframe').attr('src', content[0]);
@@ -514,14 +538,7 @@ Class.pt.creat = function(){
layer.close(that.index);
}, config.time);
that.move().callback();
-
- // 为兼容 jQuery3.0 的 css 动画影响元素尺寸计算
- if(doms.anim[config.anim]){
- var animClass = 'layer-anim '+ doms.anim[config.anim];
- that.layero.addClass(animClass).one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function(){
- $(this).removeClass(animClass);
- });
- }
+ setAnim(that.layero);
// 记录配置信息
that.layero.data('config', config);
@@ -667,13 +684,15 @@ Class.pt.tips = function(){
};
// 辨别 tips 的方位
+ // 21 为箭头大小 8*2 + 箭头相对父元素的top偏移 5
goal.where = [function(){ // 上
goal.autoLeft();
goal.tipTop = goal.top - layArea[1] - 10;
tipsG.removeClass('layui-layer-TipsB').addClass('layui-layer-TipsT').css('border-right-color', config.tips[1]);
}, function(){ // 右
goal.tipLeft = goal.left + goal.width + 10;
- goal.tipTop = goal.top;
+ goal.tipTop = goal.top - (goal.height * 0.75 < 21 ? 21 - goal.height * 0.5 : 0);
+ goal.tipTop = Math.max(goal.tipTop, 0);
tipsG.removeClass('layui-layer-TipsL').addClass('layui-layer-TipsR').css('border-bottom-color', config.tips[1]);
}, function(){ // 下
goal.autoLeft();
@@ -681,7 +700,8 @@ Class.pt.tips = function(){
tipsG.removeClass('layui-layer-TipsT').addClass('layui-layer-TipsB').css('border-right-color', config.tips[1]);
}, function(){ // 左
goal.tipLeft = goal.left - layArea[0] - 10;
- goal.tipTop = goal.top;
+ goal.tipTop = goal.top - (goal.height * 0.75 < 21 ? 21 - goal.height * 0.5 : 0);
+ goal.tipTop = Math.max(goal.tipTop, 0);
tipsG.removeClass('layui-layer-TipsR').addClass('layui-layer-TipsL').css('border-bottom-color', config.tips[1]);
}];
goal.where[guide-1]();
@@ -839,6 +859,16 @@ Class.pt.move = function(){
return that;
};
+Class.pt.btnLoading = function(btnElem, isLoading){
+ if(isLoading){
+ var loadingTpl = '
';
+ if(btnElem.find('.layui-layer-btn-loading-icon')[0]) return;
+ btnElem.addClass('layui-layer-btn-is-loading').attr({disabled: ''}).prepend(loadingTpl);
+ }else{
+ btnElem.removeClass('layui-layer-btn-is-loading').removeAttr('disabled').find('.layui-layer-btn-loading-icon').remove();
+ }
+}
+
Class.pt.callback = function(){
var that = this, layero = that.layero, config = that.config;
that.openLayer();
@@ -855,18 +885,42 @@ Class.pt.callback = function(){
// 按钮
layero.find('.'+ doms[6]).children('a').on('click', function(){
- var index = $(this).index();
- if(index === 0){
- if(config.yes){
- config.yes(that.index, layero, that);
- } else if(config['btn1']){
- config['btn1'](that.index, layero, that);
- } else {
+ var btnElem = $(this);
+ var index = btnElem.index();
+ if(btnElem.attr('disabled')) return;
+
+ // 若为异步按钮
+ if(config.btnAsync){
+ var btnCallback = index === 0 ? (config.yes || config['btn1']) : config['btn'+(index+1)];
+ that.loading = function(isLoading){
+ that.btnLoading(btnElem, isLoading);
+ }
+
+ if(btnCallback){
+ ready.promiseLikeResolve(btnCallback.call(config, that.index, layero, that))
+ .then(function(result){
+ if(result !== false){
+ layer.close(that.index)
+ }
+ }, function(reason){
+ reason !== undefined && window.console && window.console.error('layer error hint: ' + reason);
+ });
+ }else{
layer.close(that.index);
}
- } else {
- var close = config['btn'+(index+1)] && config['btn'+(index+1)](that.index, layero, that);
- close === false || layer.close(that.index);
+ } else { // 普通按钮
+ if(index === 0){
+ if(config.yes){
+ config.yes(that.index, layero, that);
+ } else if(config['btn1']){
+ config['btn1'](that.index, layero, that);
+ } else {
+ layer.close(that.index);
+ }
+ } else {
+ var close = config['btn'+(index+1)] && config['btn'+(index+1)](that.index, layero, that);
+ close === false || layer.close(that.index);
+ }
}
});
@@ -906,6 +960,7 @@ Class.pt.callback = function(){
});
config.end && (ready.end[that.index] = config.end);
+ config.beforeEnd && (ready.beforeEnd[that.index] = $.proxy(config.beforeEnd, config, layero, that.index, that));
};
// for ie6 恢复 select
@@ -950,27 +1005,47 @@ Class.pt.openLayer = function(){
// 记录宽高坐标,用于还原
ready.record = function(layero){
if(!layero[0]) return window.console && console.error('index error');
+ var type = layero.attr('type');
+ var contentElem = layero.find('.layui-layer-content');
+ var contentRecordHeightElem = type === ready.type[2] ? contentElem.children('iframe') : contentElem;
var area = [
- layero[0].style.width || layero.width(),
- layero[0].style.height || layero.height(),
+ layero[0].style.width || ready.getStyle(layero[0], 'width'),
+ layero[0].style.height || ready.getStyle(layero[0], 'height'),
layero.position().top,
layero.position().left + parseFloat(layero.css('margin-left'))
];
layero.find('.layui-layer-max').addClass('layui-layer-maxmin');
layero.attr({area: area});
+ contentElem.data(RECORD_HEIGHT_KEY, ready.getStyle(contentRecordHeightElem[0], 'height'));
};
-ready.rescollbar = function(index){
+// 设置页面滚动条
+ready.setScrollbar = function(index){
+ doms.html.css('overflow', 'hidden').attr('layer-full', index);
+};
+
+// 恢复页面滚动条
+ready.restScrollbar = function(index){
if(doms.html.attr('layer-full') == index){
- if(doms.html[0].style.removeProperty){
- doms.html[0].style.removeProperty('overflow');
- } else {
- doms.html[0].style.removeAttribute('overflow');
- }
+ doms.html[0].style[doms.html[0].style.removeProperty
+ ? 'removeProperty'
+ : 'removeAttribute']('overflow');
doms.html.removeAttr('layer-full');
}
};
+// 类似 Promise.resolve
+ready.promiseLikeResolve = function(value){
+ var deferred = $.Deferred();
+
+ if(value && typeof value.then === 'function'){
+ value.then(deferred.resolve, deferred.reject);
+ }else{
+ deferred.resolve(value);
+ }
+ return deferred.promise();
+}
+
/** 内置成员 */
window.layer = layer;
@@ -1005,7 +1080,7 @@ layer.iframeSrc = function(index, url){
// 设定层的样式
layer.style = function(index, options, limit){
var layero = $('#'+ doms[0] + index);
- var contElem = layero.find('.layui-layer-content');
+ var contentElem = layero.find('.layui-layer-content');
var type = layero.attr('type');
var titHeight = layero.find(doms[1]).outerHeight() || 0;
var btnHeight = layero.find('.'+doms[6]).outerHeight() || 0;
@@ -1033,10 +1108,10 @@ layer.style = function(index, options, limit){
height: (typeof options.height === 'number' ? options.height : layero.height()) - titHeight - btnHeight
});
} else {
- contElem.css({
+ contentElem.css({
height: (typeof options.height === 'number' ? options.height : layero.height()) - titHeight - btnHeight
- - parseFloat(contElem.css('padding-top'))
- - parseFloat(contElem.css('padding-bottom'))
+ - parseFloat(contentElem.css('padding-top'))
+ - parseFloat(contentElem.css('padding-bottom'))
})
}
};
@@ -1097,7 +1172,7 @@ layer.min = function(index, options){
elemMin.hide();
layero.attr('type') === 'page' && layero.find(doms[4]).hide();
- ready.rescollbar(index);
+ ready.restScrollbar(index);
// 隐藏遮罩
shadeo.hide();
@@ -1107,8 +1182,11 @@ layer.min = function(index, options){
layer.restore = function(index){
var layero = $('#'+ doms[0] + index);
var shadeo = $('#'+ doms.SHADE + index);
+ var contentElem = layero.find('.layui-layer-content');
var area = layero.attr('area').split(',');
var type = layero.attr('type');
+ var options = layero.data('config') || {};
+ var contentRecordHeight = contentElem.data(RECORD_HEIGHT_KEY);
layero.removeData('maxminStatus'); // 移除最大最小状态
@@ -1125,7 +1203,16 @@ layer.restore = function(index){
layero.find('.layui-layer-max').removeClass('layui-layer-maxmin');
layero.find('.layui-layer-min').show();
type === 'page' && layero.find(doms[4]).show();
- ready.rescollbar(index);
+
+ // 恢复页面滚动条弹层打开时的状态
+ options.scrollbar ? ready.restScrollbar(index) : ready.setScrollbar(index);
+
+ // #1604
+ if(contentRecordHeight !== undefined){
+ contentElem.removeData(RECORD_HEIGHT_KEY);
+ var contentRecordHeightElem = type === ready.type[2] ? contentElem.children('iframe') : contentElem;
+ contentRecordHeightElem.css({height: contentRecordHeight});
+ }
// 恢复遮罩
shadeo.show();
@@ -1144,7 +1231,7 @@ layer.full = function(index){
ready.record(layero); // 记录当前尺寸、坐标
if(!doms.html.attr('layer-full')){
- doms.html.css('overflow','hidden').attr('layer-full', index);
+ ready.setScrollbar(index);
}
setTimeout(function(){
@@ -1168,10 +1255,10 @@ layer.title = function(name, index){
// 关闭 layer 总方法
layer.close = function(index, callback){
var layero = function(){
- var closest = $('.'+ doms[0]).find('#'+ index).closest('.'+ doms[0]);
+ var closest = $('.'+ doms[0]).children('#'+ index).closest('.'+ doms[0]);
return closest[0] ? (
- index = closest.attr('times')
- ,closest
+ index = closest.attr('times'),
+ closest
) : $('#'+ doms[0] + index)
}();
var type = layero.attr('type');
@@ -1180,83 +1267,104 @@ layer.close = function(index, callback){
if(!layero[0]) return;
- // 关闭动画
- var closeAnim = ({
- slideDown: 'layer-anim-slide-down-out',
- slideLeft: 'layer-anim-slide-left-out',
- slideUp: 'layer-anim-slide-up-out',
- slideRight: 'layer-anim-slide-right-out'
- })[options.anim] || 'layer-anim-close';
-
- // 移除主容器
- var remove = function(){
- var WRAP = 'layui-layer-wrap';
-
- // 是否关闭时隐藏弹层容器
- if(hideOnClose){
- layero.removeClass('layer-anim '+ closeAnim);
- return layero.hide();
- }
-
- // 是否为页面捕获层
- if(type === ready.type[1] && layero.attr('conType') === 'object'){
- layero.children(':not(.'+ doms[5] +')').remove();
- var wrap = layero.find('.'+WRAP);
- for(var i = 0; i < 2; i++){
- wrap.unwrap();
+ var executor = function(){
+ // 关闭动画
+ var closeAnim = ({
+ slideDown: 'layer-anim-slide-down-out',
+ slideLeft: 'layer-anim-slide-left-out',
+ slideUp: 'layer-anim-slide-up-out',
+ slideRight: 'layer-anim-slide-right-out'
+ })[options.anim] || 'layer-anim-close';
+
+ // 移除主容器
+ var remove = function(){
+ var WRAP = 'layui-layer-wrap';
+
+ // 是否关闭时隐藏弹层容器
+ if(hideOnClose){
+ layero.removeClass('layer-anim '+ closeAnim);
+ return layero.hide();
}
- wrap.css('display', wrap.data('display')).removeClass(WRAP);
+
+ // 是否为页面捕获层
+ if(type === ready.type[1] && layero.attr('conType') === 'object'){
+ layero.children(':not(.'+ doms[5] +')').remove();
+ var wrap = layero.find('.'+WRAP);
+ for(var i = 0; i < 2; i++){
+ wrap.unwrap();
+ }
+ wrap.css('display', wrap.data('display')).removeClass(WRAP);
+ } else {
+ // 低版本 IE 回收 iframe
+ if(type === ready.type[2]){
+ try {
+ var iframe = $('#'+ doms[4] + index)[0];
+ iframe.contentWindow.document.write('');
+ iframe.contentWindow.close();
+ layero.find('.'+doms[5])[0].removeChild(iframe);
+ } catch(e){}
+ }
+ layero[0].innerHTML = '';
+ layero.remove();
+ }
+
+ typeof ready.end[index] === 'function' && ready.end[index]();
+ delete ready.end[index];
+ typeof callback === 'function' && callback();
+
+ // 移除 reisze 事件
+ if(ready.events.resize[index]){
+ win.off('resize', ready.events.resize[index]);
+ delete ready.events.resize[index];
+ }
+ };
+ // 移除遮罩
+ var shadeo = $('#'+ doms.SHADE + index);
+ if((layer.ie && layer.ie < 10) || !options.isOutAnim){
+ shadeo[hideOnClose ? 'hide' : 'remove']();
+ }else{
+ shadeo.css({opacity: 0});
+ setTimeout(function(){
+ shadeo[hideOnClose ? 'hide' : 'remove']();
+ }, 350);
+ }
+
+ // 是否允许关闭动画
+ if(options.isOutAnim){
+ layero.addClass('layer-anim '+ closeAnim);
+ }
+
+ layer.ie == 6 && ready.reselect();
+ ready.restScrollbar(index);
+
+ // 记住被关闭层的最小化堆叠坐标
+ if(typeof layero.attr('minLeft') === 'string'){
+ ready.minStackIndex--;
+ ready.minStackArr.push(layero.attr('minLeft'));
+ }
+
+ if((layer.ie && layer.ie < 10) || !options.isOutAnim){
+ remove()
} else {
- // 低版本 IE 回收 iframe
- if(type === ready.type[2]){
- try {
- var iframe = $('#'+ doms[4] + index)[0];
- iframe.contentWindow.document.write('');
- iframe.contentWindow.close();
- layero.find('.'+doms[5])[0].removeChild(iframe);
- } catch(e){}
- }
- layero[0].innerHTML = '';
- layero.remove();
+ setTimeout(function(){
+ remove();
+ }, 200);
}
-
- typeof ready.end[index] === 'function' && ready.end[index]();
- delete ready.end[index];
- typeof callback === 'function' && callback();
-
- // 移除 reisze 事件
- if(ready.events.resize[index]){
- win.off('resize', ready.events.resize[index]);
- delete ready.events.resize[index];
- }
- };
- // 移除遮罩
- var removeShade = (function fn(){
- $('#'+ doms.SHADE + index)[
- hideOnClose ? 'hide' : 'remove'
- ]();
- })();
-
- // 是否允许关闭动画
- if(options.isOutAnim){
- layero.addClass('layer-anim '+ closeAnim);
}
-
- layer.ie == 6 && ready.reselect();
- ready.rescollbar(index);
-
- // 记住被关闭层的最小化堆叠坐标
- if(typeof layero.attr('minLeft') === 'string'){
- ready.minStackIndex--;
- ready.minStackArr.push(layero.attr('minLeft'));
- }
-
- if((layer.ie && layer.ie < 10) || !options.isOutAnim){
- remove()
- } else {
- setTimeout(function(){
- remove();
- }, 200);
+
+ if(!hideOnClose && typeof ready.beforeEnd[index] === 'function'){
+ ready.promiseLikeResolve(ready.beforeEnd[index]())
+ .then(function(result){
+ if(result !== false){
+ delete ready.beforeEnd[index];
+ executor();
+ }
+ }, function(reason){
+ reason !== undefined && window.console && window.console.error('layer error hint: ' + reason);
+ });
+ }else{
+ delete ready.beforeEnd[index];
+ executor();
}
};
@@ -1277,9 +1385,19 @@ layer.closeAll = function(type, callback){
};
// 根据弹层类型关闭最近打开的层
-layer.closeLast = function(type){
- type = type || 'page';
- layer.close($('.layui-layer-'+ type +':last').attr("times"));
+layer.closeLast = function(type, callback){
+ var layerIndexList = [];
+ var isArrayType = $.isArray(type);
+ $(typeof type === 'string' ? '.layui-layer-' + type : '.layui-layer').each(function(i, el){
+ var layero = $(el);
+ var shouldSkip = (isArrayType && type.indexOf(layero.attr('type')) === -1) || layero.css('display') === 'none';
+ if(shouldSkip) return true;
+ layerIndexList.push(Number(layero.attr('times')));
+ });
+ if(layerIndexList.length > 0){
+ var layerIndexMax = Math.max.apply(null, layerIndexList);
+ layer.close(layerIndexMax, callback);
+ }
};
@@ -1317,7 +1435,7 @@ layer.prompt = function(options, yes){
return layer.open($.extend({
type: 1,
- btn: ['确定','取消'],
+ btn: ['确定','取消'],
content: content,
skin: 'layui-layer-prompt' + skin('prompt'),
maxWidth: win.width(),
@@ -1330,7 +1448,7 @@ layer.prompt = function(options, yes){
yes: function(index){
var value = prompt.val();
if(value.length > (options.maxlength||500)) {
- layer.tips('最多输入'+ (options.maxlength || 500) +'个字数', prompt, {tips: 1});
+ layer.tips('最多输入'+ (options.maxlength || 500) +'个字符', prompt, {tips: 1});
} else {
yes && yes(value, index, prompt);
}
@@ -1342,9 +1460,9 @@ layer.prompt = function(options, yes){
layer.tab = function(options){
options = options || {};
- var tab = options.tab || {}
- ,THIS = 'layui-this'
- ,success = options.success;
+ var tab = options.tab || {};
+ var THIS = 'layui-this';
+ var success = options.success;
delete options.success;
@@ -1387,10 +1505,16 @@ layer.tab = function(options){
}, options));
};
-// 相册层
+// 图片层
layer.photos = function(options, loop, key){
var dict = {};
- options = options || {};
+
+ // 默认属性
+ options = $.extend(true, {
+ toolbar: true,
+ footer: true
+ }, options);
+
if(!options.photos) return;
// 若 photos 并非选择器或 jQuery 对象,则为普通 object
@@ -1398,11 +1522,10 @@ layer.photos = function(options, loop, key){
var photos = isObject ? options.photos : {};
var data = photos.data || [];
var start = photos.start || 0;
+ var success = options.success;
dict.imgIndex = (start|0) + 1;
options.img = options.img || 'img';
-
- var success = options.success;
delete options.success;
// 若 options.photos 不是一个对象
@@ -1439,10 +1562,9 @@ layer.photos = function(options, loop, key){
});
// 不直接弹出
- if(!loop) return;
-
+ if (!loop) return;
} else if (data.length === 0){
- return layer.msg('没有图片');
+ return layer.msg('没有图片');
}
// 上一张
@@ -1486,28 +1608,128 @@ layer.photos = function(options, loop, key){
layer.close(dict.index);
return layer.photos(options, true, key);
}
+
+ dict.isNumber = function (n) {
+ return typeof n === 'number' && !isNaN(n);
+ }
+
+ dict.image = {};
+
+ dict.getTransform = function(opts){
+ var transforms = [];
+ var rotate = opts.rotate;
+ var scaleX = opts.scaleX;
+ var scale = opts.scale;
+
+ if (dict.isNumber(rotate) && rotate !== 0) {
+ transforms.push('rotate(' + rotate + 'deg)');
+ }
+
+ if (dict.isNumber(scaleX) && scaleX !== 1) {
+ transforms.push('scaleX(' + scaleX + ')');
+ }
+
+ if (dict.isNumber(scale)) {
+ transforms.push('scale(' + scale + ')');
+ }
+
+ return transforms.length ? transforms.join(' ') : 'none';
+ }
// 一些动作
- dict.event = function(){
- /*
- dict.bigimg.hover(function(){
- dict.imgsee.show();
- }, function(){
- dict.imgsee.hide();
- });
- */
-
- dict.bigimg.find('.layui-layer-imgprev').on('click', function(event){
+ dict.event = function(layero, index, that){
+ // 上一张
+ dict.main.find('.layui-layer-photos-prev').on('click', function(event){
event.preventDefault();
dict.imgprev(true);
});
- dict.bigimg.find('.layui-layer-imgnext').on('click', function(event){
+ // 下一张
+ dict.main.find('.layui-layer-photos-next').on('click', function(event){
event.preventDefault();
dict.imgnext(true);
});
$(document).on('keyup', dict.keyup);
+
+ // 头部工具栏事件
+ layero.off('click').on('click','*[toolbar-event]', function () {
+ var othis = $(this);
+ var event = othis.attr('toolbar-event');
+ switch (event) {
+ case 'rotate':
+ dict.image.rotate = ((dict.image.rotate || 0) + Number(othis.attr('data-option'))) % 360;
+ dict.imgElem.css({
+ transform: dict.getTransform(dict.image)
+ });
+ break;
+ case 'scalex':
+ dict.image.scaleX = dict.image.scaleX === -1 ? 1 : -1;
+ dict.imgElem.css({
+ transform: dict.getTransform(dict.image)
+ });
+ break;
+ case 'zoom':
+ var ratio = Number(othis.attr('data-option'));
+ dict.image.scale = (dict.image.scale || 1) + ratio;
+ // 缩小状态最小值
+ if (ratio < 0 && dict.image.scale < 0 - ratio) {
+ dict.image.scale = 0 - ratio;
+ }
+ dict.imgElem.css({
+ transform: dict.getTransform(dict.image)
+ });
+ break;
+ case 'reset':
+ dict.image.scaleX = 1;
+ dict.image.scale = 1;
+ dict.image.rotate = 0;
+ dict.imgElem.css({
+ transform: 'none'
+ });
+ break;
+ case 'close':
+ layer.close(index);
+ break;
+ }
+ that.offset();
+ that.auto(index);
+ });
+
+ // 鼠标滚轮缩放图片事件
+ dict.main.on('mousewheel DOMMouseScroll', function(e) {
+ var delta = e.originalEvent.wheelDelta || -e.originalEvent.detail;
+ var zoomElem = dict.main.find('[toolbar-event="zoom"]');
+ if (delta > 0) {
+ zoomElem.eq(0).trigger('click');
+ } else {
+ zoomElem.eq(1).trigger('click');
+ }
+ e.preventDefault();
+ });
+
+ // 滑动切换图片事件,仅限 layui 中
+ if(window.layui || window.lay){
+ var lay = window.layui.lay || window.lay;
+ var touchEndCallback = function(e, state){
+ var duration = Date.now() - state.timeStart;
+ var speed = state.distanceX / duration;
+ var threshold = win.width() / 3;
+ var shouldSwipe = Math.abs(speed) > 0.25 || Math.abs(state.distanceX) > threshold;
+ if(!shouldSwipe) return;
+ if(state.direction === 'left'){
+ dict.imgnext(true);
+ }else if(state.direction === 'right'){
+ dict.imgprev(true);
+ }
+ }
+
+ $.each([that.shadeo, dict.main], function(i, elem){
+ lay.touchSwipe(elem, {
+ onTouchEnd: touchEndCallback
+ })
+ })
+ }
};
// 图片预加载
@@ -1528,7 +1750,7 @@ layer.photos = function(options, loop, key){
}
dict.loadi = layer.load(1, {
- shade: 'shade' in options ? false : 0.9,
+ shade: 'shade' in options ? false : [0.9, undefined, 'unset'],
scrollbar: false
});
@@ -1559,52 +1781,65 @@ layer.photos = function(options, loop, key){
imgarea[1] = imgarea[1]/wh[1];
}
}
-
+
return [imgarea[0]+'px', imgarea[1]+'px'];
}(),
title: false,
- shade: 0.9,
+ shade: [0.9, undefined, 'unset'],
shadeClose: true,
closeBtn: false,
- move: '.layui-layer-phimg img',
+ move: '.layer-layer-photos-main img',
moveType: 1,
scrollbar: false,
moveOut: true,
anim: 5,
isOutAnim: false,
skin: 'layui-layer-photos' + skin('photos'),
- content: '
'
- + '
'
+ content: '
'
+ + '
'
+ function(){
- var arr = ['
'];
+ var arr = ['
'];
// 左右箭头翻页
- if(data.length > 1){
- arr.push(['
'
- ,' '
- ,' '
- ,'
'].join(''));
+ if (data.length > 1) {
+ arr.push(['
',
+ ' ',
+ ' ',
+ '
'].join(''));
+ }
+
+ // 头部工具栏
+ if (options.toolbar) {
+ arr.push([
+ ''
+ ].join(''));
}
// 底部栏
- if(!options.hideFooter){
- arr.push(['
'
- ,'
'
- ,'
'+ alt +' '
- ,'
'+ dict.imgIndex +' / '+ data.length +' '
- ,'
查看原图 '
- ,'
'
- ,'
'].join(''));
+ if (options.footer) {
+ arr.push([''].join(''));
}
arr.push('
');
return arr.join('');
}()
+'
',
- success: function(layero, index){
- dict.bigimg = layero.find('.layui-layer-phimg');
- dict.imgsee = layero.find('.layui-layer-imgbar');
- dict.event(layero);
+ success: function(layero, index, that){
+ dict.main = layero.find('.layer-layer-photos-main');
+ dict.footer = layero.find('.layui-layer-photos-footer');
+ dict.imgElem = dict.main.children('img');
+ dict.event(layero, index, that);
options.tab && options.tab(data[start], layero);
typeof success === 'function' && success(layero);
}, end: function(){
@@ -1614,9 +1849,9 @@ layer.photos = function(options, loop, key){
}, options));
}, function(){
layer.close(dict.loadi);
- layer.msg('当前图片地址异常
是否继续查看下一张?', {
+ layer.msg('当前图片地址异常,
是否继续查看下一张?', {
time: 30000,
- btn: ['下一张', '不看了'],
+ btn: ['下一张', '不看了'],
yes: function(){
data.length > 1 && dict.imgnext(true,true);
}
@@ -1628,6 +1863,23 @@ layer.photos = function(options, loop, key){
ready.run = function(_$){
$ = _$;
win = $(window);
+
+ // 移动端兼容性处理
+ // https://gitee.com/layui/layui/issues/I81WGC
+ // https://github.com/jquery/jquery/issues/1729
+ var agent = navigator.userAgent.toLowerCase();
+ var isMobile = /android|iphone|ipod|ipad|ios/.test(agent)
+ var _win = $(window);
+ if(isMobile){
+ $.each({Height: "height", Width: "width"}, function(propSuffix, funcName){
+ var propName = 'inner' + propSuffix;
+ win[funcName] = function(){
+ return propName in window
+ ? window[propName]
+ : _win[funcName]()
+ }
+ })
+ }
doms.html = $('html');
layer.open = function(deliver){
var o = new Class(deliver);
@@ -1638,7 +1890,7 @@ ready.run = function(_$){
// 加载方式
window.layui && layui.define ? (
layer.ready(),
- layui.define('jquery', function(exports){ // layui
+ layui.define(['jquery','lay'], function(exports){ // layui
layer.path = layui.cache.dir;
ready.run(layui.$);
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/laypage.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/laypage.js
index c0d44d9..12c7404 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/modules/laypage.js
+++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/laypage.js
@@ -5,22 +5,23 @@
layui.define(function(exports){
"use strict";
- var doc = document
- ,id = 'getElementById'
- ,tag = 'getElementsByTagName'
+ var doc = document;
+ var id = 'getElementById';
+ var tag = 'getElementsByTagName';
- //字符常量
- ,MOD_NAME = 'laypage', DISABLED = 'layui-disabled'
+ // 字符常量
+ var MOD_NAME = 'laypage';
+ var DISABLED = 'layui-disabled';
- //构造器
- ,Class = function(options){
+ // 构造器
+ var Class = function(options){
var that = this;
that.config = options || {};
that.config.index = ++laypage.index;
that.render(true);
};
- //判断传入的容器类型
+ // 判断传入的容器类型
Class.prototype.type = function(){
var config = this.config;
if(typeof config.elem === 'object'){
@@ -54,7 +55,7 @@ layui.define(function(exports){
// 默认条数
config.limit = Number(config.limit) || 10;
- //总页数
+ // 总页数
config.pages = Math.ceil(config.count/config.limit) || 1;
// 当前页不能超过总页数
@@ -64,126 +65,147 @@ layui.define(function(exports){
config.curr = 1;
}
- //连续分页个数不能低于 0 且不能大于总页数
+ // 连续分页个数不能低于 0 且不能大于总页数
if(groups < 0){
groups = 1;
} else if (groups > config.pages){
groups = config.pages;
}
- config.prev = 'prev' in config ? config.prev : '上一页'; //上一页文本
- config.next = 'next' in config ? config.next : '下一页'; //下一页文本
+ config.prev = 'prev' in config ? config.prev : '上一页'; // 上一页文本
+ config.next = 'next' in config ? config.next : '下一页'; // 下一页文本
- //计算当前组
+ // 计算当前组
var index = config.pages > groups
? Math.ceil( (config.curr + (groups > 1 ? 1 : 0)) / (groups > 0 ? groups : 1) )
- : 1
+ : 1;
- //视图片段
- ,views = {
- //上一页
+ // 视图片段
+ var views = {
+ // 上一页
prev: function(){
return config.prev
? '
'+ config.prev +' '
: '';
- }()
+ }(),
- //页码
- ,page: function(){
+ // 页码
+ page: function(){
var pager = [];
- //数据量为0时,不输出页码
+ // 数据量为0时,不输出页码
if(config.count < 1){
return '';
}
- //首页
+ // 首页
if(index > 1 && config.first !== false && groups !== 0){
- pager.push('
'+ (config.first || 1) +' ');
+ pager.push('
'+ (config.first || 1) +' ');
}
- //计算当前页码组的起始页
- var halve = Math.floor((groups-1)/2) //页码数等分
- ,start = index > 1 ? config.curr - halve : 1
- ,end = index > 1 ? (function(){
+ // 计算当前页码组的起始页
+ var halve = Math.floor((groups-1)/2) // 页码数等分
+ var start = index > 1 ? config.curr - halve : 1;
+ var end = index > 1 ? (function(){
var max = config.curr + (groups - halve - 1);
return max > config.pages ? config.pages : max;
}()) : groups;
- //防止最后一组出现“不规定”的连续页码数
+ // 防止最后一组出现“不规定”的连续页码数
if(end - start < groups - 1){
start = end - groups + 1;
}
- //输出左分割符
+ // 输出左分割符
if(config.first !== false && start > 2){
- pager.push('
… ')
+ pager.push('
... ')
}
- //输出连续页码
+ // 输出连续页码
for(; start <= end; start++){
if(start === config.curr){
- //当前页
+ // 当前页
pager.push('
'+ start +' ');
} else {
pager.push('
'+ start +' ');
}
}
- //输出输出右分隔符 & 末页
+ // 输出输出右分隔符 & 末页
if(config.pages > groups && config.pages > end && config.last !== false){
if(end + 1 < config.pages){
- pager.push('
… ');
+ pager.push('
... ');
}
if(groups !== 0){
- pager.push('
'+ (config.last || config.pages) +' ');
+ pager.push('
'+ (config.last || config.pages) +' ');
}
}
return pager.join('');
- }()
+ }(),
- //下一页
- ,next: function(){
+ // 下一页
+ next: function(){
return config.next
? '
'+ config.next +' '
: '';
- }()
+ }(),
- //数据总数
- ,count: '
共 '+ config.count +' 条 '
+ // 数据总数
+ count: function(){
+ var countText = typeof config.countText === 'object' ? config.countText : ['共 ', ' 条'];
+ return '
'+ countText[0] + config.count + countText[1] +' '
+ }(),
- //每页条数
- ,limit: function(){
- var options = ['
'];
+ // 每页条数
+ limit: function(){
+ var elemArr = [''];
+ var template = function(item) {
+ var def = item +' 条/页';
+ return typeof config.limitTemplet === 'function'
+ ? (config.limitTemplet(item) || def)
+ : def;
+ };
+
+ // 条目选项列表
layui.each(config.limits, function(index, item){
- options.push(
- ''+ item +' 条/页 '
+ elemArr.push(
+ ''
+ + template(item)
+ + ' '
);
});
- return options.join('') +' ';
- }()
-
- //刷新当前页
- ,refresh: [''
- ,' '
- ,' '].join('')
- //跳页区域
- ,skip: function(){
- return ['到第'
- ,' '
- ,'页确定 '
- ,' '].join('');
+ return elemArr.join('') +' ';
+ }(),
+
+ // 刷新当前页
+ refresh: [
+ '
',
+ ' ',
+ ' '
+ ].join(''),
+
+ // 跳页区域
+ skip: function(){
+ var skipText = typeof config.skipText === 'object' ? config.skipText : [
+ '到第',
+ '页',
+ '确定'
+ ];
+ return [
+ '
'+ skipText[0],
+ ' ',
+ skipText[1]+ ''+ skipText[2] +' ',
+ ' '
+ ].join('');
}()
};
return ['
'
- ,function(){
+ ) : 'default') +'" id="layui-laypage-'+ config.index +'">',
+ function(){
var plate = [];
layui.each(config.layout, function(index, item){
if(views[item]){
@@ -191,20 +213,21 @@ layui.define(function(exports){
}
});
return plate.join('');
- }()
- ,'
'].join('');
+ }(),
+ '
'].join('');
};
- //跳页的回调
+ // 跳页的回调
Class.prototype.jump = function(elem, isskip){
if(!elem) return;
- var that = this
- ,config = that.config
- ,childs = elem.children
- ,btn = elem[tag]('button')[0]
- ,input = elem[tag]('input')[0]
- ,select = elem[tag]('select')[0]
- ,skip = function(){
+
+ var that = this;
+ var config = that.config;
+ var childs = elem.children;
+ var btn = elem[tag]('button')[0];
+ var input = elem[tag]('input')[0];
+ var select = elem[tag]('select')[0];
+ var skip = function(){
var curr = Number(input.value.replace(/\s|\D/g, ''));
if(curr){
config.curr = curr;
@@ -214,7 +237,7 @@ layui.define(function(exports){
if(isskip) return skip();
- //页码
+ // 页码
for(var i = 0, len = childs.length; i < len; i++){
if(childs[i].nodeName.toLowerCase() === 'a'){
laypage.on(childs[i], 'click', function(){
@@ -226,7 +249,7 @@ layui.define(function(exports){
}
}
- //条数
+ // 条数
if(select){
laypage.on(select, 'change', function(){
var value = this.value;
@@ -238,7 +261,7 @@ layui.define(function(exports){
});
}
- //确定
+ // 确定
if(btn){
laypage.on(btn, 'click', function(){
skip();
@@ -246,15 +269,22 @@ layui.define(function(exports){
}
};
- //输入页数字控制
+ // 输入页数字控制
Class.prototype.skip = function(elem){
if(!elem) return;
- var that = this, input = elem[tag]('input')[0];
+
+ var that = this;
+ var input = elem[tag]('input')[0];
+
if(!input) return;
+
+ // 键盘事件
laypage.on(input, 'keyup', function(e){
- var value = this.value
- ,keyCode = e.keyCode;
+ var value = this.value;
+ var keyCode = e.keyCode;
+
if(/^(37|38|39|40)$/.test(keyCode)) return;
+
if(/\D/.test(value)){
this.value = value.replace(/\D/, '');
}
@@ -264,12 +294,12 @@ layui.define(function(exports){
});
};
- //渲染分页
+ // 渲染分页
Class.prototype.render = function(load){
- var that = this
- ,config = that.config
- ,type = that.type()
- ,view = that.view();
+ var that = this;
+ var config = that.config;
+ var type = that.type();
+ var view = that.view();
if(type === 2){
config.elem && (config.elem.innerHTML = view);
@@ -293,16 +323,16 @@ layui.define(function(exports){
that.skip(elem);
};
- //外部接口
+ // 外部接口
var laypage = {
- //分页渲染
+ // 分页渲染
render: function(options){
var o = new Class(options);
return o.index;
- }
- ,index: layui.laypage ? (layui.laypage.index + 10000) : 0
- ,on: function(elem, even, fn){
- elem.attachEvent ? elem.attachEvent('on'+ even, function(e){ //for ie
+ },
+ index: layui.laypage ? (layui.laypage.index + 10000) : 0,
+ on: function(elem, even, fn){
+ elem.attachEvent ? elem.attachEvent('on'+ even, function(e){ // for ie
e.target = e.srcElement;
fn.call(elem, e);
}) : elem.addEventListener(even, fn, false);
@@ -311,4 +341,4 @@ layui.define(function(exports){
}
exports(MOD_NAME, laypage);
-});
\ No newline at end of file
+});
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/laytpl.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/laytpl.js
index 161262c..0e67d9a 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/modules/laytpl.js
+++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/laytpl.js
@@ -1,4 +1,4 @@
-/**
+/**
* laytpl 轻量模板引擎
*/
@@ -12,11 +12,11 @@ layui.define(function(exports){
};
// 模板工具
- var tool = {
+ var tool = {
escape: function(html){
var exp = /[<"'>]|&(?=#[a-zA-Z0-9]+)/g;
if(html === undefined || html === null) return '';
-
+
html += '';
if(!exp.test(html)) return html;
@@ -77,12 +77,12 @@ layui.define(function(exports){
// 模板必须为 string 类型
if(typeof template !== 'string') return template;
-
+
// 正则解析
template = template.replace(/\s+|\r|\t|\n/g, ' ')
.replace(inner.exp(options.open +'#'), options.open +'# ')
.replace(inner.exp(options.close +'}'), '} '+ options.close).replace(/\\/g, '\\\\')
-
+
// 不匹配指定区域的内容
.replace(inner.exp(options.open + '!(.+?)!' + options.close), function(str){
str = str.replace(inner.exp('^'+ options.open + '!'), '')
@@ -92,13 +92,13 @@ layui.define(function(exports){
});
return str
})
-
+
// 匹配 JS 语法
.replace(/(?="|')/g, '\\').replace(that.tagExp(), function(str){
str = str.replace(jss, '').replace(jsse, '');
return '";' + str.replace(/\\(.)/g, '$1') + ';view+="';
})
-
+
// 匹配普通输出语句
.replace(that.tagExp(1), function(str){
var start = '"+laytpl.escape(';
@@ -114,10 +114,14 @@ layui.define(function(exports){
}
return start + str.replace(/\\(.)/g, '$1') + ')+"';
});
-
+
template = '"use strict";var view = "' + template + '";return view;';
try {
+ /**
+ * 请注意: 开发者在使用模板语法时,需确保模板中的 JS 语句不来自于页面用户输入。
+ * 即模板中的 JS 语句必须在页面开发者自身的可控范围内,否则请避免使用该模板解析。
+ */
that.cache = template = new Function('d, laytpl', template);
return template(data, tool);
} catch(e) {
@@ -132,7 +136,7 @@ layui.define(function(exports){
var that = this;
var result = that.cache ? that.cache(data, tool) : that.parse(that.template, data);
-
+
// 返回渲染结果
typeof callback === 'function' && callback(result);
return result;
@@ -152,7 +156,7 @@ layui.define(function(exports){
};
laytpl.v = '2.0.0';
-
+
// export
exports('laytpl', laytpl);
-});
\ No newline at end of file
+});
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/rate.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/rate.js
index 23d7faf..842a808 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/modules/rate.js
+++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/rate.js
@@ -10,42 +10,47 @@ layui.define(['jquery', 'lay'],function(exports){
// 外部接口
var rate = {
- config: {}
- ,index: layui.rate ? (layui.rate.index + 10000) : 0
+ config: {},
+ index: layui.rate ? (layui.rate.index + 10000) : 0,
//设置全局项
- ,set: function(options){
+ set: function(options){
var that = this;
that.config = $.extend({}, that.config, options);
return that;
- }
-
+ },
+
//事件
- ,on: function(events, callback){
+ on: function(events, callback){
return layui.onevent.call(this, MOD_NAME, events, callback);
}
}
// 操作当前实例
- ,thisRate = function(){
- var that = this
- ,options = that.config;
-
+ var thisRate = function () {
+ var that = this;
+ var options = that.config;
+
return {
- setvalue: function(value){
+ setvalue: function (value) {
that.setvalue.call(that, value);
- }
- ,config: options
+ },
+ config: options
}
- }
+ };
//字符常量
- ,MOD_NAME = 'rate',ELEM_VIEW = 'layui-rate', ICON_RATE = 'layui-icon-rate', ICON_RATE_SOLID = 'layui-icon-rate-solid', ICON_RATE_HALF = 'layui-icon-rate-half'
-
- ,ICON_SOLID_HALF = 'layui-icon-rate-solid layui-icon-rate-half', ICON_SOLID_RATE = 'layui-icon-rate-solid layui-icon-rate', ICON_HALF_RATE = 'layui-icon-rate layui-icon-rate-half'
+ var MOD_NAME = 'rate';
+ var ELEM_VIEW = 'layui-rate';
+ var ICON_RATE = 'layui-icon-rate';
+ var ICON_RATE_SOLID = 'layui-icon-rate-solid';
+ var ICON_RATE_HALF = 'layui-icon-rate-half';
+ var ICON_SOLID_HALF = 'layui-icon-rate-solid layui-icon-rate-half';
+ var ICON_SOLID_RATE = 'layui-icon-rate-solid layui-icon-rate';
+ var ICON_HALF_RATE = 'layui-icon-rate layui-icon-rate-half';
//构造器
- ,Class = function(options){
+ var Class = function (options) {
var that = this;
that.index = ++rate.index;
that.config = $.extend({}, that.config, rate.config, options);
@@ -54,19 +59,19 @@ layui.define(['jquery', 'lay'],function(exports){
//默认配置
Class.prototype.config = {
- length: 5 //初始长度
- ,text: false //是否显示评分等级
- ,readonly: false //是否只读
- ,half: false //是否可以半星
- ,value: 0 //星星选中个数
- ,theme: ''
+ length: 5, //初始长度
+ text: false, //是否显示评分等级
+ readonly: false, //是否只读
+ half: false, //是否可以半星
+ value: 0, //星星选中个数
+ theme: '' //主题颜色
};
//评分渲染
Class.prototype.render = function(){
var that = this;
var options = that.config;
-
+
// 若 elem 非唯一,则拆分为多个实例
var elem = $(options.elem);
if(elem.length > 1){
@@ -83,9 +88,9 @@ layui.define(['jquery', 'lay'],function(exports){
// 自定义主题
var style = options.theme ? ('style="color: '+ options.theme + ';"') : '';
-
+
options.elem = $(options.elem);
-
+
//最大值不能大于总长度
if(options.value > options.length){
options.value = options.length;
@@ -114,14 +119,14 @@ layui.define(['jquery', 'lay'],function(exports){
temp += '' + (options.text ? ('
'+ options.value + '星') : '') + ' ';
//开始插入替代元素
- var othis = options.elem
- ,hasRender = othis.next('.' + ELEM_VIEW);
-
+ var othis = options.elem;
+ var hasRender = othis.next('.' + ELEM_VIEW);
+
//生成替代元素
hasRender[0] && hasRender.remove(); //如果已经渲染,则Rerender
that.elemTemp = $(temp);
-
+
options.span = that.elemTemp.next('span');
options.setText && options.setText(options.value);
@@ -131,14 +136,14 @@ layui.define(['jquery', 'lay'],function(exports){
othis.addClass("layui-inline");
//如果不是只读,那么进行触控事件
- if(!options.readonly) that.action();
+ if(!options.readonly) that.action();
};
//评分重置
Class.prototype.setvalue = function(value){
- var that = this
- ,options = that.config ;
+ var that = this;
+ var options = that.config;
options.value = value ;
that.render();
@@ -146,14 +151,15 @@ layui.define(['jquery', 'lay'],function(exports){
//li触控事件
Class.prototype.action = function(){
- var that = this
- ,options = that.config
- ,_ul = that.elemTemp
- ,wide = _ul.find("i").width();
+ var that = this;
+ var options = that.config;
+ var _ul = that.elemTemp;
+ var wide = _ul.find("i").width();
+ var liElems = _ul.children("li");
- _ul.children("li").each(function(index){
- var ind = index + 1
- ,othis = $(this);
+ liElems.each(function(index){
+ var ind = index + 1;
+ var othis = $(this);
//点击
othis.on('click', function(e){
@@ -175,7 +181,7 @@ layui.define(['jquery', 'lay'],function(exports){
//移入
othis.on('mousemove', function(e){
- _ul.find("i").each(function(){
+ _ul.find("i").each(function(){
$(this).addClass(ICON_RATE).removeClass(ICON_SOLID_HALF)
});
_ul.find("i:lt(" + ind + ")").each(function(){
@@ -187,7 +193,7 @@ layui.define(['jquery', 'lay'],function(exports){
if(x <= wide / 2){
othis.children("i").addClass(ICON_RATE_HALF).removeClass(ICON_RATE_SOLID)
}
- }
+ }
})
//移出
@@ -201,18 +207,68 @@ layui.define(['jquery', 'lay'],function(exports){
//如果设置可选半星,根据分数判断是否有半星
if(options.half){
if(parseInt(options.value) !== options.value){
- _ul.children("li:eq(" + Math.floor(options.value) + ")").children("i").addClass(ICON_RATE_HALF).removeClass(ICON_SOLID_RATE)
+ _ul.children("li:eq(" + Math.floor(options.value) + ")").children("i").addClass(ICON_RATE_HALF).removeClass(ICON_SOLID_RATE)
}
- }
+ }
})
})
+
+ lay.touchSwipe(_ul, {
+ onTouchMove: function(e, state){
+ if(Date.now() - state.timeStart <= 200) return;
+ var pageX = e.touches[0].pageX;
+ var rateElemWidth = _ul.width();
+ var itemElemWidth = rateElemWidth / options.length; // 单颗星的宽度
+ var offsetX = pageX - _ul.offset().left;
+ var num = offsetX / itemElemWidth; // 原始值
+ var remainder = num % 1;
+ var integer = num - remainder;
+
+ // 最终值
+ var score = remainder <= 0.5 && options.half ? integer + 0.5 : Math.ceil(num);
+ if(score > options.length) score = options.length;
+ if(score < 0) score = 0;
+
+ liElems.each(function(index){
+ var iconElem = $(this).children('i');
+ var isActiveIcon = (Math.ceil(score) - index === 1);
+ var needSelect = Math.ceil(score) > index;
+ var shouldHalfIcon = (score - index === 0.5);
+
+ if(needSelect){
+ // 设置选中样式
+ iconElem.addClass(ICON_RATE_SOLID).removeClass(ICON_HALF_RATE);
+ if(options.half && shouldHalfIcon){
+ iconElem.addClass(ICON_RATE_HALF).removeClass(ICON_RATE_SOLID);
+ }
+ }else{
+ // 恢复初始样式
+ iconElem.addClass(ICON_RATE).removeClass(ICON_SOLID_HALF);
+ }
+
+ // 设置缩放样式
+ iconElem.toggleClass('layui-rate-hover', isActiveIcon);
+ });
+
+ // 更新最终值
+ options.value = score;
+ if(options.text) _ul.next("span").text(options.value + "星");
+ options.setText && options.setText(options.value);
+ },
+ onTouchEnd: function(e, state){
+ if(Date.now() - state.timeStart <= 200) return;
+ _ul.find('i').removeClass('layui-rate-hover');
+ options.choose && options.choose(options.value);
+ options.setText && options.setText(options.value);
+ }
+ });
};
-
+
//事件处理
- Class.prototype.events = function(){
- var that = this
- ,options = that.config;
+ Class.prototype.events = function () {
+ var that = this;
+ //var options = that.config;
};
//核心入口
@@ -220,6 +276,6 @@ layui.define(['jquery', 'lay'],function(exports){
var inst = new Class(options);
return thisRate.call(inst);
};
-
+
exports(MOD_NAME, rate);
-})
\ No newline at end of file
+})
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/slider.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/slider.js
index c0f3e35..745c52b 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/modules/slider.js
+++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/slider.js
@@ -10,26 +10,26 @@ layui.define(['jquery', 'lay'], function(exports){
// 外部接口
var slider = {
- config: {}
- ,index: layui.slider ? (layui.slider.index + 10000) : 0
+ config: {},
+ index: layui.slider ? (layui.slider.index + 10000) : 0,
// 设置全局项
- ,set: function(options){
+ set: function(options){
var that = this;
that.config = $.extend({}, that.config, options);
return that;
- }
-
+ },
+
// 事件
- ,on: function(events, callback){
+ on: function(events, callback){
return layui.onevent.call(this, MOD_NAME, events, callback);
}
};
-
+
// 操作当前实例
var thisSlider = function(){
- var that = this
- ,options = that.config;
+ var that = this;
+ var options = that.config;
return {
setValue: function(value, index){ // 设置值
@@ -37,8 +37,8 @@ layui.define(['jquery', 'lay'], function(exports){
value = value < options.min ? options.min : value;
options.value = value;
return that.slide('set', value, index || 0);
- }
- ,config: options
+ },
+ config: options
}
};
@@ -65,20 +65,32 @@ layui.define(['jquery', 'lay'], function(exports){
// 默认配置
Class.prototype.config = {
- type: 'default' //滑块类型,垂直:vertical
- ,min: 0 //最小值
- ,max: 100 //最大值,默认100
- ,value: 0 //初始值,默认为0
- ,step: 1 //间隔值
- ,showstep: false //间隔点开启
- ,tips: true //文字提示,开启
- ,input: false //输入框,关闭
- ,range: false //范围选择,与输入框不能同时开启,默认关闭
- ,height: 200 //配合 type:"vertical" 使用,默认200px
- ,disabled: false //滑块禁用,默认关闭
- ,theme: '#16baaa' //主题颜色
+ type: 'default', //滑块类型,垂直:vertical
+ min: 0, //最小值
+ max: 100, //最大值,默认100
+ value: 0, //初始值,默认为0
+ step: 1, //间隔值
+ showstep: false, //间隔点开启
+ tips: true, //文字提示,开启
+ tipsAlways: false, //文字提示,始终开启
+ input: false, //输入框,关闭
+ range: false, //范围选择,与输入框不能同时开启,默认关闭
+ height: 200, //配合 type:"vertical" 使用,默认200px
+ disabled: false, //滑块禁用,默认关闭
+ theme: '#16baaa' //主题颜色
};
+ // 数值精度
+ Class.prototype.precision = function(){
+ var that = this;
+ var options = that.config;
+ var precisions = $.map([options.min, options.max, options.step], function(v, i){
+ var decimalArr = String(v).split('.');
+ return decimalArr[1] ? decimalArr[1].length : 0;
+ })
+ return Math.max.apply(null, precisions);
+ }
+
//滑块渲染
Class.prototype.render = function(){
var that = this;
@@ -97,28 +109,28 @@ layui.define(['jquery', 'lay'], function(exports){
// 合并 lay-options 属性上的配置信息
$.extend(options, lay.options(elem[0]));
-
- //间隔值不能小于 1
- if(options.step < 1) options.step = 1;
-
+
+ //间隔值不能小于等于 0
+ if(options.step <= 0) options.step = 1;
+
//最大值不能小于最小值
if(options.max < options.min) options.max = options.min + options.step;
-
-
+
+
//判断是否开启双滑块
if(options.range){
options.value = typeof(options.value) == 'object' ? options.value : [options.min, options.value];
var minValue = Math.min(options.value[0], options.value[1])
,maxValue = Math.max(options.value[0], options.value[1]);
- options.value[0] = minValue > options.min ? minValue : options.min;
- options.value[1] = maxValue > options.min ? maxValue : options.min;
- options.value[0] = options.value[0] > options.max ? options.max : options.value[0];
- options.value[1] = options.value[1] > options.max ? options.max : options.value[1];
-
- var scaleFir = Math.floor((options.value[0] - options.min) / (options.max - options.min) * 100)
- ,scaleSec = Math.floor((options.value[1] - options.min) / (options.max - options.min) * 100)
- ,scale = scaleSec - scaleFir + '%';
+ options.value[0] = Math.max(minValue,options.min);
+ options.value[1] = Math.max(maxValue,options.min);
+ options.value[0] = Math.min(options.value[0],options.max);
+ options.value[1] = Math.min(options.value[1],options.max);
+
+ var scaleFir = (options.value[0] - options.min) / (options.max - options.min) * 100;
+ var scaleSec = (options.value[1] - options.min) / (options.max - options.min) * 100;
+ var scale = scaleSec - scaleFir + '%';
scaleFir = scaleFir + '%';
scaleSec = scaleSec + '%';
} else {
@@ -126,44 +138,44 @@ layui.define(['jquery', 'lay'], function(exports){
if(typeof options.value == 'object'){
options.value = Math.min.apply(null, options.value);
}
-
+
//初始值不能小于最小值且不能大于最大值
if(options.value < options.min) options.value = options.min;
if(options.value > options.max) options.value = options.max;
- var scale = Math.floor((options.value - options.min) / (options.max - options.min) * 100) + '%';
- };
-
+ var scale = (options.value - options.min) / (options.max - options.min) * 100 + '%';
+ }
+
//如果禁用,颜色为统一的灰色
var theme = options.disabled ? '#c2c2c2' : options.theme;
//滑块
- var temp = '
'+ (options.tips ? '
' : '') +
+ var temp = '
'+ (options.tips ? '
' : '') +
'
'+ (options.range ? '
' : '') +'
';
- var othis = $(options.elem)
- ,hasRender = othis.next('.' + ELEM_VIEW);
+ var othis = $(options.elem);
+ var hasRender = othis.next('.' + ELEM_VIEW);
//生成替代元素
- hasRender[0] && hasRender.remove(); //如果已经渲染,则Rerender
+ hasRender[0] && hasRender.remove(); //如果已经渲染,则Rerender
that.elemTemp = $(temp);
//把数据缓存到滑块上
if(options.range){
that.elemTemp.find('.' + SLIDER_WRAP).eq(0).data('value', options.value[0]);
- that.elemTemp.find('.' + SLIDER_WRAP).eq(1).data('value', options.value[1]);
+ that.elemTemp.find('.' + SLIDER_WRAP).eq(1).data('value', options.value[1]);
}else{
that.elemTemp.find('.' + SLIDER_WRAP).data('value', options.value);
- };
-
+ }
+
//插入替代元素
- othis.html(that.elemTemp);
+ othis.html(that.elemTemp);
//垂直滑块
if(options.type === 'vertical'){
that.elemTemp.height(options.height + 'px');
- };
+ }
//显示间断点
if(options.showstep){
@@ -173,9 +185,9 @@ layui.define(['jquery', 'lay'], function(exports){
if(step < 100){
item += '
'
}
- };
+ }
that.elemTemp.append(item);
- };
+ }
//插入输入框
if(options.input && !options.range){
@@ -191,7 +203,7 @@ layui.define(['jquery', 'lay'], function(exports){
} else {
that.elemTemp.css("margin-right", elemInput.outerWidth() + 15);
}
- };
+ }
//给未禁止的滑块滑动事件
if(!options.disabled){
@@ -199,70 +211,107 @@ layui.define(['jquery', 'lay'], function(exports){
}else{
that.elemTemp.addClass(DISABLED);
that.elemTemp.find('.' + SLIDER_WRAP_BTN).addClass(DISABLED);
- };
+ }
- //划过滑块显示数值
- var timer;
- that.elemTemp.find('.' + SLIDER_WRAP_BTN).on('mouseover', function(){
- var sliderWidth = options.type === 'vertical' ? options.height : that.elemTemp[0].offsetWidth
- ,sliderWrap = that.elemTemp.find('.' + SLIDER_WRAP)
- ,tipsLeft = options.type === 'vertical' ? (sliderWidth - $(this).parent()[0].offsetTop - sliderWrap.height()) : $(this).parent()[0].offsetLeft
- ,left = tipsLeft / sliderWidth * 100
- ,value = $(this).parent().data('value')
- ,tipsTxt = options.setTips ? options.setTips(value) : value;
+ /**
+ * @description 设置提示文本内容
+ * @param {Element} sliderWrapBtnElem 提示文本节点元素
+ */
+ function setSliderTipsTxt(sliderWrapBtnElem) {
+ var value = sliderWrapBtnElem.parent().data('value');
+ var tipsTxt = options.setTips ? options.setTips(value) : value;
that.elemTemp.find('.' + SLIDER_TIPS).html(tipsTxt);
+ }
- clearTimeout(timer);
- timer = setTimeout(function(){
- if(options.type === 'vertical'){
- that.elemTemp.find('.' + SLIDER_TIPS).css({
- "bottom": left + '%',
- "margin-bottom": "20px",
- "display": "inline-block"
- });
- } else {
- that.elemTemp.find('.' + SLIDER_TIPS).css({
- "left": left + '%',
- "display": "inline-block"
- });
- };
- }, 300);
- }).on('mouseout', function(){
- clearTimeout(timer);
- that.elemTemp.find('.' + SLIDER_TIPS).css("display", "none");
- });
+ /**
+ * @description 计算提示文本元素的 position left
+ * @param {Element} sliderWrapBtnElem 提示文本节点元素
+ */
+ function calcSliderTipsLeft(sliderWrapBtnElem){
+ var sliderWidth = options.type === 'vertical' ? options.height : that.elemTemp[0].offsetWidth;
+ var sliderWrap = that.elemTemp.find('.' + SLIDER_WRAP);
+ var tipsLeft = options.type === 'vertical' ? (sliderWidth - sliderWrapBtnElem.parent()[0].offsetTop - sliderWrap.height()) : sliderWrapBtnElem.parent()[0].offsetLeft;
+ var left = tipsLeft / sliderWidth * 100;
+ return left
+ }
+
+ /**
+ * @description 设置提示文本元素的 position left
+ * @param {number} left 要设置的 left 的大小
+ */
+ function setSliderTipsLeft(left) {
+ if(options.type === 'vertical'){
+ that.elemTemp.find('.' + SLIDER_TIPS).css({
+ "bottom": left + '%',
+ "margin-bottom": "20px",
+ "display": "inline-block"
+ });
+ } else {
+ that.elemTemp.find('.' + SLIDER_TIPS).css({
+ "left": left + '%',
+ "display": "inline-block"
+ });
+ }
+ }
+
+ //判断是否要始终显示提示文本
+ if(options.tips){
+ if(options.tipsAlways){
+ var sliderWrapBtnElem = that.elemTemp.find('.' + SLIDER_WRAP_BTN);
+ setSliderTipsTxt(sliderWrapBtnElem)
+ var left = calcSliderTipsLeft(sliderWrapBtnElem);
+ setSliderTipsLeft(left)
+ }else{
+ //划过滑块显示数值
+ var timer;
+ that.elemTemp.find('.' + SLIDER_WRAP_BTN).on('mouseover', function(){
+ setSliderTipsTxt($(this))
+ var left = calcSliderTipsLeft($(this));
+ clearTimeout(timer);
+ timer = setTimeout(function(){
+ setSliderTipsLeft(left)
+ }, 300);
+ }).on('mouseout', function(){
+ clearTimeout(timer);
+ if(!options.tipsAlways){
+ that.elemTemp.find('.' + SLIDER_TIPS).css("display", "none");
+ }
+ });
+ }
+ }
};
//滑块滑动
Class.prototype.slide = function(setValue, value, i){
- var that = this
- ,options = that.config
- ,sliderAct = that.elemTemp
- ,sliderWidth = function(){
+ var that = this;
+ var options = that.config;
+ var sliderAct = that.elemTemp;
+ var sliderWidth = function(){
return options.type === 'vertical' ? options.height : sliderAct[0].offsetWidth
- }
- ,sliderWrap = sliderAct.find('.' + SLIDER_WRAP)
- ,sliderTxt = sliderAct.next('.' + SLIDER_INPUT)
- ,inputValue = sliderTxt.children('.' + SLIDER_INPUT_TXT).children('input').val()
- ,step = 100 / ((options.max - options.min) / Math.ceil(options.step))
- ,change = function(offsetValue, index, from){
+ };
+ var sliderWrap = sliderAct.find('.' + SLIDER_WRAP);
+ var sliderTxt = sliderAct.next('.' + SLIDER_INPUT);
+ var inputValue = sliderTxt.children('.' + SLIDER_INPUT_TXT).children('input').val();
+ var step = 100 / ((options.max - options.min) / options.step);
+ var precision = that.precision();
+ var change = function(offsetValue, index, from){
if(Math.ceil(offsetValue) * step > 100){
offsetValue = Math.ceil(offsetValue) * step
}else{
offsetValue = Math.round(offsetValue) * step
- };
+ }
offsetValue = offsetValue > 100 ? 100: offsetValue;
offsetValue = offsetValue < 0 ? 0: offsetValue;
sliderWrap.eq(index).css((options.type === 'vertical' ?'bottom':'left'), offsetValue + '%');
- var firLeft = valueTo(sliderWrap[0].offsetLeft)
- ,secLeft = options.range ? valueTo(sliderWrap[1].offsetLeft) : 0;
+ var firLeft = valueTo(sliderWrap[0].offsetLeft);
+ var secLeft = options.range ? valueTo(sliderWrap[1].offsetLeft) : 0;
if(options.type === 'vertical'){
sliderAct.find('.' + SLIDER_TIPS).css({"bottom":offsetValue + '%', "margin-bottom":"20px"});
firLeft = valueTo(sliderWidth() - sliderWrap[0].offsetTop - sliderWrap.height());
secLeft = options.range ? valueTo(sliderWidth() - sliderWrap[1].offsetTop - sliderWrap.height()) : 0;
}else{
sliderAct.find('.' + SLIDER_TIPS).css("left",offsetValue + '%');
- };
+ }
firLeft = firLeft > 100 ? 100: firLeft;
secLeft = secLeft > 100 ? 100: secLeft;
var minLeft = Math.min(firLeft, secLeft)
@@ -271,18 +320,19 @@ layui.define(['jquery', 'lay'], function(exports){
sliderAct.find('.' + SLIDER_BAR).css({"height":wrapWidth + '%', "bottom":minLeft + '%'});
}else{
sliderAct.find('.' + SLIDER_BAR).css({"width":wrapWidth + '%', "left":minLeft + '%'});
- };
- var selfValue = options.min + Math.round((options.max - options.min) * offsetValue / 100);
+ }
+ var selfValue = options.min + (options.max - options.min) * offsetValue / 100;
+ selfValue = Number(parseFloat(selfValue).toFixed(precision));
inputValue = selfValue;
sliderTxt.children('.' + SLIDER_INPUT_TXT).children('input').val(inputValue);
sliderWrap.eq(index).data('value', selfValue);
sliderAct.find('.' + SLIDER_TIPS).html(options.setTips ? options.setTips(selfValue) : selfValue);
-
+
//如果开启范围选择,则返回数组值
if(options.range){
var arrValue = [
- sliderWrap.eq(0).data('value')
- ,sliderWrap.eq(1).data('value')
+ sliderWrap.eq(0).data('value'),
+ sliderWrap.eq(1).data('value')
];
if(arrValue[0] > arrValue[1]) arrValue.reverse(); //如果前面的圆点超过了后面的圆点值,则调换顺序
}
@@ -292,47 +342,70 @@ layui.define(['jquery', 'lay'], function(exports){
// 值完成选中的事件
if(from === 'done') options.done && options.done(that.value);
- }
- ,valueTo = function(value){
- var oldLeft = value / sliderWidth() * 100 / step
- ,left = Math.round(oldLeft) * step;
+ };
+ var valueTo = function(value){
+ var oldLeft = value / sliderWidth() * 100 / step;
+ var left = Math.round(oldLeft) * step;
if(value == sliderWidth()){
left = Math.ceil(oldLeft) * step;
- };
+ }
return left;
- }
-
+ };
+
//拖拽元素
- ,elemMove = $(['
sliderWidth())left = sliderWidth();
@@ -342,23 +415,27 @@ layui.define(['jquery', 'lay'], function(exports){
sliderAct.find('.' + SLIDER_TIPS).show();
e.preventDefault();
};
-
- var up = function(){
+
+ var up = function(delay){
othis.removeClass(ELEM_HOVER);
- sliderAct.find('.' + SLIDER_TIPS).hide();
+ if(!options.tipsAlways){
+ setTimeout(function(){
+ sliderAct.find('.' + SLIDER_TIPS).hide();
+ }, delay);
+ }
};
-
- createMoveElem(move, up)
+
+ createMoveElem(othis, move, up)
});
});
-
+
// 点击滑块
sliderAct.on('click', function(e){
var main = $('.' + SLIDER_WRAP_BTN);
var othis = $(this);
if(!main.is(event.target) && main.has(event.target).length === 0 && main.length){
var index;
- var offset = options.type === 'vertical'
+ var offset = options.type === 'vertical'
? (sliderWidth() - e.clientY + othis.offset().top - $(window).scrollTop())
:(e.clientX - othis.offset().left - $(window).scrollLeft());
@@ -373,30 +450,30 @@ layui.define(['jquery', 'lay'], function(exports){
}
} else {
index = 0;
- };
+ }
change(reaLeft, index, 'done');
e.preventDefault();
}
});
-
+
//点击加减输入框
sliderTxt.children('.' + SLIDER_INPUT_BTN).children('i').each(function(index){
$(this).on('click', function(){
inputValue = sliderTxt.children('.' + SLIDER_INPUT_TXT).children('input').val();
if(index == 1){ //减
- inputValue = inputValue - options.step < options.min
- ? options.min
+ inputValue = inputValue - options.step < options.min
+ ? options.min
: Number(inputValue) - options.step;
}else{
- inputValue = Number(inputValue) + options.step > options.max
- ? options.max
+ inputValue = Number(inputValue) + options.step > options.max
+ ? options.max
: Number(inputValue) + options.step;
- };
+ }
var inputScale = (inputValue - options.min) / (options.max - options.min) * 100 / step;
change(inputScale, 0, 'done');
});
});
-
+
//获取输入框值
var getInputValue = function(){
var realValue = this.value;
@@ -412,20 +489,20 @@ layui.define(['jquery', 'lay'], function(exports){
e.preventDefault();
getInputValue.call(this);
}
- }).on('change', getInputValue);
+ }).on('change', getInputValue);
};
//事件处理
Class.prototype.events = function(){
- var that = this
- ,options = that.config;
+ var that = this;
+ var options = that.config;
};
//核心入口
slider.render = function(options){
- var inst = new Class(options);
+ var inst = new Class(options);
return thisSlider.call(inst);
};
-
+
exports(MOD_NAME, slider);
-})
\ No newline at end of file
+})
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/table.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/table.js
index 72da9c1..6ba70f6 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/modules/table.js
+++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/table.js
@@ -77,6 +77,16 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
return config || null;
};
+ // lay 函数可以处理 Selector,HTMLElement,JQuery 类型
+ // 无效的 CSS 选择器字符串,会抛出 SyntaxError 异常,此时直接返回 laytpl 模板字符串
+ var resolveTplStr = function(templet){
+ try{
+ return lay(templet).html();
+ }catch(err){
+ return templet;
+ }
+ }
+
// 解析自定义模板数据
var parseTempData = function(obj){
obj = obj || {};
@@ -97,9 +107,9 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
if(templet){
content = typeof templet === 'function'
? templet.call(item3, obj.tplData, obj.obj)
- : laytpl($(templet).html() || String(content)).render($.extend({
- LAY_COL: item3
- }, obj.tplData));
+ : laytpl(resolveTplStr(templet) || String(content)).render($.extend({
+ LAY_COL: item3
+ }, obj.tplData));
}
// 是否只返回文本
@@ -108,6 +118,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
// 字符
var MOD_NAME = 'table';
+ var MOD_ID = 'lay-' + MOD_NAME + '-id';
var ELEM = '.layui-table';
var THIS = 'layui-this';
var SHOW = 'layui-show';
@@ -136,6 +147,8 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
var ELEM_GROUP = 'laytable-cell-group';
var ELEM_COL_SPECIAL = 'layui-table-col-special';
var ELEM_TOOL_PANEL = 'layui-table-tool-panel';
+ var ELEM_EXPAND = 'layui-table-expanded';
+ var DISABLED_TRANSITION = 'layui-table-disabled-transition';
var DATA_MOVE_NAME = 'LAY_TABLE_MOVE_DICT';
@@ -162,7 +175,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
return '';
}()
,'{{# var isSort = !(item2.colGroup) && item2.sort; }}'
- ,'
'
+ ,' '
,''
,'{{# if(d.data.loading){ }}'
- ,'
'
- ,'
'
+ ,'
'
+ ,'
'
+ ,'{{# if(typeof d.data.loading === "string"){ }}'
+ ,'{{- d.data.loading}}'
+ ,'{{# } else{ }}'
+ ,' '
+ ,'{{# } }}'
+ ,'
'
,'
'
,'{{# } }}'
@@ -257,29 +276,6 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
,'
'
-
- ,''
].join('');
var _WIN = $(window);
@@ -328,18 +324,18 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
//请求参数的自定义格式
options.request = $.extend({
- pageName: 'page'
- ,limitName: 'limit'
+ pageName: 'page',
+ limitName: 'limit'
}, options.request)
// 响应数据的自定义格式
options.response = $.extend({
- statusName: 'code' //规定数据状态的字段名称
- ,statusCode: 0 //规定成功的状态码
- ,msgName: 'msg' //规定状态信息的字段名称
- ,dataName: 'data' //规定数据总数的字段名称
- ,totalRowName: 'totalRow' //规定数据统计的字段名称
- ,countName: 'count'
+ statusName: 'code', //规定数据状态的字段名称
+ statusCode: 0, //规定成功的状态码
+ msgName: 'msg', //规定状态信息的字段名称
+ dataName: 'data', //规定数据总数的字段名称
+ totalRowName: 'totalRow', //规定数据统计的字段名称
+ countName: 'count'
}, options.response);
//如果 page 传入 laypage 对象
@@ -370,27 +366,31 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
options.index = that.index;
that.key = options.id || options.index;
- //初始化一些其他参数
+ // 初始化一些其他参数
that.setInit();
- //高度铺满:full-差距值
- if(options.height && /^full-\d+$/.test(options.height)){
+ // 高度铺满:full-差距值
+ if(options.height && /^full-.+$/.test(options.height)){
that.fullHeightGap = options.height.split('-')[1];
- options.height = _WIN.height() - that.fullHeightGap;
- } else if (options.height && /^#\w+\S*-\d+$/.test(options.height)) {
+ options.height = _WIN.height() - (parseFloat(that.fullHeightGap) || 0);
+ } else if (options.height && /^#\w+\S*-.+$/.test(options.height)) {
var parentDiv = options.height.split("-");
that.parentHeightGap = parentDiv.pop();
that.parentDiv = parentDiv.join("-");
- options.height = $(that.parentDiv).height() - that.parentHeightGap;
+ options.height = $(that.parentDiv).height() - (parseFloat(that.parentHeightGap) || 0);
+ } else if (typeof options.height === "function"){
+ that.customHeightFunc = options.height;
+ options.height = that.customHeightFunc();
}
- //开始插入替代元素
- var othis = options.elem
- ,hasRender = othis.next('.' + ELEM_VIEW)
+ // 开始插入替代元素
+ var othis = options.elem;
+ var hasRender = othis.next('.' + ELEM_VIEW);
- //主容器
- ,reElem = that.elem = $('
');
+ // 主容器
+ var reElem = that.elem = $('
');
+ // 添加 className
reElem.addClass(function(){
var arr = [
ELEM_VIEW,
@@ -400,28 +400,37 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
];
if(options.className) arr.push(options.className);
return arr.join(' ');
- }()).attr({
- 'lay-filter': 'LAY-TABLE-FORM-DF-'+ that.index
- ,'lay-id': options.id
- ,'style': function(){
- var arr = [];
- if(options.width) arr.push('width:'+ options.width + 'px;');
- // if(options.height) arr.push('height:'+ options.height + 'px;');
- return arr.join('')
- }()
- }).html(laytpl(TPL_MAIN, {
+ }()).attr(function(){
+ var obj = {
+ 'lay-filter': 'LAY-TABLE-FORM-DF-'+ that.index,
+ 'style': function(){
+ var arr = [];
+ if(options.width) arr.push('width:'+ options.width + 'px;');
+ // if(options.height) arr.push('height:'+ options.height + 'px;');
+ return arr.join('')
+ }()
+ }
+ obj[MOD_ID] = options.id;
+ return obj;
+ }()).html(laytpl(TPL_MAIN, {
open: '{{', // 标签符前缀
close: '}}' // 标签符后缀
}).render({
- data: options
- ,index: that.index //索引
+ data: options,
+ index: that.index //索引
}));
- //生成替代元素
- hasRender[0] && hasRender.remove(); //如果已经渲染,则Rerender
+ // 初始化样式
+ that.renderStyle();
+
+ // 生成替代元素
+ if(hasRender[0]){
+ that.resizeObserver && that.resizeObserver.unobserve(that.elem[0]);
+ hasRender.remove(); // 如果已经渲染,则 Rerender
+ }
othis.after(reElem);
- //各级容器
+ // 各级容器
that.layTool = reElem.find(ELEM_TOOL);
that.layBox = reElem.find(ELEM_BOX);
that.layHeader = reElem.find(ELEM_HEADER);
@@ -442,23 +451,22 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
// 让表格平铺
that.fullSize();
-
- that.pullData(that.page); //请求数据
- that.events(); //事件
+ that.pullData(that.page); // 请求数据
+ that.events(); // 事件
};
- //根据列类型,定制化参数
+ // 根据列类型,定制化参数
Class.prototype.initOpts = function(item){
var that = this
- ,options = that.config
- ,initWidth = {
- checkbox: 50
- ,radio: 50
- ,space: 30
- ,numbers: 60
+ var options = that.config;
+ var initWidth = {
+ checkbox: 50,
+ radio: 50,
+ space: 30,
+ numbers: 60
};
- //让 type 参数兼容旧版本
+ // 让 type 参数兼容旧版本
if(item.checkbox) item.type = "checkbox";
if(item.space) item.type = "space";
if(!item.type) item.type = "normal";
@@ -471,8 +479,8 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
//初始化一些参数
Class.prototype.setInit = function(type){
- var that = this
- ,options = that.config;
+ var that = this;
+ var options = that.config;
options.clientWidth = options.width || function(){ //获取容器宽度
//如果父元素宽度为0(一般为隐藏元素),则继续查找上层元素,直到找到真实宽度为止
@@ -553,10 +561,70 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
};
- // 初始工具栏
+ // 初始化样式
+ Class.prototype.renderStyle = function() {
+ var that = this;
+ var options = that.config;
+ var index = that.index;
+ var text = [];
+
+ // 单元格宽度
+ layui.each(options.cols, function(i1, item1) {
+ layui.each(item1, function(i2, item2) {
+ var key = [index, i1, i2].join('-');
+ var val = ['width: ', (item2.width || options.cellMinWidth), 'px'].join('');
+ text.push('.laytable-cell-'+ key +'{'+ val +'}');
+ });
+ });
+
+ // 自定义行样式
+ (function (lineStyle) {
+ if (!lineStyle) return;
+ var trClassName = '.layui-table-view-'+ index +' .layui-table-body .layui-table tr';
+ var rules = lineStyle.split(';');
+ var cellMaxHeight = 'none';
+
+ // 计算单元格最大高度
+ layui.each(rules, function(i, rule) {
+ rule = rule.split(':');
+ if (rule[0] === 'height') {
+ var val = parseFloat(rule[1]);
+ if (!isNaN(val)) cellMaxHeight = (val - 1) + 'px';
+ return true;
+ }
+ });
+
+ // 多行相关样式
+ layui.each([
+ '{'+ lineStyle +'}',
+ '.layui-table-cell{height: auto; max-height: '+ cellMaxHeight +'; white-space: normal; text-overflow: clip;}',
+ '> td:hover > .layui-table-cell{overflow: auto;}'
+ ].concat(
+ device.ie ? [
+ '.layui-table-edit{height: '+ cellMaxHeight +';}',
+ 'td[data-edit]:hover:after{height: '+ cellMaxHeight +';}'
+ ] : []
+ ), function(i, val) {
+ val && text.push(trClassName + ' ' + val);
+ });
+ })(options.lineStyle);
+
+ // 自定义 css 属性
+ if (options.css) text.push(options.css);
+
+ // 生成 style
+ lay.style({
+ target: that.elem[0],
+ text: text.join(''),
+ id: 'DF-table-'+ index
+ });
+ };
+
+ // 初始头部工具栏
Class.prototype.renderToolbar = function(){
- var that = this
- var options = that.config
+ var that = this;
+ var options = that.config;
+ var filter = options.elem.attr('lay-filter');
// 添加工具栏左侧模板
var leftDefaultTemp = [
@@ -575,36 +643,164 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
);
}
- // 添加工具栏右侧面板
- var layout = {
+ // 头部工具栏右上角默认工具
+ var defaultConfig = {
filter: {
title: '筛选列',
layEvent: 'LAYTABLE_COLS',
- icon: 'layui-icon-cols'
+ icon: 'layui-icon-cols',
+ onClick: function(obj) {
+ var options = obj.config;
+ var openPanel = obj.openPanel;
+
+ openPanel({
+ list: function(){
+ var lis = [];
+ that.eachCols(function(i, item){
+ if(item.field && item.type == 'normal'){
+ lis.push('
');
+ }
+ });
+ return lis.join('');
+ }(),
+ done: function() {
+ form.on('checkbox(LAY_TABLE_TOOL_COLS)', function(obj){
+ var othis = $(obj.elem);
+ var checked = this.checked;
+ var key = othis.data('key');
+ var col = that.col(key);
+ var hide = col.hide;
+ var parentKey = othis.data('parentkey');
+
+ if(!col.key) return;
+
+ // 同步勾选列的 hide 值和隐藏样式
+ col.hide = !checked;
+ that.elem.find('*[data-key="'+ key +'"]')[
+ checked ? 'removeClass' : 'addClass'
+ ](HIDE);
+
+ // 根据列的显示隐藏,同步多级表头的父级相关属性值
+ if(hide != col.hide){
+ that.setParentCol(!checked, parentKey);
+ }
+
+ // 重新适配尺寸
+ that.resize();
+
+ // 列筛选(显示或隐藏)后的事件
+ layui.event.call(this, MOD_NAME, 'colToggled('+ filter +')', {
+ col: col,
+ config: options
+ });
+ });
+ }
+ });
+ }
},
exports: {
title: '导出',
layEvent: 'LAYTABLE_EXPORT',
- icon: 'layui-icon-export'
+ icon: 'layui-icon-export',
+ onClick: function(obj) { // 自带导出
+ var data = obj.data;
+ var options = obj.config;
+ var openPanel = obj.openPanel;
+ var elem = obj.elem;
+
+ if (!data.length) return layer.tips('当前表格无数据', elem, {tips: 3});
+ if(device.ie){
+ layer.tips('导出功能不支持 IE,请用 Chrome 等高级浏览器导出', elem, {
+ tips: 3
+ });
+ } else {
+ openPanel({
+ list: function(){
+ return [
+ '
导出 CSV 文件 '
+ ].join('')
+ }(),
+ done: function(panel, list){
+ list.on('click', function(){
+ var type = $(this).data('type')
+ table.exportFile.call(that, options.id, null, type);
+ });
+ }
+ });
+ }
+ }
},
print: {
title: '打印',
layEvent: 'LAYTABLE_PRINT',
- icon: 'layui-icon-print'
- }
- }, iconElem = [];
+ icon: 'layui-icon-print',
+ onClick: function(obj) {
+ var data = obj.data;
+ var options = obj.config;
+ var elem = obj.elem;
- if(typeof options.defaultToolbar === 'object'){
- layui.each(options.defaultToolbar, function(i, item){
- var thisItem = typeof item === 'string' ? layout[item] : item;
- if(thisItem){
- iconElem.push('
'
- +' '
- +'
');
+ if (!data.length) return layer.tips('当前表格无数据', elem, {tips: 3});
+ var printWin = window.open('about:blank', '_blank');
+ var style = [''].join('')
+ var html = $(that.layHeader.html()); // 输出表头
+
+ html.append(that.layMain.find('table').html()); // 输出表体
+ html.append(that.layTotal.find('table').html()) // 输出合计行
+
+ html.find('th.layui-table-patch').remove(); // 移除补丁
+ // 移除表头特殊列
+ html.find('thead>tr>th.'+ ELEM_COL_SPECIAL).filter(function(i, thElem){
+ return !$(thElem).children('.'+ ELEM_GROUP).length; // 父级表头除外
+ }).remove();
+ html.find('tbody>tr>td.'+ ELEM_COL_SPECIAL).remove(); // 移除表体特殊列
+
+ printWin.document.write(style + html.prop('outerHTML'));
+ printWin.document.close();
+
+ if(layui.device('edg').edg){
+ printWin.onafterprint = printWin.close;
+ printWin.print();
+ }else{
+ printWin.print();
+ printWin.close();
+ }
}
+ }
+ };
+
+ // 若开启 defaultToolbar
+ if (typeof options.defaultToolbar === 'object') {
+ var iconElem = [];
+ options.defaultToolbar = $.map(options.defaultToolbar, function(item, i) {
+ var itemIsName = typeof item === 'string';
+ var thisItem = itemIsName ? defaultConfig[item] : item;
+ if (thisItem) {
+ // 根据 name 匹配默认工具并合并
+ if (thisItem.name && defaultConfig[thisItem.name]) {
+ thisItem = $.extend({}, defaultConfig[thisItem.name], thisItem);
+ }
+ // 初始化默认工具 name
+ if (!thisItem.name && itemIsName) {
+ thisItem.name = item;
+ }
+ // 图标列表
+ iconElem.push(
+ '
'
+ +' '
+ +'
'
+ );
+ }
+ return thisItem;
});
+ that.layTool.find('.layui-table-tool-self').html(iconElem.join(''));
}
- that.layTool.find('.layui-table-tool-self').html(iconElem.join(''));
};
// 分页栏
@@ -784,7 +980,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
// 给未分配宽的列平均分配宽
if(item3.width === 0){
- that.getCssRule(item3.key, function(item){
+ that.cssRules(item3.key, function(item){
item.style.width = Math.floor(function(){
if(autoWidth < minWidth) return minWidth;
if(autoWidth > maxWidth) return maxWidth;
@@ -795,7 +991,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
// 给设定百分比的列分配列宽
else if(/\d+%$/.test(item3.width)){
- that.getCssRule(item3.key, function(item){
+ that.cssRules(item3.key, function(item){
var width = Math.floor((parseFloat(item3.width) / 100) * cntrWidth);
width < minWidth && (width = minWidth);
width > maxWidth && (width = maxWidth);
@@ -805,7 +1001,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
// 给拥有普通 width 值的列分配最新列宽
else {
- that.getCssRule(item3.key, function(item){
+ that.cssRules(item3.key, function(item){
item.style.width = item3.width + 'px';
});
}
@@ -828,7 +1024,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
var th = getEndTh();
var key = th.data('key');
- that.getCssRule(key, function(item){
+ that.cssRules(key, function(item){
var width = item.style.width || th.outerWidth();
item.style.width = (parseFloat(width) + patchNums) + 'px';
@@ -850,33 +1046,17 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
that.layMain.find('table').width('auto');
}
- that.loading(!0);
};
// 重置表格尺寸/结构
Class.prototype.resize = function(){
var that = this;
- //soultable
- //---
- var scrollTop = 0;
- if (!!that.config.id) {
- scrollTop = that.layMain[0].scrollTop;
- }
- //---
+
+ if (!that.layMain) return;
+
that.fullSize(); // 让表格铺满
that.setColsWidth(); // 自适应列宽
- that.scrollPatch(); // 滚动条补丁
- //soultable
- //---
- if (layui.tableFilter) {
- layui.tableFilter.resize(that.config);
- if (!!that.config.id) {
- that.layMain[0].scrollTop = scrollTop;
- //同步更新滚动
- that.layFixed.find(ELEM_BODY).scrollTop(scrollTop);
- }
- }
- //---
+ that.scrollPatch(); // 滚动条补丁
};
// 表格重载
@@ -930,6 +1110,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
that.syncCheckAll();
that.renderForm();
that.setColsWidth();
+ that.loading(false);
};
// 初始页码
@@ -944,6 +1125,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
options.HAS_SET_COLS_PATCH = true;
var request = options.request;
var response = options.response;
+ var res;
var sort = function(){
if(typeof options.initSort === 'object'){
that.sort({
@@ -955,6 +1137,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
};
var done = function(res, origin){
that.setColsWidth();
+ that.loading(false);
typeof options.done === 'function' && options.done(
res, curr, res[response.countName], origin
);
@@ -969,7 +1152,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
that.startTime = new Date().getTime(); // 渲染开始时间
if (opts.renderData) { // 将 cache 信息重新渲染
- var res = {};
+ res = {};
res[response.dataName] = table.cache[that.key];
res[response.countName] = options.url ? (layui.type(options.page) === 'object' ? options.page.count : res[response.dataName].length) : options.data.length;
@@ -983,7 +1166,8 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
curr: curr,
count: res[response.countName],
type: opts.type,
- }), sort(), done(res, 'renderData');
+ sort: true
+ }), done(res, 'renderData');
} else if(options.url){ // Ajax请求
var params = {};
// 当 page 开启,默认自动传递 page、limit 参数
@@ -998,7 +1182,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
data = JSON.stringify(data);
}
- that.loading();
+ that.loading(true);
$.ajax({
type: options.method || 'get',
@@ -1008,6 +1192,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
dataType: options.dataType || 'json',
jsonpCallback: options.jsonpCallback,
headers: options.headers || {},
+ complete: typeof options.complete === 'function' ? options.complete : undefined,
success: function(res){
// 若有数据解析的回调,则获得其返回的数据
if(typeof options.parseData === 'function'){
@@ -1031,7 +1216,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
// 耗时(接口请求+视图渲染)
options.time = (new Date().getTime() - that.startTime) + ' ms';
}
- done(res);
+ done(res, opts.type);
},
error: function(e, msg){
that.errorView('请求异常,错误提示:'+ msg);
@@ -1039,7 +1224,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
}
});
} else if(layui.type(options.data) === 'array'){ //已知数据
- var res = {};
+ res = {};
var startLimit = curr*options.limit - options.limit;
var newData = options.data.concat();
@@ -1061,7 +1246,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
type: opts.type
}), sort();
- done(res);
+ done(res, opts.type);
}
};
@@ -1092,8 +1277,10 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
curr = curr || 1
layui.each(data, function(i1, item1){
- var tds = [], tds_fixed = [], tds_fixed_r = []
- ,numbers = i1 + options.limit*(curr - 1) + 1; // 序号
+ var tds = [];
+ var tds_fixed = [];
+ var tds_fixed_r = [];
+ var numbers = i1 + options.limit*(curr - 1) + 1; // 序号
// 数组值是否为 object,如果不是,则自动转为 object
if(typeof item1 !== 'object'){
@@ -1123,34 +1310,31 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
// td 内容
var td = ['
'
- ,''
+ +'>'
+ function(){
var tplData = $.extend(true, {
LAY_COL: item3
@@ -1158,7 +1342,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
var checkName = table.config.checkName;
var disabledName = table.config.disabledName;
- //渲染不同风格的列
+ // 渲染不同风格的列
switch(item3.type){
case 'checkbox': // 复选
return '
';
- break;
+ //break;
case 'radio': // 单选
return '
';
- break;
+ //break;
case 'numbers':
return numbers;
- break;
- };
+ //break;
+ }
//解析工具列模板
if(item3.toolbar){
@@ -1328,15 +1512,15 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
//同步分页状态
if(options.page){
options.page = $.extend({
- elem: 'layui-table-page' + options.index
- ,count: count
- ,limit: options.limit
- ,limits: options.limits || [10,20,30,40,50,60,70,80,90]
- ,groups: 3
- ,layout: ['prev', 'page', 'next', 'skip', 'count', 'limit']
- ,prev: '
'
- ,next: '
'
- ,jump: function(obj, first){
+ elem: 'layui-table-page' + options.index,
+ count: count,
+ limit: options.limit,
+ limits: options.limits || [10,20,30,40,50,60,70,80,90],
+ groups: 3,
+ layout: ['prev', 'page', 'next', 'skip', 'count', 'limit'],
+ prev: '
',
+ next: '
',
+ jump: function(obj, first){
if(!first){
//分页本身并非需要做以下更新,下面参数的同步,主要是因为其它处理统一用到了它们
//而并非用的是 options.page 中的参数(以确保分页未开启的情况仍能正常使用)
@@ -1413,9 +1597,9 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
// 获取自动计算的合并内容
var getContent = item3.totalRow ? (parseTempData.call(that, {
- item3: item3
- ,content: thisTotalNum
- ,tplData: tplData
+ item3: item3,
+ content: thisTotalNum,
+ tplData: tplData
}) || text) : text;
// 如果直接传入了合计行数据,则不输出自动计算的结果
@@ -1434,21 +1618,21 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
var attr = [];
if(item3.minWidth) attr.push('data-minwidth="'+ item3.minWidth +'"'); // 单元格最小宽度
if(item3.maxWidth) attr.push('data-maxwidth="'+ item3.maxWidth +'"'); // 单元格最小宽度
+ if(item3.style) attr.push('style="'+ item3.style +'"'); // 自定义单元格样式
return attr.join(' ');
}() +' class="'+ function(){ // 追加样式
var classNames = [];
if(item3.hide) classNames.push(HIDE); // 插入隐藏列样式
if(!item3.field) classNames.push(ELEM_COL_SPECIAL); // 插入特殊列样式
return classNames.join(' ');
- }() +'">'
- ,'
',
+ '
' + function(){
var totalRow = item3.totalRow || options.totalRow;
@@ -1462,8 +1646,8 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
}, item3));
}
return content;
- }()
- ,'
'].join('');
+ }(),
+ '
'].join('');
tds.push(td);
});
@@ -1474,8 +1658,8 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
//找到对应的列元素
Class.prototype.getColElem = function(parent, key){
- var that = this
- ,options = that.config;
+ var that = this;
+ //var options = that.config;
return parent.eq(0).find('.laytable-cell-'+ key + ':eq(0)');
};
@@ -1487,6 +1671,13 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
form.render(type, filter);
};
+ // 定向渲染表单
+ Class.prototype.renderFormByElem = function(elem){
+ layui.each(['input', 'select'], function(i, formType){
+ form.render(elem.find(formType));
+ })
+ };
+
// 同步全选按钮状态
Class.prototype.syncCheckAll = function(){
var that = this;
@@ -1510,26 +1701,49 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
checked: checkStatus.isAll,
indeterminate: !checkStatus.isAll && checkStatus.data.length // 半选
});
- form.render(checkAllElem);
};
// 标记当前活动行背景色
- Class.prototype.setRowActive = function(index, className){
+ Class.prototype.setRowActive = function(index, className, removeClass){
var that = this;
var options = that.config;
var tr = that.layBody.find('tr[data-index="'+ index +'"]');
className = className || 'layui-table-click';
- tr.addClass(className)
- .siblings('tr').removeClass(className);
+
+ if(removeClass) return tr.removeClass(className);
+
+ tr.addClass(className);
+ tr.siblings('tr').removeClass(className);
};
// 设置行选中状态
Class.prototype.setRowChecked = function(opts){
var that = this;
var options = that.config;
- var tr = that.layBody.find('tr'+ (
- opts.index === 'all' ? '' : '[data-index="'+ opts.index +'"]'
- ));
+ var isCheckAll = opts.index === 'all'; // 是否操作全部
+ var isCheckMult = layui.type(opts.index) === 'array'; // 是否操作多个
+ var needDisableTransition= isCheckAll || isCheckMult; // 减少回流
+
+ if(needDisableTransition){
+ that.layBox.addClass(DISABLED_TRANSITION);
+ }
+
+ if(isCheckMult){
+ var makeMap = {}
+ layui.each(opts.index, function(i,v){
+ makeMap[v] = true;
+ })
+ opts.index = makeMap;
+ }
+
+ // 匹配行元素
+ var selector = (isCheckAll || isCheckMult) ? 'tr' : 'tr[data-index="'+ opts.index +'"]';
+ var tr = function(tr) {
+ return isCheckAll ? tr : tr.filter(isCheckMult ? function() {
+ var dataIndex = $(this).data('index');
+ return opts.index[dataIndex];
+ } : '[data-index="'+ opts.index +'"]');
+ }(that.layBody.find(selector));
// 默认属性
opts = $.extend({
@@ -1539,36 +1753,84 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
// 同步数据选中属性值
var thisData = table.cache[that.key];
var existChecked = 'checked' in opts;
+
+ // 若为单选框,则单向选中;若为复选框,则切换选中。
var getChecked = function(value){
- // 若为单选框,则单向选中;若为复选框,则切换选中。
return opts.type === 'radio' ? true : (existChecked ? opts.checked : !value)
};
- // 设置数据选中属性
+ var ignoreTrIndex = {};
+ // 设置选中状态
layui.each(thisData, function(i, item){
- if(layui.type(item) === 'array') return; // 空项
- if(Number(opts.index) === i || opts.index === 'all'){
+ // 绕过空项和禁用项
+ if(layui.type(item) === 'array' || item[options.disabledName]){
+ ignoreTrIndex[i] = true;
+ return;
+ }
+
+ // 匹配条件
+ var matched = isCheckAll || (
+ isCheckMult ? opts.index[i] : Number(opts.index) === i
+ );
+
+ // 设置匹配项的选中值
+ if(matched){
+ // 标记数据选中状态
var checked = item[options.checkName] = getChecked(item[options.checkName]);
- tr[checked ? 'addClass' : 'removeClass'](ELEM_CHECKED); // 标记当前选中行背景色
- // 若为 radio 类型,则取消其他行选中背景色
- if(opts.type === 'radio'){
- tr.siblings().removeClass(ELEM_CHECKED);
+
+ // 标记当前行背景色
+ // 此处只更新 radio 和 单个 checkbox
+ if(!isCheckAll && !isCheckMult){
+ var currTr = tr.filter('[data-index="'+ i +'"]');
+ currTr[checked ? 'addClass' : 'removeClass'](ELEM_CHECKED);
+
+ // 若为 radio 类型,则取消其他行选中背景色
+ if(opts.type === 'radio'){
+ currTr.siblings().removeClass(ELEM_CHECKED);
+ }
}
} else if(opts.type === 'radio') {
delete item[options.checkName];
}
});
+ if(isCheckAll){
+ tr.each(function(i){
+ var index = this.getAttribute('data-index');
+ if(!ignoreTrIndex[index]){
+ var el = $(this);
+ el.toggleClass(ELEM_CHECKED, !!getChecked(thisData[index][options.checkName]))
+ }
+ });
+ }else if(isCheckMult){
+ tr.each(function(i){
+ var index = this.getAttribute('data-index');
+ if(opts.index[index] && !ignoreTrIndex[index]){
+ var el = $(this);
+ el.toggleClass(ELEM_CHECKED, !!getChecked(thisData[index][options.checkName]))
+ }
+ });
+ }
+
// 若存在复选框或单选框,则标注选中状态样式
var checkedElem = tr.find('input[lay-type="'+ ({
radio: 'layTableRadio',
checkbox: 'layTableCheckbox'
- }[opts.type] || 'checkbox') +'"]');
+ }[opts.type] || 'checkbox') +'"]:not(:disabled)');
+ var checkedSameElem = checkedElem.last();
+ var fixRElem = checkedSameElem.closest(ELEM_FIXR);
- checkedElem.prop('checked', getChecked(checkedElem.last().prop('checked')));
+ ( opts.type === 'radio' && fixRElem.hasClass(HIDE)
+ ? checkedElem.first()
+ : checkedElem ).prop('checked', getChecked(checkedSameElem.prop('checked')));
that.syncCheckAll();
- that.renderForm(opts.type);
+
+ if(needDisableTransition){
+ setTimeout(function(){
+ that.layBox.removeClass(DISABLED_TRANSITION);
+ },100)
+ }
};
// 数据排序
@@ -1586,8 +1848,8 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
if(typeof opts.field === 'string'){
field = opts.field;
that.layHeader.find('th').each(function(i, item){
- var othis = $(this)
- ,_field = othis.data('field');
+ var othis = $(this);
+ var _field = othis.data('field');
if(_field === opts.field){
opts.field = othis;
field = _field;
@@ -1597,8 +1859,8 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
}
try {
- var field = field || opts.field.data('field')
- ,key = opts.field.data('key');
+ field = field || opts.field.data('field');
+ var key = opts.field.data('key');
// 如果欲执行的排序已在状态中,则不执行渲染
if(that.sortKey && !opts.pull){
@@ -1617,8 +1879,8 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
// 记录排序索引和类型
that.sortKey = {
- field: field
- ,sort: opts.type
+ field: field,
+ sort: opts.type
};
// 默认为前端自动排序。如果否,则需自主排序(通常为服务端处理好排序)
@@ -1648,8 +1910,8 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
// 排序是否来自于点击表头事件触发
if(opts.fromEvent){
options.initSort = {
- field: field
- ,type: opts.type
+ field: field,
+ type: opts.type
};
layui.event.call(opts.field, MOD_NAME, 'sort('+ filter +')', $.extend({
config: options
@@ -1658,52 +1920,47 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
};
// 请求 loading
- Class.prototype.loading = function(hide){
+ Class.prototype.loading = function(show){
var that = this;
var options = that.config;
+
if(options.loading){
- if(hide){
- that.layInit && that.layInit.remove();
- delete that.layInit;
- that.layBox.find(ELEM_INIT).remove();
- } else {
- that.layInit = $(['
'
- ,' '
- ,'
'].join(''));
- that.layBox.append(that.layInit);
- }
+ that.layBox.find(ELEM_INIT).toggleClass(HIDE_V, !show);
}
};
- // 获取 cssRule
- Class.prototype.getCssRule = function(key, callback){
+ // 获取对应单元格的 cssRules
+ Class.prototype.cssRules = function(key, callback){
var that = this;
- var style = that.elem.find('style')[0];
- var sheet = style.sheet || style.styleSheet || {};
- var rules = sheet.cssRules || sheet.rules;
+ var style = that.elem.children('style')[0];
- layui.each(rules, function(i, item){
- if(item.selectorText === ('.laytable-cell-'+ key)){
- return callback(item), true;
+ lay.getStyleRules(style, function(item){
+ if (item.selectorText === ('.laytable-cell-'+ key)) {
+ callback(item);
+ return true;
}
});
};
- //让表格铺满
+ // 让表格铺满
Class.prototype.fullSize = function(){
- var that = this
- ,options = that.config
- ,height = options.height
- ,bodyHeight;
+ var that = this;
+ var options = that.config;
+ var height = options.height;
+ var bodyHeight;
+ var MIN_HEIGHT = 135;
if(that.fullHeightGap){
height = _WIN.height() - that.fullHeightGap;
- if(height < 135) height = 135;
+ if(height < MIN_HEIGHT) height = MIN_HEIGHT;
// that.elem.css('height', height);
} else if (that.parentDiv && that.parentHeightGap) {
height = $(that.parentDiv).height() - that.parentHeightGap;
- if (height < 135) height = 135;
+ if(height < MIN_HEIGHT) height = MIN_HEIGHT;
// that.elem.css("height", height);
+ } else if (that.customHeightFunc) {
+ height = that.customHeightFunc();
+ if(height < MIN_HEIGHT) height = MIN_HEIGHT;
}
// 如果多级表头,则填补表头高度
@@ -1752,7 +2009,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
//获取滚动条宽度
Class.prototype.getScrollWidth = function(elem){
- var width = 0;
+ var width;
if(elem){
width = elem.offsetWidth - elem.clientWidth;
} else {
@@ -1772,19 +2029,19 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
Class.prototype.scrollPatch = function(){
var that = this;
var layMainTable = that.layMain.children('table');
- var scollWidth = that.layMain.width() - that.layMain.prop('clientWidth'); // 纵向滚动条宽度
- var scollHeight = that.layMain.height() - that.layMain.prop('clientHeight'); // 横向滚动条高度
+ var scrollWidth = that.layMain.width() - that.layMain.prop('clientWidth'); // 纵向滚动条宽度
+ var scrollHeight = that.layMain.height() - that.layMain.prop('clientHeight'); // 横向滚动条高度
var getScrollWidth = that.getScrollWidth(that.layMain[0]); // 获取主容器滚动条宽度,如果有的话
var outWidth = layMainTable.outerWidth() - that.layMain.width(); // 表格内容器的超出宽度
// 添加补丁
var addPatch = function(elem){
- if(scollWidth && scollHeight){
+ if(scrollWidth && scrollHeight){
elem = elem.eq(0);
if(!elem.find('.layui-table-patch')[0]){
var patchElem = $('
'); // 补丁元素
patchElem.find('div').css({
- width: scollWidth
+ width: scrollWidth
});
elem.find('tr').append(patchElem);
}
@@ -1798,7 +2055,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
// 固定列区域高度
var mainHeight = that.layMain.height();
- var fixHeight = mainHeight - scollHeight;
+ var fixHeight = mainHeight - scrollHeight;
that.layFixed.find(ELEM_BODY).css(
'height',
@@ -1813,9 +2070,76 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
](HIDE);
// 操作栏
- that.layFixRight.css('right', scollWidth - 1);
+ that.layFixRight.css('right', scrollWidth - 1);
};
+ /**
+ * @typedef updateRowOptions
+ * @prop {number} index - 行索引
+ * @prop {Object.
} data - 行数据
+ * @prop {boolean | ((field, index) => boolean)} [related] - 更新其他包含自定义模板且可能有所关联的列视图
+ */
+ /**
+ * 更新指定行
+ * @param {updateRowOptions | updateRowOptions[]} opts
+ * @param {(field: string, value: any) => void} [callback] - 更新每个字段时的回调函数
+ */
+ Class.prototype.updateRow = function(opts, callback){
+ var that = this;
+ var ELEM_CELL = '.layui-table-cell';
+ var opts = layui.type(opts) === 'array' ? opts : [opts];
+ var dataCache = table.cache[that.key] || [];
+
+ var update = function(opt){
+ var index = opt.index;
+ var row = opt.data;
+ var related = opt.related;
+
+ var data = dataCache[index] || {};
+ var tr = that.layBody.find('tr[data-index="' + index + '"]');
+
+ // 更新缓存中的数据
+ layui.each(row, function (key, value) {
+ data[key] = value;
+ callback && callback(key, value);
+ });
+
+ // 更新单元格
+ that.eachCols(function (i, item3) {
+ var field = String(item3.field || i);
+ var shouldUpdate = field in row || ((typeof related === 'function' ? related(field, i) : related) && (item3.templet || item3.toolbar));
+ if(shouldUpdate){
+ var td = tr.children('td[data-field="' + field + '"]');
+ var cell = td.children(ELEM_CELL);
+ var content = data[item3.field];
+ cell.html(parseTempData.call(that, {
+ item3: item3,
+ content: content,
+ tplData: $.extend({
+ LAY_COL: item3,
+ }, data)
+ }));
+ td.data("content", content);
+ that.renderFormByElem(cell);
+ }
+ });
+ }
+
+ layui.each(opts, function(i, opt){
+ update(opt);
+ });
+ };
+
+ /**
+ * 更新指定行
+ * @param {string} id - table ID
+ * @param {updateRowOptions | updateRowOptions[]} options
+ */
+ table.updateRow = function (id, options){
+ var that = getThisTable(id);
+ return that.updateRow(options);
+ }
+
// 事件处理
Class.prototype.events = function(){
var that = this;
@@ -1832,7 +2156,10 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
that.layTool.on('click', '*[lay-event]', function(e){
var othis = $(this);
var events = othis.attr('lay-event');
- var openPanel = function(sets){
+ var data = table.cache[options.id];
+
+ // 弹出工具下拉面板
+ var openPanel = function(sets) {
var list = $(sets.list);
var panel = $('');
@@ -1858,112 +2185,23 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
_DOC.trigger('table.tool.panel.remove');
layer.close(that.tipsIndex);
- switch(events){
- case 'LAYTABLE_COLS': // 筛选列
- openPanel({
- list: function(){
- var lis = [];
- that.eachCols(function(i, item){
- if(item.field && item.type == 'normal'){
- lis.push(' ');
- }
- });
- return lis.join('');
- }()
- ,done: function(){
- form.on('checkbox(LAY_TABLE_TOOL_COLS)', function(obj){
- var othis = $(obj.elem);
- var checked = this.checked;
- var key = othis.data('key');
- var col = that.col(key);
- var hide = col.hide;
- var parentKey = othis.data('parentkey');
-
- if(!col.key) return;
-
- // 同步勾选列的 hide 值和隐藏样式
- col.hide = !checked;
- that.elem.find('*[data-key="'+ key +'"]')[
- checked ? 'removeClass' : 'addClass'
- ](HIDE);
-
- // 根据列的显示隐藏,同步多级表头的父级相关属性值
- if(hide != col.hide){
- that.setParentCol(!checked, parentKey);
- }
-
- // 重新适配尺寸
- that.resize();
-
- // 列筛选(显示或隐藏)后的事件
- layui.event.call(this, MOD_NAME, 'colToggled('+ filter +')', {
- col: col,
- config: options
- });
- });
- }
+ // 头部工具栏右侧图标
+ layui.each(options.defaultToolbar, function(index, item) {
+ if (item.layEvent === events) {
+ typeof item.onClick === 'function' && item.onClick({
+ data: data,
+ config: options,
+ openPanel: openPanel,
+ elem: othis
});
- break;
- case 'LAYTABLE_EXPORT': // 导出
- if(device.ie){
- layer.tips('导出功能不支持 IE,请用 Chrome 等高级浏览器导出', this, {
- tips: 3
- })
- } else {
- openPanel({
- list: function(){
- return [
- '导出 csv 格式文件 ',
- '导出 xls 格式文件 '
- ].join('')
- }()
- ,done: function(panel, list){
- list.on('click', function(){
- var type = $(this).data('type')
- table.exportFile.call(that, options.id, null, type);
- });
- }
- });
- }
- break;
- case 'LAYTABLE_PRINT': // 打印
- var printWin = window.open('about:blank', '_blank');
- var style = [''].join('')
- var html = $(that.layHeader.html()); // 输出表头
-
- html.append(that.layMain.find('table').html()); // 输出表体
- html.append(that.layTotal.find('table').html()) // 输出合计行
-
- html.find('th.layui-table-patch').remove(); // 移除补丁
- // 移除表头特殊列
- html.find('thead>tr>th.'+ ELEM_COL_SPECIAL).filter(function(i, thElem){
- return !$(thElem).children('.'+ ELEM_GROUP).length; // 父级表头除外
- }).remove();
- html.find('tbody>tr>td.'+ ELEM_COL_SPECIAL).remove(); // 移除表体特殊列
-
- printWin.document.write(style + html.prop('outerHTML'));
- printWin.document.close();
-
- if(layui.device('edg').edg){
- printWin.onafterprint = printWin.close;
- printWin.print();
- }else{
- printWin.print();
- printWin.close();
- }
- break;
- }
+ return true;
+ }
+ });
+ // table toolbar 事件
layui.event.call(this, MOD_NAME, 'toolbar('+ filter +')', $.extend({
- event: events
- ,config: options
+ event: events,
+ config: options
},{}));
});
@@ -1988,16 +2226,16 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
var events = othis.attr('lay-event');
layui.event.call(this, MOD_NAME, 'pagebar('+ filter +')', $.extend({
- event: events
- ,config: options
+ event: events,
+ config: options
},{}));
});
// 拖拽调整宽度
th.on('mousemove', function(e){
- var othis = $(this)
- ,oLeft = othis.offset().left
- ,pLeft = e.clientX - oLeft;
+ var othis = $(this);
+ var oLeft = othis.offset().left;
+ var pLeft = e.clientX - oLeft;
if(othis.data('unresize') || thisTable.eventMoveElem){
return;
}
@@ -2006,6 +2244,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
}).on('mouseleave', function(){
var othis = $(this);
if(thisTable.eventMoveElem) return;
+ dict.allowResize = false;
_BODY.css('cursor', '');
}).on('mousedown', function(e){
var othis = $(this);
@@ -2014,7 +2253,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
e.preventDefault();
dict.offset = [e.clientX, e.clientY]; //记录初始坐标
- that.getCssRule(key, function(item){
+ that.cssRules(key, function(item){
var width = item.style.width || othis.outerWidth();
dict.rule = item;
dict.ruleWidth = parseFloat(width);
@@ -2039,7 +2278,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
if(dict.rule){
var setWidth = dict.ruleWidth + e.clientX - dict.offset[0];
- var id = thisTable.eventMoveElem.closest('.' + ELEM_VIEW).attr('lay-id');
+ var id = thisTable.eventMoveElem.closest('.' + ELEM_VIEW).attr(MOD_ID);
var thatTable = getThisTable(id);
if(!thatTable) return;
@@ -2055,7 +2294,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
}).on('mouseup', function(e){
if(thisTable.eventMoveElem){
var th = thisTable.eventMoveElem; // 当前触发拖拽的 th 元素
- var id = th.closest('.' + ELEM_VIEW).attr('lay-id');
+ var id = th.closest('.' + ELEM_VIEW).attr(MOD_ID);
var thatTable = getThisTable(id);
if(!thatTable) return;
@@ -2074,7 +2313,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
delete thisTable.eventMoveElem;
// 列拖拽宽度后的事件
- thatTable.getCssRule(key, function(item){
+ thatTable.cssRules(key, function(item){
col.width = parseFloat(item.style.width);
layui.event.call(th[0], MOD_NAME, 'colResized('+ filter +')', {
col: col,
@@ -2114,9 +2353,9 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
fromEvent: true
});
}).find(ELEM_SORT+' .layui-edge ').on('click', function(e){
- var othis = $(this)
- ,index = othis.index()
- ,field = othis.parents('th').eq(0).data('field')
+ var othis = $(this);
+ var index = othis.index();
+ var field = othis.parents('th').eq(0).data('field');
layui.stope(e);
if(index === 0){
that.sort({
@@ -2156,43 +2395,13 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
},
update: function(fields, related){ // 修改行数据
fields = fields || {};
- layui.each(fields, function(key, value){
- var td = tr.children('td[data-field="'+ key +'"]');
- var cell = td.children(ELEM_CELL); // 获取当前修改的列
-
- // 更新缓存中的数据
- data[key] = obj.data[key] = value;
-
- // 更新相应列视图
- that.eachCols(function(i, item3){
- if(item3.field == key){
- cell.html(parseTempData.call(that, {
- item3: item3
- ,content: value
- ,tplData: $.extend({
- LAY_COL: item3
- }, data)
- }));
- td.data('content', value);
- }
- // 更新其他包含自定义模板且可能有所关联的列视图
- else if(related && (item3.templet || item3.toolbar)){
- var thisTd = tr.children('td[data-field="'+ (item3.field || i) +'"]');
- var content = data[item3.field];
-
- thisTd.children(ELEM_CELL).html(parseTempData.call(that, {
- item3: item3
- ,content: content
- ,tplData: $.extend({
- LAY_COL: item3
- }, data)
- }));
- thisTd.data('content', content);
- }
- });
+ that.updateRow({
+ index: index,
+ data: fields,
+ related: related
+ }, function(key, value){
+ obj.data[key] = value;
});
-
- that.renderForm();
},
// 设置行选中状态
setRowChecked: function(opts){
@@ -2288,26 +2497,39 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
if(othis.data('off')) return; // 不触发事件
that.layBody.find('tr:eq('+ index +')').removeClass(ELEM_HOVER)
}).on('click', 'tr', function(e){ // 单击行
- // 不支持行单击事件的元素
- var UNROW = '.layui-form-checkbox,.layui-form-switch,.layui-form-radio,[lay-unrow]';
- if( $(e.target).is(UNROW) || $(e.target).closest(UNROW)[0]){
- return;
- };
- setRowEvent.call(this, 'row');
- }).on('dblclick', 'tr', function(){ // 双击行
- setRowEvent.call(this, 'rowDouble');
+ setRowEvent.call(this, 'row', e);
+ }).on('dblclick', 'tr', function(e){ // 双击行
+ setRowEvent.call(this, 'rowDouble', e);
}).on('contextmenu', 'tr', function(e){ // 菜单
if (!options.defaultContextmenu) e.preventDefault();
- setRowEvent.call(this, 'rowContextmenu');
+ setRowEvent.call(this, 'rowContextmenu', e);
});
// 创建行单击、双击、菜单事件
- var setRowEvent = function(eventType){
+ var setRowEvent = function(eventType, e){
var othis = $(this);
- if(othis.data('off')) return; //不触发事件
- layui.event.call(this,
+ if(othis.data('off')) return; // 不触发事件
+
+ // 不触发「行单/双击事件」的子元素
+ if (eventType !== 'rowContextmenu') {
+ var UNROW = [
+ '.layui-form-checkbox',
+ '.layui-form-switch',
+ '.layui-form-radio',
+ '[lay-unrow]'
+ ].join(',');
+
+ if($(e.target).is(UNROW) || $(e.target).closest(UNROW)[0]){
+ return;
+ }
+ }
+
+ layui.event.call(
+ this,
MOD_NAME, eventType + '('+ filter +')',
- commonMember.call(othis.children('td')[0])
+ commonMember.call(othis.children('td')[0], {
+ e: e
+ })
);
};
@@ -2339,8 +2561,9 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
}
return inputElem;
}());
-
- input[0].value = othis.data('content') || data[field] || elemCell.text();
+ input[0].value = function(val) {
+ return (val === undefined || val === null) ? '' : val;
+ }(othis.data('content') || data[field]);
othis.find('.'+ELEM_EDIT)[0] || othis.append(input);
input.focus();
e && layui.stope(e);
@@ -2391,7 +2614,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
// 表格主体单元格触发编辑的事件
that.layBody.on(options.editTrigger, 'td', function(e){
- renderGridEdit(this, e)
+ renderGridEdit(this, e);
}).on('mouseenter', 'td', function(){
showGridExpandIcon.call(this)
}).on('mouseleave', 'td', function(){
@@ -2413,51 +2636,106 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
var othis = $(this);
var elemCell = othis.children(ELEM_CELL);
- if(othis.data('off')) return; //不触发事件
+ if(othis.data('off')) return; // 不触发事件
+ if(othis.parent().hasClass(ELEM_EXPAND)) return; // 是否已为展开状态
if(hide){
othis.find('.layui-table-grid-down').remove();
} else if((
- elemCell.prop('scrollWidth') > elemCell.outerWidth() ||
+ elemCell.prop('scrollWidth') > elemCell.prop('clientWidth') ||
elemCell.find("br").length > 0
) && !options.lineStyle){
if(elemCell.find('.'+ ELEM_GRID_DOWN)[0]) return;
othis.append('
');
}
};
- // 单元格内容展开
- var gridExpand = function(e){
+ // 展开单元格内容
+ var gridExpand = function(e, expandedMode){
var othis = $(this);
var td = othis.parent();
+ var key = td.data('key');
+ var col = that.col(key);
+ var index = td.parent().data('index');
var elemCell = td.children(ELEM_CELL);
+ var ELEM_CELL_C = 'layui-table-cell-c';
+ var elemCellClose = $('');
- that.tipsIndex = layer.tips([
- ' ',
+ elemCell.html(),
+ '
',
+ ' '
+ ].join(''), elemCell[0], {
+ tips: [3, ''],
+ time: -1,
+ anim: -1,
+ maxWidth: (device.ios || device.android) ? 300 : that.elem.width()/2,
+ isOutAnim: false,
+ skin: 'layui-table-tips',
+ success: function(layero, index){
+ layero.find('.layui-table-tips-c').on('click', function(){
+ layer.close(index);
+ });
}
- if(options.size === 'lg'){
- return 'padding: 14px 15px;';
- }
- return '';
- }() +'">',
- elemCell.html(),
- ' ',
- ' '
- ].join(''), elemCell[0], {
- tips: [3, ''],
- time: -1,
- anim: -1,
- maxWidth: (device.ios || device.android) ? 300 : that.elem.width()/2,
- isOutAnim: false,
- skin: 'layui-table-tips',
- success: function(layero, index){
- layero.find('.layui-table-tips-c').on('click', function(){
- layer.close(index);
+ });
+ } else { // 多行展开风格
+ // 恢复其他已经展开的单元格
+ that.elem.find('.'+ ELEM_CELL_C).trigger('click');
+
+ // 设置当前单元格展开宽度
+ that.cssRules(key, function(item){
+ var width = item.style.width;
+ var expandedWidth = col.expandedWidth || options.cellExpandedWidth;
+
+ // 展开后的宽度不能小于当前宽度
+ if(expandedWidth < parseFloat(width)) expandedWidth = parseFloat(width);
+
+ elemCellClose.data('cell-width', width);
+ item.style.width = expandedWidth + 'px';
+
+ setTimeout(function(){
+ that.scrollPatch(); // 滚动条补丁
});
- }
- });
+ });
+ // 设置当前单元格展开样式
+ that.setRowActive(index, ELEM_EXPAND);
+
+ // 插入关闭按钮
+ if(!elemCell.next('.'+ ELEM_CELL_C)[0]){
+ elemCell.after(elemCellClose);
+ }
+
+ // 关闭展开状态
+ elemCellClose.on('click', function(){
+ var $this = $(this);
+ that.setRowActive(index, [ELEM_EXPAND, ELEM_HOVER].join(' '), true); // 移除单元格展开样式
+ that.cssRules(key, function(item){
+ item.style.width = $this.data('cell-width'); // 恢复单元格展开前的宽度
+ setTimeout(function(){
+ that.resize(); // 滚动条补丁
+ });
+ });
+ $this.remove();
+ // 重置单元格滚动条位置
+ elemCell.scrollTop(0);
+ elemCell.scrollLeft(0);
+ });
+ }
+
+ othis.remove();
layui.stope(e);
};
@@ -2467,7 +2745,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
});
// 表格合计栏单元格展开事件
that.layTotal.on('click', '.'+ ELEM_GRID_DOWN, function(e){
- gridExpand.call(this, e);
+ gridExpand.call(this, e, 'tips'); // 强制采用 tips 风格
});
// 行工具条操作事件
@@ -2514,20 +2792,41 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
layer.close(that.tipsIndex);
});
- // 适应
- _WIN.on('resize', function(){
- that.resize();
+ // 固定列滚轮事件 - 临时兼容方案
+ that.layFixed.find(ELEM_BODY).on('mousewheel DOMMouseScroll', function(e) {
+ var delta = e.originalEvent.wheelDelta || -e.originalEvent.detail;
+ var scrollTop = that.layMain.scrollTop();
+ var step = 30;
+
+ e.preventDefault();
+ that.layMain.scrollTop(scrollTop + (delta > 0 ? -step : step));
});
+
+ if(window.ResizeObserver){
+ if(!that.resizeObserver){
+ that.resizeObserver = new ResizeObserver(function(){
+ table.resize(that.key);
+ });
+ }
+ that.resizeObserver.observe(that.elem[0]);
+ }
};
- //一次性事件
- ;(function(){
- //全局点击
+ // 全局事件
+ (function(){
+ // 自适应尺寸
+ _WIN.on('resize', function(){
+ layui.each(thisTable.that, function(){
+ this.resize();
+ });
+ });
+
+ // 全局点击
_DOC.on('click', function(){
_DOC.trigger('table.remove.tool.panel');
});
- //工具面板移除事件
+ // 工具面板移除事件
_DOC.on('table.remove.tool.panel', function(){
$('.' + ELEM_TOOL_PANEL).remove();
});
@@ -2578,8 +2877,8 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
var row = $.extend({
title: th.text()
- ,colspan: parseInt(th.attr('colspan')) || 0 //列单元格
- ,rowspan: parseInt(th.attr('rowspan')) || 0 //行单元格
+ ,colspan: parseInt(th.attr('colspan')) || 1 //列单元格
+ ,rowspan: parseInt(th.attr('rowspan')) || 1 //行单元格
}, itemData);
options.cols[i].push(row);
@@ -2648,8 +2947,8 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
// 遍历表头
table.eachCols = function(id, callback, cols){
- var config = thisTable.config[id] || {}
- ,arrs = [], index = 0;
+ var config = thisTable.config[id] || {};
+ var arrs = [], index = 0;
cols = $.extend(true, [], cols || config.cols);
@@ -2683,7 +2982,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
//计算全选个数
layui.each(data, function(i, item){
- if(layui.type(item) === 'array'){
+ if(layui.type(item) === 'array' || item[table.config.disabledName]){
invalidNum++; // 无效数据,或已删除的
return;
}
@@ -2709,12 +3008,12 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
// 获取表格当前页的所有行数据
table.getData = function(id){
- var arr = []
- ,data = table.cache[id] || [];
+ var arr = [];
+ var data = table.cache[id] || [];
layui.each(data, function(i, item){
if(layui.type(item) === 'array'){
return;
- };
+ }
arr.push(table.clearCacheKey(item));
});
return arr;
@@ -2749,13 +3048,28 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
var thatTable = thisTable.that[id];
var config = thisTable.config[id] || {};
var textType = ({
- csv: 'text/csv'
- ,xls: 'application/vnd.ms-excel'
+ csv: 'text/csv',
+ xls: 'application/vnd.ms-excel'
})[type];
var alink = document.createElement("a");
if(device.ie) return hint.error('IE_NOT_SUPPORT_EXPORTS');
+ // 处理 treeTable 数据
+ var isTreeTable = config.tree && config.tree.view;
+ if (isTreeTable) {
+ try {
+ data = $.extend(true, [], table.cache[id]);
+ data = (function fn(data) {
+ return data.reduce(function (acc, obj){
+ var children = obj.children || [];
+ delete obj.children;
+ return acc.concat(obj, fn(children));
+ }, []);
+ })(Array.from(data));
+ } catch (e) {}
+ }
+
alink.href = 'data:'+ textType +';charset=utf-8,\ufeff'+ encodeURIComponent(function(){
var dataTitle = [];
var dataMain = [];
@@ -2775,8 +3089,11 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
} else {
table.eachCols(id, function(i3, item3){
if(item3.ignoreExport === false || item3.field && item3.type == 'normal'){
- // 不导出隐藏列
- if(item3.hide || item3.ignoreExport){
+ // 不导出隐藏列,除非设置 ignoreExport 强制导出
+ if (
+ (item3.hide && item3.ignoreExport !== false) ||
+ item3.ignoreExport === true // 忽略导出
+ ) {
if(i1 == 0) fieldsIsHide[item3.field] = true; // 记录隐藏列
return;
}
@@ -2788,12 +3105,13 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
// 解析内容
content = parseTempData.call(thatTable, {
- item3: item3
- ,content: content
- ,tplData: item1
- ,text: 'text'
- ,obj: {
+ item3: item3,
+ content: content,
+ tplData: item1,
+ text: 'text',
+ obj: {
td: function(field){
+ if (isTreeTable) i1 = item1['LAY_DATA_INDEX']; // 兼容 treeTable 索引
var td = thatTable.layBody.find('tr[data-index="'+ i1 +'"]>td');
return td.filter('[data-field="'+ field +'"]');
}
@@ -2807,6 +3125,9 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
// 插入内容
vals.push(content);
+ }else if(item3.field && item3.type !== 'normal'){
+ // https://gitee.com/layui/layui/issues/I8PHCR
+ if(i1 == 0) fieldsIsHide[item3.field] = true;
}
});
}
@@ -2901,7 +3222,7 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
var dataParams = new RegExp('^('+ [
'elem', 'id', 'cols', 'width', 'height', 'maxHeight',
'toolbar', 'defaultToolbar',
- 'className', 'css', 'totalRow', 'pagebar'
+ 'className', 'css', 'pagebar'
].join('|') + ')$');
// 过滤与数据无关的参数
@@ -2937,5 +3258,3 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
exports(MOD_NAME, table);
});
-
-
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/transfer.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/transfer.js
index aa1adcd..200eb28 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/modules/transfer.js
+++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/transfer.js
@@ -56,7 +56,7 @@ layui.define(['laytpl', 'form'], function(exports){
var getThisModuleConfig = function(id){
var config = thisModule.config[id];
if(!config) hint.error('The ID option was not found in the '+ MOD_NAME +' instance');
- return; config || null;
+ return config || null;
};
// 字符常量
@@ -73,39 +73,39 @@ layui.define(['laytpl', 'form'], function(exports){
// 穿梭框模板
var TPL_BOX = function(obj){
obj = obj || {};
- return [''
- ,''
- ,'{{# if(d.data.showSearch){ }}'
- ,'
'
- ,' '
- ,' '
- ,'
'
- ,'{{# } }}'
- ,'
'
- ,'
'].join('');
+ return ['',
+ '',
+ '{{# if(d.data.showSearch){ }}',
+ '
',
+ ' ',
+ ' ',
+ '
',
+ '{{# } }}',
+ '
',
+ '
'].join('');
};
// 主模板
- var TPL_MAIN = [''].join('');
+ var TPL_MAIN = [''].join('');
// 构造器
var Class = function(options){
@@ -115,7 +115,7 @@ layui.define(['laytpl', 'form'], function(exports){
that.render();
};
- //默认配置
+ // 默认配置
Class.prototype.config = {
title: ['列表一', '列表二'],
width: 200,
@@ -130,31 +130,31 @@ layui.define(['laytpl', 'form'], function(exports){
}
};
- //重载实例
+ // 重载实例
Class.prototype.reload = function(options){
var that = this;
that.config = $.extend({}, that.config, options);
that.render();
};
- //渲染
+ // 渲染
Class.prototype.render = function(){
var that = this;
var options = that.config;
- //解析模板
+ // 解析模板
var thisElem = that.elem = $(laytpl(TPL_MAIN, {
open: '{{', // 标签符前缀
close: '}}' // 标签符后缀
}).render({
- data: options
- ,index: that.index //索引
+ data: options,
+ index: that.index // 索引
}));
var othis = options.elem = $(options.elem);
if(!othis[0]) return;
- //初始化属性
+ // 初始化属性
options.data = options.data || [];
options.value = options.value || [];
@@ -164,20 +164,20 @@ layui.define(['laytpl', 'form'], function(exports){
);
that.key = options.id;
- //插入组件结构
+ // 插入组件结构
othis.html(that.elem);
- //各级容器
+ // 各级容器
that.layBox = that.elem.find('.'+ ELEM_BOX)
that.layHeader = that.elem.find('.'+ ELEM_HEADER)
that.laySearch = that.elem.find('.'+ ELEM_SEARCH)
that.layData = thisElem.find('.'+ ELEM_DATA);
that.layBtn = thisElem.find('.'+ ELEM_ACTIVE + ' .layui-btn');
- //初始化尺寸
+ // 初始化尺寸
that.layBox.css({
- width: options.width
- ,height: options.height
+ width: options.width,
+ height: options.height
});
that.layData.css({
height: function(){
@@ -189,8 +189,8 @@ layui.define(['laytpl', 'form'], function(exports){
}()
});
- that.renderData(); //渲染数据
- that.events(); //事件
+ that.renderData(); // 渲染数据
+ that.events(); // 事件
};
// 渲染数据
@@ -233,27 +233,28 @@ layui.define(['laytpl', 'form'], function(exports){
that.renderCheckBtn();
};
- //渲染表单
+ // 渲染表单
Class.prototype.renderForm = function(type){
form.render(type, 'LAY-transfer-'+ this.index);
};
- //同步复选框和按钮状态
+ // 同步复选框和按钮状态
Class.prototype.renderCheckBtn = function(obj){
- var that = this
- ,options = that.config;
+ var that = this;
+ var options = that.config;
obj = obj || {};
that.layBox.each(function(_index){
- var othis = $(this)
- ,thisDataElem = othis.find('.'+ ELEM_DATA)
- ,allElemCheckbox = othis.find('.'+ ELEM_HEADER).find('input[type="checkbox"]')
- ,listElemCheckbox = thisDataElem.find('input[type="checkbox"]');
+ var othis = $(this);
+ var thisDataElem = othis.find('.'+ ELEM_DATA);
+ var allElemCheckbox = othis.find('.'+ ELEM_HEADER).find('input[type="checkbox"]');
+ var listElemCheckbox = thisDataElem.find('input[type="checkbox"]');
- //同步复选框和按钮状态
- var nums = 0
- ,haveChecked = false;
+ // 同步复选框和按钮状态
+ var nums = 0;
+ var haveChecked = false;
+
listElemCheckbox.each(function(){
var isHide = $(this).data('hide');
if(this.checked || this.disabled || isHide){
@@ -264,10 +265,10 @@ layui.define(['laytpl', 'form'], function(exports){
}
});
- allElemCheckbox.prop('checked', haveChecked && nums === listElemCheckbox.length); //全选复选框状态
- that.layBtn.eq(_index)[haveChecked ? 'removeClass' : 'addClass'](DISABLED); //对应的按钮状态
+ allElemCheckbox.prop('checked', haveChecked && nums === listElemCheckbox.length); // 全选复选框状态
+ that.layBtn.eq(_index)[haveChecked ? 'removeClass' : 'addClass'](DISABLED); // 对应的按钮状态
- //无数据视图
+ // 无数据视图
if(!obj.stopNone){
var isNone = thisDataElem.children('li:not(.'+ HIDE +')').length
that.noneView(thisDataElem, isNone ? '' : options.text.none);
@@ -277,7 +278,7 @@ layui.define(['laytpl', 'form'], function(exports){
that.renderForm('checkbox');
};
- //无数据视图
+ // 无数据视图
Class.prototype.noneView = function(thisDataElem, text){
var createNoneElem = $(''+ (text || '') +'
');
if(thisDataElem.find('.'+ NONE)[0]){
@@ -286,11 +287,12 @@ layui.define(['laytpl', 'form'], function(exports){
text.replace(/\s/g, '') && thisDataElem.append(createNoneElem);
};
- //同步 value 属性值
+ // 同步 value 属性值
Class.prototype.setValue = function(){
- var that = this
- ,options = that.config
- ,arr = [];
+ var that = this;
+ var options = that.config;
+ var arr = [];
+
that.layBox.eq(1).find('.'+ ELEM_DATA +' input[type="checkbox"]').each(function(){
var isHide = $(this).data('hide');
isHide || arr.push(this.value);
@@ -300,14 +302,14 @@ layui.define(['laytpl', 'form'], function(exports){
return that;
};
- //解析数据
+ // 解析数据
Class.prototype.parseData = function(callback){
- var that = this
- ,options = that.config
- ,newData = [];
+ var that = this;
+ var options = that.config;
+ var newData = [];
layui.each(options.data, function(index, item){
- //解析格式
+ // 解析格式
item = (typeof options.parseData === 'function'
? options.parseData(item)
: item) || item;
@@ -326,11 +328,11 @@ layui.define(['laytpl', 'form'], function(exports){
return that;
};
- //获得右侧面板数据
+ // 获得右侧面板数据
Class.prototype.getData = function(value){
- var that = this
- ,options = that.config
- ,selectedData = [];
+ var that = this;
+ var options = that.config;
+ var selectedData = [];
that.setValue();
@@ -345,30 +347,30 @@ layui.define(['laytpl', 'form'], function(exports){
return selectedData;
};
- //执行穿梭
+ // 执行穿梭
Class.prototype.transfer = function (_index, elem) {
- var that = this
- ,options = that.config
- ,thisBoxElem = that.layBox.eq(_index)
- ,arr = []
+ var that = this;
+ var options = that.config;
+ var thisBoxElem = that.layBox.eq(_index);
+ var arr = [];
if (!elem) {
- //通过按钮触发找到选中的进行移动
+ // 通过按钮触发找到选中的进行移动
thisBoxElem.each(function(_index){
- var othis = $(this)
- ,thisDataElem = othis.find('.'+ ELEM_DATA);
+ var othis = $(this);
+ var thisDataElem = othis.find('.'+ ELEM_DATA);
thisDataElem.children('li').each(function(){
- var thisList = $(this)
- ,thisElemCheckbox = thisList.find('input[type="checkbox"]')
- ,isHide = thisElemCheckbox.data('hide');
+ var thisList = $(this);
+ var thisElemCheckbox = thisList.find('input[type="checkbox"]');
+ var isHide = thisElemCheckbox.data('hide');
if(thisElemCheckbox[0].checked && !isHide){
thisElemCheckbox[0].checked = false;
thisBoxElem.siblings('.'+ ELEM_BOX).find('.'+ ELEM_DATA).append(thisList.clone());
thisList.remove();
- //记录当前穿梭的数据
+ // 记录当前穿梭的数据
arr.push(thisElemCheckbox[0].value);
}
@@ -376,15 +378,15 @@ layui.define(['laytpl', 'form'], function(exports){
});
});
} else {
- //双击单条记录移动
- var thisList = elem
- ,thisElemCheckbox = thisList.find('input[type="checkbox"]')
+ // 双击单条记录移动
+ var thisList = elem;
+ var thisElemCheckbox = thisList.find('input[type="checkbox"]');
thisElemCheckbox[0].checked = false;
thisBoxElem.siblings('.'+ ELEM_BOX).find('.'+ ELEM_DATA).append(thisList.clone());
thisList.remove();
- //记录当前穿梭的数据
+ // 记录当前穿梭的数据
arr.push(thisElemCheckbox[0].value);
that.setValue();
@@ -392,28 +394,28 @@ layui.define(['laytpl', 'form'], function(exports){
that.renderCheckBtn();
- //穿梭时,如果另外一个框正在搜索,则触发匹配
+ // 穿梭时,如果另外一个框正在搜索,则触发匹配
var siblingInput = thisBoxElem.siblings('.'+ ELEM_BOX).find('.'+ ELEM_SEARCH +' input')
siblingInput.val() === '' || siblingInput.trigger('keyup');
- //穿梭时的回调
+ // 穿梭时的回调
options.onchange && options.onchange(that.getData(arr), _index);
}
- //事件
+ // 事件
Class.prototype.events = function(){
- var that = this
- ,options = that.config;
+ var that = this;
+ var options = that.config;
- //左右复选框
+ // 左右复选框
that.elem.on('click', 'input[lay-filter="layTransferCheckbox"]+', function(){
- var thisElemCheckbox = $(this).prev()
- ,checked = thisElemCheckbox[0].checked
- ,thisDataElem = thisElemCheckbox.parents('.'+ ELEM_BOX).eq(0).find('.'+ ELEM_DATA);
+ var thisElemCheckbox = $(this).prev();
+ var checked = thisElemCheckbox[0].checked;
+ var thisDataElem = thisElemCheckbox.parents('.'+ ELEM_BOX).eq(0).find('.'+ ELEM_DATA);
if(thisElemCheckbox[0].disabled) return;
- //判断是否全选
+ // 判断是否全选
if(thisElemCheckbox.attr('lay-type') === 'all'){
thisDataElem.find('input[type="checkbox"]').each(function(){
if(this.disabled) return;
@@ -428,26 +430,36 @@ layui.define(['laytpl', 'form'], function(exports){
// 双击穿梭
that.elem.on('dblclick', '.' + ELEM_DATA + '>li', function(event){
- var elemThis = $(this)
- ,thisElemCheckbox = elemThis.children('input[type="checkbox"]')
- ,thisDataElem = elemThis.parent()
- ,thisBoxElem = thisDataElem.parent()
+ var elemThis = $(this);
+ var thisElemCheckbox = elemThis.children('input[type="checkbox"]');
+ var thisDataElem = elemThis.parent();
+ var thisBoxElem = thisDataElem.parent();
+ var index = thisBoxElem.data('index');
if(thisElemCheckbox[0].disabled) return;
- that.transfer(thisBoxElem.data('index'), elemThis);
+ // 根据 dblclick 回调函数返回值决定是否执行穿梭 --- 2.9.3+
+ var ret = typeof options.dblclick === 'function' ? options.dblclick({
+ elem: elemThis,
+ data: that.getData([thisElemCheckbox[0].value])[0],
+ index: index
+ }) : null;
+
+ if(ret === false) return;
+
+ that.transfer(index, elemThis);
})
// 穿梭按钮事件
that.layBtn.on('click', function(){
- var othis = $(this)
- ,_index = othis.data('index')
- if(othis.hasClass(DISABLED)) return;
+ var othis = $(this);
+ var _index = othis.data('index');
+ if(othis.hasClass(DISABLED)) return;
that.transfer(_index);
});
- //搜索
+ // 搜索
that.laySearch.find('input').on('keyup', function(){
var value = this.value;
var thisDataElem = $(this).parents('.'+ ELEM_SEARCH).eq(0).siblings('.'+ ELEM_DATA);
@@ -472,17 +484,17 @@ layui.define(['laytpl', 'form'], function(exports){
that.renderCheckBtn();
- //无匹配数据视图
+ // 无匹配数据视图
var isNone = thisListElem.length === thisDataElem.children('li.'+ HIDE).length;
that.noneView(thisDataElem, isNone ? options.text.searchNone : '');
});
};
- //记录所有实例
- thisModule.that = {}; //记录所有实例对象
- thisModule.config = {}; //记录所有实例配置项
+ // 记录所有实例
+ thisModule.that = {}; // 记录所有实例对象
+ thisModule.config = {}; // 记录所有实例配置项
- //重载实例
+ // 重载实例
transfer.reload = function(id, options){
var that = thisModule.that[id];
that.reload(options);
@@ -490,13 +502,13 @@ layui.define(['laytpl', 'form'], function(exports){
return thisModule.call(that);
};
- //获得选中的数据(右侧面板)
+ // 获得选中的数据(右侧面板)
transfer.getData = function(id){
var that = thisModule.that[id];
return that.getData();
};
- //核心入口
+ // 核心入口
transfer.render = function(options){
var inst = new Class(options);
return thisModule.call(inst);
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/tree.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/tree.js
index 4fc94a4..1397d97 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/modules/tree.js
+++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/tree.js
@@ -2,19 +2,26 @@
* tree 树组件
*/
-layui.define('form', function(exports){
+layui.define(['form','util'], function(exports){
"use strict";
var $ = layui.$;
var form = layui.form;
var layer = layui.layer;
+ var util = layui.util;
// 模块名
var MOD_NAME = 'tree';
// 外部接口
var tree = {
- config: {},
+ config: {
+ customName: { // 自定义 data 字段名
+ id: 'id',
+ title: 'title',
+ children: 'children'
+ }
+ },
index: layui[MOD_NAME] ? (layui[MOD_NAME].index + 10000) : 0,
// 设置全局项
@@ -122,10 +129,13 @@ layui.define('form', function(exports){
Class.prototype.render = function(){
var that = this;
var options = that.config;
+
+ // 初始化自定义字段名
+ options.customName = $.extend({}, tree.config.customName, options.customName);
that.checkids = [];
- var temp = $('
');
+ var temp = $('
');
that.tree(temp);
var othis = options.elem = $(options.elem);
@@ -178,13 +188,14 @@ layui.define('form', function(exports){
Class.prototype.tree = function(elem, children){
var that = this;
var options = that.config;
+ var customName = options.customName;
var data = children || options.data;
// 遍历数据
layui.each(data, function(index, item){
- var hasChild = item.children && item.children.length > 0;
+ var hasChild = item[customName.children] && item[customName.children].length > 0;
var packDiv = $('
');
- var entryDiv = $([''
+ var entryDiv = $(['
'
,'
'
,'
'
// 箭头
@@ -202,15 +213,15 @@ layui.define('form', function(exports){
// 复选框
,function(){
- return options.showCheckbox ? '
' : '';
+ return options.showCheckbox ? '
' : '';
}()
// 节点
,function(){
if(options.isJump && item.href){
- return '
'+ (item.title || item.label || options.text.defaultNodeName) +' ';
+ return '
'+ (item[customName.title] || item.label || options.text.defaultNodeName) +' ';
}else{
- return '
'+ (item.title || item.label || options.text.defaultNodeName) +' ';
+ return '
'+ (item[customName.title] || item.label || options.text.defaultNodeName) +' ';
}
}()
,'
'
@@ -241,7 +252,7 @@ layui.define('form', function(exports){
// 如果有子节点,则递归继续生成树
if(hasChild){
entryDiv.append(packDiv);
- that.tree(packDiv, item.children);
+ that.tree(packDiv, item[customName.children]);
};
elem.append(entryDiv);
@@ -261,7 +272,7 @@ layui.define('form', function(exports){
// 选择框
if(options.showCheckbox){
- item.checked && that.checkids.push(item.id);
+ item.checked && that.checkids.push(item[customName.id]);
that.checkClick(entryDiv, item);
}
@@ -296,10 +307,12 @@ layui.define('form', function(exports){
elem.removeClass(ELEM_SPREAD);
packCont.slideUp(200);
iconClick.removeClass(ICON_SUB).addClass(ICON_ADD);
+ that.updateFieldValue(item, 'spread', false);
}else{
elem.addClass(ELEM_SPREAD);
packCont.slideDown(200);
iconClick.addClass(ICON_SUB).removeClass(ICON_ADD);
+ that.updateFieldValue(item, 'spread', true);
// 是否手风琴
if(options.accordion){
@@ -328,7 +341,7 @@ layui.define('form', function(exports){
// 获取选中状态
if(elemCheckbox[0]){
- item['checked'] = elemCheckbox.prop('checked');
+ that.updateFieldValue(item, 'checked', elemCheckbox.prop('checked'));
}
// 点击产生的回调
@@ -339,22 +352,29 @@ layui.define('form', function(exports){
});
});
};
+
+ // 更新数据源 checked,spread 字段值
+ Class.prototype.updateFieldValue = function(obj, field, value){
+ if(field in obj) obj[field] = value;
+ };
// 计算复选框选中状态
Class.prototype.setCheckbox = function(elem, item, elemCheckbox){
var that = this;
var options = that.config;
+ var customName = options.customName;
var checked = elemCheckbox.prop('checked');
if(elemCheckbox.prop('disabled')) return;
// 同步子节点选中状态
- if(typeof item.children === 'object' || elem.find('.'+ELEM_PACK)[0]){
+ if(typeof item[customName.children] === 'object' || elem.find('.'+ELEM_PACK)[0]){
var elemCheckboxs = elem.find('.'+ ELEM_PACK).find('input[same="layuiTreeCheck"]');
elemCheckboxs.each(function(index){
if(this.disabled) return; // 不可点击则跳过
- if(item.children[index]) item.children[index]['checked'] = checked;
- this.checked = checked;
+ var children = item[customName.children][index];
+ if(children) that.updateFieldValue(children, 'checked', checked);
+ that.updateFieldValue(this, 'checked', checked);
});
};
@@ -410,7 +430,7 @@ layui.define('form', function(exports){
if(elemCheckbox.prop('disabled')) return;
that.setCheckbox(elem, item, elemCheckbox);
- item.checked = checked;
+ that.updateFieldValue(item, 'checked', checked);
// 复选框点击产生的回调
options.oncheck && options.oncheck({
@@ -425,6 +445,7 @@ layui.define('form', function(exports){
Class.prototype.operate = function(elem, item){
var that = this;
var options = that.config;
+ var customName = options.customName;
var entry = elem.children('.'+ ELEM_ENTRY);
var elemMain = entry.children('.'+ ELEM_MAIN);
@@ -458,8 +479,8 @@ layui.define('form', function(exports){
var key = options.operate && options.operate(returnObj);
var obj = {};
- obj.title = options.text.defaultNodeName;
- obj.id = key;
+ obj[customName.title] = options.text.defaultNodeName;
+ obj[customName.id] = key;
that.tree(elem.children('.'+ELEM_PACK), [obj]);
// 放在新增后面,因为要对元素进行操作
@@ -527,16 +548,16 @@ layui.define('form', function(exports){
// 添加输入框,覆盖在文字上方
elemMain.append('
');
// 获取焦点
- elemMain.children('.layui-tree-editInput').val(text).focus();
+ elemMain.children('.layui-tree-editInput').val(util.unescape(text)).focus();
// 嵌入文字移除输入框
var getVal = function(input){
- var textNew = input.val().trim();
+ var textNew = util.escape(input.val().trim());
textNew = textNew ? textNew : options.text.defaultNodeName;
input.remove();
elemMain.children('.'+ ELEM_TEXT).html(textNew);
// 同步数据
- returnObj.data.title = textNew;
+ returnObj.data[customName.title] = textNew;
// 节点修改的回调
options.operate && options.operate(returnObj);
@@ -555,7 +576,7 @@ layui.define('form', function(exports){
// 删除
} else {
- layer.confirm('确认删除该节点 "
'+ (item.title || '') +' " 吗?', function(index){
+ layer.confirm('确认删除该节点 "
'+ (item[customName.title] || '') +' " 吗?', function(index){
options.operate && options.operate(returnObj); // 节点删除的回调
returnObj.status = 'remove'; // 标注节点删除
@@ -742,6 +763,7 @@ layui.define('form', function(exports){
Class.prototype.getChecked = function(){
var that = this;
var options = that.config;
+ var customName = options.customName;
var checkId = [];
var checkData = [];
@@ -754,16 +776,17 @@ layui.define('form', function(exports){
var eachNodes = function(data, checkNode){
layui.each(data, function(index, item){
layui.each(checkId, function(index2, item2){
- if(item.id == item2){
- item['checked'] = true;
+ if(item[customName.id] == item2){
+ that.updateFieldValue(item, 'checked', true);
+
var cloneItem = $.extend({}, item);
- delete cloneItem.children;
+ delete cloneItem[customName.children];
checkNode.push(cloneItem);
- if(item.children){
- cloneItem.children = [];
- eachNodes(item.children, cloneItem.children);
+ if(item[customName.children]){
+ cloneItem[customName.children] = [];
+ eachNodes(item[customName.children], cloneItem[customName.children]);
}
return true
}
@@ -839,4 +862,4 @@ layui.define('form', function(exports){
};
exports(MOD_NAME, tree);
-})
\ No newline at end of file
+})
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/treetable.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/treetable.js
index 265833c..7f16eac 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/modules/treetable.js
+++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/treetable.js
@@ -47,7 +47,11 @@ layui.define(['table'], function (exports) {
}
}
- // 获取当前实例
+ /**
+ * 获取当前实例
+ * @param {string} id 表格id
+ * @returns {Class}
+ */
var getThisTable = function (id) {
var that = thisTreeTable.that[id];
if (!that) hint.error(id ? ('The treeTable instance with ID \'' + id + '\' not found') : 'ID argument required');
@@ -56,6 +60,7 @@ layui.define(['table'], function (exports) {
// 字符
var MOD_NAME = 'treeTable';
+ var MOD_ID = 'lay-table-id';
var HIDE = 'layui-hide';
var ELEM_VIEW = '.layui-table-view';
@@ -78,8 +83,14 @@ layui.define(['table'], function (exports) {
var LAY_EXPAND = 'LAY_EXPAND';
var LAY_HAS_EXPANDED = 'LAY_HAS_EXPANDED';
var LAY_ASYNC_STATUS = 'LAY_ASYNC_STATUS';
+ var LAY_CASCADE = ['all', 'parent', 'children', 'none'];
+ var HTML_TAG_RE = /<[^>]+?>/;
+ var ICON_PROPS = ['flexIconClose', 'flexIconOpen', 'iconClose', 'iconOpen', 'iconLeaf', 'icon']
- // 构造器
+ /**
+ * 构造器
+ * @class
+ */
var Class = function (options) {
var that = this;
that.index = ++treeTable.index;
@@ -92,9 +103,9 @@ layui.define(['table'], function (exports) {
var updateCache = function (id, childrenKey, data) {
var tableCache = table.cache[id];
layui.each(data || tableCache, function (index, item) {
- var itemDataIndex = item[LAY_DATA_INDEX];
+ var itemDataIndex = item[LAY_DATA_INDEX] || '';
if (itemDataIndex.indexOf('-') !== -1) {
- tableCache[itemDataIndex] = item
+ tableCache[itemDataIndex] = item;
}
item[childrenKey] && updateCache(id, childrenKey, item[childrenKey]);
})
@@ -126,6 +137,14 @@ layui.define(['table'], function (exports) {
var parseData = options.parseData;
var done = options.done;
+ // treeTable重载数据时,会先加载显示顶层节点,然后根据重载数据前的子节点展开状态,展开相应的子节点,
+ // 那么如果重载数据前有滚动条滚动在某个位子,重新加载时顶层节点如果比较少,只显示顶层节点时没有滚动条的情况下,
+ // 自动展开子节点后,滚动条就会显示在顶部,无法保持在重载数据之前的位置。
+ // 处理保持滚动条的问题,重载数据前记录滚动条的位置
+ if(reload === 'reloadData' && thatOptionsTemp.scrollPos === 'fixed'){
+ that.scrollTopCache = that.config.elem.next().find(ELEM_BODY).scrollTop();
+ }
+
if (thatOptionsTemp.url) {
// 异步加载的时候需要处理parseData进行转换
if (!reload || (reload && parseData && !parseData.mod)) {
@@ -157,19 +176,25 @@ layui.define(['table'], function (exports) {
options.parseData.mod = true
}
} else {
- options.data = options.data || [];
- // 处理 isSimpleData
- if (treeOptions.data.isSimpleData) {
- options.data = that.flatToTree(options.data);
+ if(options.data !== undefined){
+ options.data = options.data || [];
+ // 处理 isSimpleData
+ if (treeOptions.data.isSimpleData) {
+ options.data = that.flatToTree(options.data);
+ }
+ that.initData(options.data);
}
- that.initData(options.data);
}
if (!reload || (reload && done && !done.mod)) {
options.done = function () {
var args = arguments;
var doneThat = this;
- var isRenderData = args[3]; // 是否是 renderData
+ // undefined: 初始 render 或 reload,两者本质没有区别可以不做区分
+ // 'reloadData': 重载数据
+ // 'renderData': 重新渲染数据
+ var renderType = args[3];
+ var isRenderData = renderType === 'renderData';
if (!isRenderData) {
delete that.isExpandAll;
}
@@ -189,20 +214,41 @@ layui.define(['table'], function (exports) {
indeterminate: !checkStatus.isAll && checkStatus.data.length
})
}
+ if (!isRenderData && thatOptionsTemp.autoSort && thatOptionsTemp.initSort && thatOptionsTemp.initSort.type) {
+ treeTable.sort(id);
+ }
that.renderTreeTable(tableView);
+ // 恢复滚动条位置
+ if(renderType === 'reloadData' && doneThat.scrollPos === 'fixed'){
+ tableView.find(ELEM_BODY).scrollTop(that.scrollTopCache);
+ }
+
if (layui.type(done) === 'function') {
return done.apply(doneThat, args);
}
}
options.done.mod = true;
}
+
+ // 处理图标
+ if(options && options.tree && options.tree.view){
+ layui.each(ICON_PROPS, function(i, iconProp){
+ if(options.tree.view[iconProp] !== undefined){
+ options.tree.view[iconProp] = that.normalizedIcon(options.tree.view[iconProp]);
+ }
+ })
+ }
}
Class.prototype.init = function () {
var that = this;
var options = that.config;
+ var cascade = options.tree.data.cascade;
+ if (LAY_CASCADE.indexOf(cascade) === -1) {
+ options.tree.data.cascade = 'all'; // 超出范围的都重置为全联动
+ }
// 先初始一个空的表格以便拿到对应的表格实例信息
var tableIns = table.render($.extend({}, options, {
@@ -243,7 +289,8 @@ layui.define(['table'], function (exports) {
},
data: {
isSimpleData: false, // 是否简单数据模式
- rootPid: null // 根节点的父 ID 值
+ rootPid: null, // 根节点的父 ID 值
+ cascade: 'all' // 级联方式 默认全部级联:all 可选 级联父 parent 级联子 children
},
async: {
enable: false, // 是否开启异步加载模式,只有开启的时候其他参数才起作用
@@ -261,6 +308,12 @@ layui.define(['table'], function (exports) {
},
};
+ Class.prototype.normalizedIcon = function(iconStr){
+ return iconStr
+ ? HTML_TAG_RE.test(iconStr) ? iconStr : '
'
+ : ''
+ }
+
Class.prototype.getOptions = function () {
var that = this;
if (that.tableIns) {
@@ -274,27 +327,40 @@ layui.define(['table'], function (exports) {
idKey = idKey || 'id';
pIdKey = pIdKey || 'parentId';
childrenKey = childrenKey || 'children';
- // 创建一个空的 nodes 对象,用于保存所有的节点
- var nodes = {};
- // 遍历所有节点,将其加入 nodes 对象中
+ // 创建一个空的 map 对象,用于保存所有的节点
+ var map = {};
+ var rootNodes = [];
+
var idTemp = '';
- layui.each(flatArr, function (index, item) {
- idTemp = idKey + item[idKey];
- nodes[idTemp] = $.extend({}, item);
- nodes[idTemp][childrenKey] = [];
- })
- // 遍历所有节点,将其父子关系加入 nodes 对象
var pidTemp = '';
- layui.each(nodes, function (index, item) {
+ layui.each(flatArr, function(index, item){
+ idTemp = idKey + item[idKey];
pidTemp = idKey + item[pIdKey];
- if (pidTemp && nodes[pidTemp]) {
- nodes[pidTemp][childrenKey].push(item);
+
+ // 将节点存入 map 对象
+ if(!map[idTemp]){
+ map[idTemp] = {};
+ map[idTemp][childrenKey] = [];
}
- })
- // 返回顶层节点
- return Object.values(nodes).filter(function (item) {
- return rootPid ? item[pIdKey] === rootPid : !item[pIdKey];
- })
+
+ // 合并节点
+ var tempObj = {};
+ tempObj[childrenKey] = map[idTemp][childrenKey];
+ map[idTemp] = $.extend({}, item, tempObj);
+
+ var isRootNode = (rootPid ? map[idTemp][pIdKey] === rootPid : !map[idTemp][pIdKey]);
+ if(isRootNode){
+ rootNodes.push(map[idTemp]);
+ }else{
+ if(!map[pidTemp]){
+ map[pidTemp] = {};
+ map[pidTemp][childrenKey] = [];
+ }
+ map[pidTemp][childrenKey].push(map[idTemp]);
+ }
+ });
+
+ return rootNodes;
}
Class.prototype.flatToTree = function (tableData) {
@@ -321,7 +387,6 @@ layui.define(['table'], function (exports) {
layui.each(tableData, function (i1, item1) {
var dataIndex = (parentIndex ? parentIndex + '-' : '') + i1;
var dataNew = $.extend({}, item1);
- dataNew[childrenKey] = null;
dataNew[pIdKey] = item1[pIdKey] || parentId;
flat.push(dataNew);
flat = flat.concat(that.treeToFlat(item1[childrenKey], item1[customName.id], dataIndex));
@@ -341,16 +406,14 @@ layui.define(['table'], function (exports) {
var tableId = options.id;
var customName = treeOptions.customName;
- var treeNode = {
+ // 带上一些常用的方法
+ return {
data: data,
dataIndex: data[LAY_DATA_INDEX],
getParentNode: function () {
return that.getNodeByIndex(data[LAY_PARENT_INDEX])
},
- }
- // 带上一些常用的方法
-
- return treeNode;
+ };
}
// 通过 index 返回节点信息
@@ -415,45 +478,48 @@ layui.define(['table'], function (exports) {
return;
}
- // 用index
+ // 用 index
return that.getNodeByIndex(dataIndex);
}
- // 通过index获取节点数据
+ // 通过 index 获取节点数据
Class.prototype.getNodeDataByIndex = function (index, clone, newValue) {
var that = this;
var options = that.getOptions();
var treeOptions = options.tree;
var tableId = options.id;
+ var tableCache = table.cache[tableId];
- var dataCache = table.cache[tableId][index];
+ // 获取当前行中的数据
+ var dataCache = tableCache[index];
+
+ // 若非删除操作,则返回合并后的数据
if (newValue !== 'delete' && dataCache) {
$.extend(dataCache, newValue);
return clone ? $.extend({}, dataCache) : dataCache;
}
- var tableData = that.getTableData();
- index += '';
- var indexArr = index.split('-');
+ // 删除操作
+ var dataRet = tableCache;
+ var indexArr = String(index).split('-');
- var dataRet = tableData;
- var tableCache = (options.url || indexArr.length > 1) ? null : table.cache[tableId]; // 只有在删除根节点的时候才需要处理
+ // if (options.url || indexArr.length > 1) tableCache = null // 只有在删除根节点的时候才需要处理
+
+ // 根据 index 进行数据处理
for (var i = 0, childrenKey = treeOptions.customName.children; i < indexArr.length; i++) {
if (newValue && i === indexArr.length - 1) {
- if (newValue === 'delete') {
- // 删除
- if (tableCache) {
- // 同步cache
+ if (newValue === 'delete') { // 删除并返回当前数据
+ // 同步 cache --- 此段代码注释缘由:data 属性模式造成数据重复执行 splice (@Gitee: #I7Z0A/I82E2S)
+ /*if (tableCache) {
layui.each(tableCache, function (i1, item1) {
if (item1[LAY_DATA_INDEX] === index) {
tableCache.splice(i1, 1);
return true;
}
})
- }
+ }*/
return (i ? dataRet[childrenKey] : dataRet).splice(indexArr[i], 1)[0];
- } else {
- // 更新值
+ } else { // 更新值
$.extend((i ? dataRet[childrenKey] : dataRet)[indexArr[i]], newValue);
}
}
@@ -492,15 +558,19 @@ layui.define(['table'], function (exports) {
var isParentKey = customName.isParent;
var childrenKey = customName.children;
- layui.each(data, function (i1, item1) {
- if (!(isParentKey in item1)) {
- item1[isParentKey] = !!(item1[childrenKey] && item1[childrenKey].length);
- }
- item1[LAY_DATA_INDEX_HISTORY] = item1[LAY_DATA_INDEX];
- item1[LAY_PARENT_INDEX] = parentIndex = parentIndex || '';
- var dataIndex = item1[LAY_DATA_INDEX] = (parentIndex ? parentIndex + '-' : '') + i1;
- that.initData(item1[childrenKey] || [], dataIndex);
- });
+ var update = function(data, parentIndex){
+ layui.each(data, function (i1, item1) {
+ if (!(isParentKey in item1)) {
+ item1[isParentKey] = !!(item1[childrenKey] && item1[childrenKey].length);
+ }
+ item1[LAY_DATA_INDEX_HISTORY] = item1[LAY_DATA_INDEX];
+ item1[LAY_PARENT_INDEX] = parentIndex = parentIndex || '';
+ var dataIndex = item1[LAY_DATA_INDEX] = (parentIndex ? parentIndex + '-' : '') + i1;
+ update(item1[childrenKey] || [], dataIndex);
+ });
+ }
+
+ update(data, parentIndex);
updateCache(tableId, childrenKey, data);
@@ -523,7 +593,7 @@ layui.define(['table'], function (exports) {
// treeNode // 需要展开的节点
var trElem = treeNode.trElem;
var tableViewElem = treeNode.tableViewElem || trElem.closest(ELEM_VIEW);
- var tableId = treeNode.tableId || tableViewElem.attr('lay-id');
+ var tableId = treeNode.tableId || tableViewElem.attr(MOD_ID);
var options = treeNode.options || table.getOptions(tableId);
var dataIndex = treeNode.dataIndex || trElem.attr('lay-data-index'); // 可能出现多层
var treeTableThat = getThisTable(tableId);
@@ -552,14 +622,12 @@ layui.define(['table'], function (exports) {
// 找到表格中的同类节点(需要找到lay-data-index一致的所有行)
var trsElem = tableViewElem.find('tr[lay-data-index="' + dataIndex + '"]');
- // 处理折叠按钮图标
var flexIconElem = trsElem.find('.layui-table-tree-flexIcon');
- flexIconElem.html(trExpand ? treeOptions.view.flexIconOpen : treeOptions.view.flexIconClose)
- trData[isParentKey] && flexIconElem.css('visibility', 'visible');
- // 处理节点图标
- treeOptions.view.showIcon && trsElem
- .find('.layui-table-tree-nodeIcon:not(.layui-table-tree-iconCustom,.layui-table-tree-iconLeaf)')
- .html(trExpand ? treeOptions.view.iconOpen : treeOptions.view.iconClose);
+ treeTableThat.updateNodeIcon({
+ scopeEl: trsElem,
+ isExpand: trExpand,
+ isParent: trData[isParentKey]
+ });
trData[LAY_EXPAND] = trExpand;
var trDataId = trData[customName.id];
trDataId !== undefined && (treeTableThat.status.expand[trDataId] = trExpand);
@@ -572,6 +640,7 @@ layui.define(['table'], function (exports) {
if (trExpand) {
// 展开
if (trExpanded) { // 已经展开过
+ if (!childNodes.length) return ;//异步如果子节点没有数据情况下双点行展开所有已展开的节点问题解决
trsElem.nextAll(childNodes.map(function (value, index, array) {
return 'tr[lay-data-index="' + value[LAY_DATA_INDEX] + '"]'
}).join(',')).removeClass(HIDE);
@@ -598,7 +667,7 @@ layui.define(['table'], function (exports) {
options: options,
}, true);
}
- })
+ });
} else {
var asyncSetting = treeOptions.async || {};
var asyncUrl = asyncSetting.url || options.url;
@@ -701,17 +770,19 @@ layui.define(['table'], function (exports) {
'data-index': childItem[LAY_DATA_INDEX],
'lay-data-index': childItem[LAY_DATA_INDEX],
'data-level': dataLevelNew
- })
+ }).data('index', childItem[LAY_DATA_INDEX]);
+
str2Obj.trs_fixed.eq(childIndex).attr({
'data-index': childItem[LAY_DATA_INDEX],
'lay-data-index': childItem[LAY_DATA_INDEX],
'data-level': dataLevelNew
- })
+ }).data('index', childItem[LAY_DATA_INDEX]);
+
str2Obj.trs_fixed_r.eq(childIndex).attr({
'data-index': childItem[LAY_DATA_INDEX],
'lay-data-index': childItem[LAY_DATA_INDEX],
'data-level': dataLevelNew
- })
+ }).data('index', childItem[LAY_DATA_INDEX]);
})
tableViewElem.find(ELEM_MAIN).find('tbody tr[lay-data-index="' + dataIndex + '"]').after(str2Obj.trs);
@@ -896,7 +967,7 @@ layui.define(['table'], function (exports) {
d[idKey] !== undefined && (that.status.expand[d[idKey]] = true);
}
});
- if (options.initSort && options.initSort.type && (!options.url || options.autoSort)) {
+ if (options.initSort && options.initSort.type && options.autoSort) {
return treeTable.sort(id);
}
var trAll = table.getTrHtml(id, tableDataFlat);
@@ -914,9 +985,9 @@ layui.define(['table'], function (exports) {
'lay-data-index': dataItem[LAY_DATA_INDEX],
'data-level': dataLevel
};
- trAllObj.trs.eq(dataIndex).attr(props)
- trAllObj.trs_fixed.eq(dataIndex).attr(props)
- trAllObj.trs_fixed_r.eq(dataIndex).attr(props)
+ trAllObj.trs.eq(dataIndex).attr(props).data('index', dataItem[LAY_DATA_INDEX]);
+ trAllObj.trs_fixed.eq(dataIndex).attr(props).data('index', dataItem[LAY_DATA_INDEX]);
+ trAllObj.trs_fixed_r.eq(dataIndex).attr(props).data('index', dataItem[LAY_DATA_INDEX]);
})
layui.each(['main', 'fixed-l', 'fixed-r'], function (i, item) {
tableView.find('.layui-table-' + item + ' tbody').html(trAllObj[['trs', 'trs_fixed', 'trs_fixed_r'][i]]);
@@ -927,6 +998,43 @@ layui.define(['table'], function (exports) {
treeTable.resize(id);
}
+ /**
+ * @typedef updateNodeIconOptions
+ * @prop {JQuery} scopeEl - tr 元素
+ * @prop {boolean} isExpand - 是否是展开图标
+ * @prop {boolean} isParent - 是否是父节点图标
+ */
+ /**
+ * 更新节点图标
+ * @param {updateNodeIconOptions} opts
+ */
+ Class.prototype.updateNodeIcon = function(opts){
+ var that = this;
+ var options = that.getOptions();
+ var treeOptions = options.tree || {};
+ var scopeEl = opts.scopeEl;
+ var isExpand = opts.isExpand;
+ var isParent = opts.isParent;
+
+ // 处理折叠按钮图标
+ var flexIconElem = scopeEl.find('.layui-table-tree-flexIcon');
+
+ flexIconElem
+ .css('visibility', isParent || treeOptions.view.showFlexIconIfNotParent ? 'visible' : 'hidden')
+ .html(isExpand ? treeOptions.view.flexIconOpen : treeOptions.view.flexIconClose);
+ // 处理节点图标
+ if(treeOptions.view.showIcon){
+ var nodeIconElem = scopeEl.find('.layui-table-tree-nodeIcon:not(.layui-table-tree-iconCustom)');
+ var nodeIcon = isParent
+ ? (isExpand ? treeOptions.view.iconOpen : treeOptions.view.iconClose)
+ : treeOptions.view.iconLeaf;
+
+ nodeIconElem
+ .toggleClass('layui-table-tree-iconLeaf', !isParent)
+ .html(nodeIcon);
+ }
+ }
+
Class.prototype.renderTreeTable = function (tableView, level, sonSign) {
var that = this;
var options = that.getOptions();
@@ -995,7 +1103,7 @@ layui.define(['table'], function (exports) {
((trData[customName.icon] || treeOptionsView.icon) ? ' layui-table-tree-iconCustom' : '') +
(trData[isParentKey] ? '' : ' layui-table-tree-iconLeaf') +
'">' +
- (trData[customName.icon] || treeOptionsView.icon ||
+ (that.normalizedIcon(trData[customName.icon]) || treeOptionsView.icon ||
(trData[isParentKey] ?
(trData[LAY_EXPAND] ? treeOptionsView.iconOpen : treeOptionsView.iconClose) :
treeOptionsView.iconLeaf) ||
@@ -1023,10 +1131,14 @@ layui.define(['table'], function (exports) {
trDefaultExpand.find('.layui-table-tree-flexIcon').html(treeOptionsView.flexIconOpen);
expandNode({trElem: trDefaultExpand.first()}, true);
});
+ // #1463 expandNode 中已经展开过的节点不会重新渲染
+ debounceFn('renderTreeTable2-' + tableId, function () {
+ form.render($('.layui-table-tree[' + MOD_ID + '="' + tableId + '"]'));
+ }, 0)();
} else {
debounceFn('renderTreeTable-' + tableId, function () {
options.hasNumberCol && formatNumber(that);
- form.render($('.layui-table-tree[lay-id="' + tableId + '"]'));
+ form.render($('.layui-table-tree[' + MOD_ID + '="' + tableId + '"]'));
}, 0)();
}
}
@@ -1040,6 +1152,7 @@ layui.define(['table'], function (exports) {
var trFixedL = tableViewElem.find('.layui-table-fixed-l tbody tr');
var trFixedR = tableViewElem.find('.layui-table-fixed-r tbody tr');
layui.each(that.treeToFlat(table.cache[options.id]), function (i1, item1) {
+ if (item1['LAY_HIDE']) return;
var itemData = that.getNodeDataByIndex(item1[LAY_DATA_INDEX]);
itemData['LAY_NUM'] = ++num;
trMain.eq(i1).find('.laytable-cell-numbers').html(num);
@@ -1085,7 +1198,7 @@ layui.define(['table'], function (exports) {
return treeTable.reload.apply(null, args);
};
- var updateStatus = function (data, statusObj, childrenKey) {
+ var updateStatus = function (data, statusObj, childrenKey, notCascade) {
var dataUpdated = [];
layui.each(data, function (i1, item1) {
if (layui.type(statusObj) === 'function') {
@@ -1094,24 +1207,25 @@ layui.define(['table'], function (exports) {
$.extend(item1, statusObj);
}
dataUpdated.push($.extend({}, item1));
- dataUpdated = dataUpdated.concat(updateStatus(item1[childrenKey], statusObj, childrenKey));
+ notCascade || (dataUpdated = dataUpdated.concat(updateStatus(item1[childrenKey], statusObj, childrenKey, notCascade)));
});
return dataUpdated;
}
- Class.prototype.updateStatus = function (data, statusObj) {
+ Class.prototype.updateStatus = function (data, statusObj, notCascade) {
var that = this;
var options = that.getOptions();
var treeOptions = options.tree;
data = data || table.cache[options.id];
- return updateStatus(data, statusObj, treeOptions.customName.children);
+ return updateStatus(data, statusObj, treeOptions.customName.children, notCascade);
}
Class.prototype.getTableData = function () {
var that = this;
var options = that.getOptions();
- return options.url ? table.cache[options.id] : options.data;
+ // return options.url ? table.cache[options.id] : options.data;
+ return table.cache[options.id];
}
treeTable.updateStatus = function (id, statusObj, data) {
@@ -1132,8 +1246,32 @@ layui.define(['table'], function (exports) {
if(!that) return;
var options = that.getOptions();
- if (!options.url || options.autoSort) {
- that.initData();
+ var treeOptions = options.tree;
+
+ var tableData = treeTable.getData(id);
+ var customName = treeOptions.customName;
+ var childrenKey = customName.children;
+
+ // 只和同级节点排序
+ var sort = function(data, field, type){
+ layui.sort(data, field, type, true);
+ layui.each(data, function(rowIndex, trData){
+ sort(trData[childrenKey] || [], field, type);
+ })
+ }
+
+ if (options.autoSort) {
+ var initSort = options.initSort;
+ if (initSort.type) {
+ sort(tableData, initSort.field, initSort.type === 'desc');
+ } else {
+ // 恢复默认
+ sort(tableData, table.config.indexName, null);
+ }
+ // 更新缓存中数据的顺序
+ table.cache[id] = tableData;
+ // 重新初始化缓存数据
+ that.initData(tableData);
treeTable.renderData(id);
}
}
@@ -1198,47 +1336,90 @@ layui.define(['table'], function (exports) {
'data-index': trIndex,
'lay-data-index': index,
'data-level': trLevel
- }));
+ }).data('index', trIndex));
});
that.renderTreeTable(tableView.find('tr[lay-data-index="' + index + '"]'), trLevel);
}
// 删除数据
- treeTable.removeNode = function (id, node) {
+ // _keepParent 暂时为私有参数,仅供内部使用
+ treeTable.removeNode = function (id, node, _keepParent) {
var that = getThisTable(id);
if(!that) return;
var options = that.getOptions();
var treeOptions = options.tree;
+ var isParentKey = treeOptions.customName.isParent;
+ var childrenKey = treeOptions.customName.children;
var tableView = options.elem.next();
var delNode;
var indexArr = [];
+ var tableCache = table.cache[id];
delNode = that.getNodeDataByIndex(layui.type(node) === 'string' ? node : node[LAY_DATA_INDEX], false, 'delete');
var nodeP = that.getNodeDataByIndex(delNode[LAY_PARENT_INDEX]);
that.updateCheckStatus(nodeP);
var delNodesFlat = that.treeToFlat([delNode], delNode[treeOptions.customName.pid], delNode[LAY_PARENT_INDEX]);
- layui.each(delNodesFlat, function (i2, item2) {
- indexArr.push('tr[lay-data-index="' + item2[LAY_DATA_INDEX] + '"]');
+ layui.each(delNodesFlat, function (i2, delNode) {
+ var delNodeDataIndex = delNode[LAY_DATA_INDEX];
+ indexArr.push('tr[lay-data-index="' + delNodeDataIndex + '"]');
+ // 删除临时 key
+ if(delNodeDataIndex.indexOf('-') !== -1){
+ delete tableCache[delNodeDataIndex];
+ }
})
tableView.find(indexArr.join(',')).remove(); // 删除行
+
+ var deleteCacheKey = function(){
+ for (var key in tableCache) {
+ // 根节点 getNodeDataByIndex 内部已处理
+ if(key.indexOf('-') !== -1){
+ // L93 updateCache() 中,cacheKey 取自 rowData 中的 LAY_DATA_INDEX,
+ // 两者不同说明当前 cacheKey 引用的 rowData 已被更新
+ if(key !== tableCache[key][LAY_DATA_INDEX]){
+ delete tableCache[key]
+ }
+ }
+ }
+ }
+
// 重新整理数据
var tableData = that.initData();
+ deleteCacheKey();
// index发生变化需要更新页面tr中对应的lay-data-index 新增和删除都要注意数据结构变动之后的index问题
layui.each(that.treeToFlat(tableData), function (i3, item3) {
if (item3[LAY_DATA_INDEX_HISTORY] && item3[LAY_DATA_INDEX_HISTORY] !== item3[LAY_DATA_INDEX]) {
tableView.find('tr[lay-data-index="' + item3[LAY_DATA_INDEX_HISTORY] + '"]').attr({
'data-index': item3[LAY_DATA_INDEX],
'lay-data-index': item3[LAY_DATA_INDEX],
- });
+ }).data('index', item3[LAY_DATA_INDEX]);
// item3[LAY_DATA_INDEX_HISTORY] = item3[LAY_DATA_INDEX]
}
});
// 重新更新顶层节点的data-index;
- layui.each(table.cache[id], function (i4, item4) {
- tableView.find('tr[data-level="0"][lay-data-index="' + item4[LAY_DATA_INDEX] + '"]').attr('data-index', i4);
+ layui.each(tableCache, function (i4, item4) {
+ tableView.find('tr[data-level="0"][lay-data-index="' + item4[LAY_DATA_INDEX] + '"]')
+ .attr('data-index', i4)
+ .data('index', i4);
})
options.hasNumberCol && formatNumber(that);
+ // 更新父节点状态
+ if(nodeP){
+ var trEl = tableView.find('tr[lay-data-index="' + nodeP[LAY_DATA_INDEX] + '"]');
+
+ if(!_keepParent){
+ nodeP[isParentKey] = !!(nodeP[childrenKey] && nodeP[childrenKey].length);
+ }
+
+ that.updateNodeIcon({
+ scopeEl: trEl,
+ isExpand: nodeP[LAY_EXPAND],
+ isParent: nodeP[isParentKey],
+ });
+ }
+
+ // 重新适配尺寸
+ treeTable.resize(id);
}
/**
@@ -1258,6 +1439,7 @@ layui.define(['table'], function (exports) {
var options = that.getOptions();
var treeOptions = options.tree;
var tableViewElem = options.elem.next();
+ var checkName = table.config.checkName;
opts = opts || {};
@@ -1273,6 +1455,13 @@ layui.define(['table'], function (exports) {
// 添加数据
newNodes = $.extend(true, [], (layui.isArray(newNodes) ? newNodes : [newNodes]));
+ // 若未传入 LAY_CHECKED 属性,则继承父节点的 checked 状态
+ layui.each(newNodes, function(i, item){
+ if(!(checkName in item) && parentNode){
+ item[checkName] = parentNode[checkName];
+ }
+ })
+
var tableData = that.getTableData(), dataAfter;
if (!parentNode) {
// 添加到根节点
@@ -1309,9 +1498,9 @@ layui.define(['table'], function (exports) {
'lay-data-index': newNodeItem[LAY_DATA_INDEX],
'data-level': '0'
};
- newNodesHtmlObj.trs.eq(newNodeIndex).attr(attrs)
- newNodesHtmlObj.trs_fixed.eq(newNodeIndex).attr(attrs)
- newNodesHtmlObj.trs_fixed_r.eq(newNodeIndex).attr(attrs)
+ newNodesHtmlObj.trs.eq(newNodeIndex).attr(attrs).data('index', newNodeItem[LAY_DATA_INDEX]);
+ newNodesHtmlObj.trs_fixed.eq(newNodeIndex).attr(attrs).data('index', newNodeItem[LAY_DATA_INDEX]);
+ newNodesHtmlObj.trs_fixed_r.eq(newNodeIndex).attr(attrs).data('index', newNodeItem[LAY_DATA_INDEX]);
})
var trIndexPrev = parseInt(newNodes[0][LAY_DATA_INDEX]) - 1;
var tableViewElemMAIN = tableViewElem.find(ELEM_MAIN);
@@ -1319,9 +1508,16 @@ layui.define(['table'], function (exports) {
var tableViewElemFIXR = tableViewElem.find(ELEM_FIXR);
if (trIndexPrev === -1) {
// 插入到开头
- tableViewElemMAIN.find('tr[data-level="0"][data-index="0"]').before(newNodesHtmlObj.trs);
- tableViewElemFIXL.find('tr[data-level="0"][data-index="0"]').before(newNodesHtmlObj.trs_fixed);
- tableViewElemFIXR.find('tr[data-level="0"][data-index="0"]').before(newNodesHtmlObj.trs_fixed_r);
+ var hasTr = tableViewElemMAIN.find('tr[data-level="0"][data-index="0"]')[0];
+ if(hasTr){
+ tableViewElemMAIN.find('tr[data-level="0"][data-index="0"]').before(newNodesHtmlObj.trs);
+ tableViewElemFIXL.find('tr[data-level="0"][data-index="0"]').before(newNodesHtmlObj.trs_fixed);
+ tableViewElemFIXR.find('tr[data-level="0"][data-index="0"]').before(newNodesHtmlObj.trs_fixed_r);
+ }else{
+ tableViewElemMAIN.find('tbody').prepend(newNodesHtmlObj.trs);
+ tableViewElemFIXL.find('tbody').prepend(newNodesHtmlObj.trs_fixed);
+ tableViewElemFIXR.find('tbody').prepend(newNodesHtmlObj.trs_fixed_r);
+ }
} else {
if (index === -1) {
// 追加到最后
@@ -1339,7 +1535,9 @@ layui.define(['table'], function (exports) {
// 重新更新顶层节点的data-index;
layui.each(table.cache[id], function (i4, item4) {
- tableViewElem.find('tr[data-level="0"][lay-data-index="' + item4[LAY_DATA_INDEX] + '"]').attr('data-index', i4);
+ tableViewElem.find('tr[data-level="0"][lay-data-index="' + item4[LAY_DATA_INDEX] + '"]')
+ .attr('data-index', i4)
+ .data('index', i4);
})
that.renderTreeTable(tableViewElem.find(newNodes.map(function (value, index, array) {
@@ -1375,11 +1573,21 @@ layui.define(['table'], function (exports) {
expandNode({trElem: tableViewElem.find('tr[lay-data-index="' + parentIndex + '"]')}, true)
}
that.updateCheckStatus(parentNode);
+ // 更新父节点图标状态
+ if(parentNode){
+ var trEl = tableViewElem.find('tr[lay-data-index="' + parentNode[LAY_DATA_INDEX] + '"]');
+ that.updateNodeIcon({
+ scopeEl: trEl,
+ isExpand: parentNode[LAY_EXPAND],
+ isParent: parentNode[isParentKey],
+ });
+ }
treeTable.resize(id);
if (focus) {
// 滚动到第一个新增的节点
tableViewElem.find(ELEM_MAIN).find('tr[lay-data-index="' + newNodes[0][LAY_DATA_INDEX] + '"]').get(0).scrollIntoViewIfNeeded();
}
+
return newNodes;
}
@@ -1387,6 +1595,8 @@ layui.define(['table'], function (exports) {
treeTable.checkStatus = function (id, includeHalfCheck) {
var that = getThisTable(id);
if (!that) return;
+ var options = that.getOptions();
+ var treeOptions = options.tree;
var checkName = table.config.checkName;
// 需要区分单双选
@@ -1396,7 +1606,7 @@ layui.define(['table'], function (exports) {
});
var isAll = true;
- layui.each(table.cache[id], function (i1, item1) {
+ layui.each(treeOptions.data.cascade === 'all' ? table.cache[id] : treeTable.getData(id, true), function (i1, item1) {
if (!item1[checkName]) {
isAll = false;
return true;
@@ -1498,25 +1708,49 @@ layui.define(['table'], function (exports) {
}
})
+ // 设置或取消行选中样式
+ Class.prototype.setRowCheckedClass = function(tr, checked){
+ var that = this;
+ var options = that.getOptions();
+
+ var index = tr.data('index');
+ var tableViewElem = options.elem.next();
+
+ tr[checked ? 'addClass' : 'removeClass'](ELEM_CHECKED); // 主体行
+
+ // 右侧固定行
+ tr.each(function(){
+ var index = $(this).data('index');
+ var trFixedR = tableViewElem.find('.layui-table-fixed-r tbody tr[data-index="'+ index +'"]');
+ trFixedR[checked ? 'addClass' : 'removeClass'](ELEM_CHECKED);
+ });
+ };
+
// 更新表格的复选框状态
Class.prototype.updateCheckStatus = function (dataP, checked) {
var that = this;
var options = that.getOptions();
+ if (!options.hasChecboxCol) {
+ return false; // 如果没有复选列则不需要更新状态
+ }
var treeOptions = options.tree;
var tableId = options.id;
var tableView = options.elem.next();
var checkName = table.config.checkName;
+ var cascade = treeOptions.data.cascade;
+ var isCascadeParent = cascade === 'all' || cascade === 'parent';
+
// 如有必要更新父节点们的状态
- if (dataP) {
+ if (isCascadeParent && dataP) {
var trsP = that.updateParentCheckStatus(dataP, layui.type(checked) === 'boolean' ? checked : null);
layui.each(trsP, function (indexP, itemP) {
var checkboxElem = tableView.find('tr[lay-data-index="' + itemP[LAY_DATA_INDEX] + '"] input[name="layTableCheckbox"]:not(:disabled)');
var checked = itemP[checkName];
- // 标记父节点行背景色
- checkboxElem.closest('tr')[checked ? 'addClass' : 'removeClass'](ELEM_CHECKED);
+ // 标记父节点行背景色
+ that.setRowCheckedClass(checkboxElem.closest('tr'), checked);
// 设置原始复选框 checked 属性值并渲染
form.render(checkboxElem.prop({
@@ -1529,14 +1763,27 @@ layui.define(['table'], function (exports) {
// 更新全选的状态
var isAll = true;
var isIndeterminate = false;
- layui.each(table.cache[tableId], function (i1, item1) {
- if (item1[checkName] || item1[LAY_CHECKBOX_HALF]) {
- isIndeterminate = true;
- }
- if (!item1[checkName]) {
- isAll = false;
- }
- })
+ var data = treeOptions.data.cascade === 'all' ? table.cache[tableId] : treeTable.getData(tableId, true);
+ data = data.filter(function (item) {
+ return !item[options.disabledName];
+ });
+
+ if(data.length > 0){
+ layui.each(data, function (i1, item1) {
+ if (item1[checkName] || item1[LAY_CHECKBOX_HALF]) {
+ isIndeterminate = true;
+ }
+ if (!item1[checkName]) {
+ isAll = false;
+ }
+ if (isIndeterminate && !isAll) {
+ return true;
+ }
+ })
+ }else{
+ isAll = false;
+ }
+
isIndeterminate = isIndeterminate && !isAll;
form.render(tableView.find('input[name="layTableCheckbox"][lay-filter="layTableAllChoose"]').prop({
'checked': isAll,
@@ -1601,6 +1848,7 @@ layui.define(['table'], function (exports) {
var checkNode = function (trElem, checked, callbackFlag) {
var that = this;
var options = that.getOptions();
+ var treeOptions = options.tree;
var tableId = options.id;
var tableView = options.elem.next();
var inputElem = (trElem.length ? trElem : tableView).find('.laytable-cell-radio, .laytable-cell-checkbox').children('input').last();
@@ -1649,20 +1897,22 @@ layui.define(['table'], function (exports) {
if (d[checkName]) {
var radioElem = tableView.find('tr[lay-data-index="' + d[LAY_DATA_INDEX] + '"] input[type="radio"][lay-type="layTableRadio"]');
d[checkName] = false;
- radioElem.closest('tr').removeClass(ELEM_CHECKED); // 取消当前选中行背景色
+
+ // 取消当前选中行背景色
+ that.setRowCheckedClass(radioElem.closest('tr'), false);
form.render(radioElem.prop('checked', false));
}
}); // 取消其他的选中状态
trData[checkName] = checked;
- trElem[checked ? 'addClass' : 'removeClass'](ELEM_CHECKED); // 标记当前选中行背景色
- trElem.siblings().removeClass(ELEM_CHECKED); // 取消其他行背景色
+
+ that.setRowCheckedClass(trElem, checked); // 标记当前选中行背景色
+ that.setRowCheckedClass(trElem.siblings(), false); // 取消其他行背景色
+
form.render(trElem.find('input[type="radio"][lay-type="layTableRadio"]').prop('checked', checked));
} else {
- var isParentKey = options.tree.customName.isParent;
// 切换只能用到单条,全选到这一步的时候应该是一个确定的状态
checked = layui.type(checked) === 'boolean' ? checked : !trData[checkName]; // 状态切换,如果遇到不可操作的节点待处理 todo
// 全选或者是一个父节点,将子节点的状态同步为当前节点的状态
- // if (!trData || trData[isParentKey]) {
// 处理不可操作的信息
var checkedStatusFn = function (d) {
if (!d[table.config.disabledName]) { // 节点不可操作的不处理
@@ -1671,14 +1921,16 @@ layui.define(['table'], function (exports) {
}
}
- var trs = that.updateStatus(trData ? [trData] : table.cache[tableId], checkedStatusFn);
+ var trs = that.updateStatus(trData ? [trData] : table.cache[tableId], checkedStatusFn, trData && ['parent', 'none'].indexOf(treeOptions.data.cascade) !== -1);
var checkboxElem = tableView.find(trs.map(function (value) {
return 'tr[lay-data-index="' + value[LAY_DATA_INDEX] + '"] input[name="layTableCheckbox"]:not(:disabled)';
}).join(','));
- checkboxElem.closest('tr')[checked ? 'addClass' : 'removeClass'](ELEM_CHECKED); // 标记当前选中行背景色
+
+ that.setRowCheckedClass(checkboxElem.closest('tr'), checked); // 标记当前选中行背景色
form.render(checkboxElem.prop({checked: checked, indeterminate: false}));
- // }
+
var trDataP;
+
// 更新父节点以及更上层节点的状态
if (trData && trData[LAY_PARENT_INDEX]) {
// 找到父节点,然后判断父节点的子节点是否全部选中
@@ -1732,14 +1984,30 @@ layui.define(['table'], function (exports) {
// 目前只能处理当前页的数据
return;
}
+
+ var collectNeedExpandNodeIndex = function(index){
+ needExpandIndex.push(index);
+ var trElem = tableView.find('tr[lay-data-index="' + index + '"]');
+ if (!trElem.length) {
+ var nodeData = that.getNodeDataByIndex(index);
+ var parentIndex = nodeData[LAY_PARENT_INDEX];
+ parentIndex && collectNeedExpandNodeIndex(parentIndex);
+ }
+ }
+
// 判断是否展开过
var trElem = tableView.find('tr[lay-data-index="' + dataIndex + '"]');
if (!trElem.length) {
+ var parentIndex = nodeData[LAY_PARENT_INDEX];
+ var needExpandIndex = [];
+ collectNeedExpandNodeIndex(parentIndex);
// 如果还没有展开没有渲染的要先渲染出来
- treeTable.expandNode(id, {
- index: nodeData[LAY_PARENT_INDEX],
- expandFlag: true
- });
+ layui.each(needExpandIndex.reverse(),function(index, nodeIndex){
+ treeTable.expandNode(id, {
+ index: nodeIndex,
+ expandFlag: true
+ });
+ })
trElem = tableView.find('tr[lay-data-index="' + dataIndex + '"]');
}
checkNode.call(that, trElem, checked, callbackFlag);
@@ -1797,7 +2065,7 @@ layui.define(['table'], function (exports) {
dataP[LAY_EXPAND] = false;
dataP[LAY_ASYNC_STATUS] = false;
layui.each(that.treeToFlat(dataP[treeOptions.customName.children]).reverse(), function (i1, item1) {
- treeTable.removeNode(id, item1[LAY_DATA_INDEX]);
+ treeTable.removeNode(id, item1[LAY_DATA_INDEX], true);
})
// 重新展开
treeTable.expandNode(id, {
@@ -1855,7 +2123,7 @@ layui.define(['table'], function (exports) {
// 重载
treeTable.reload = function (id, options, deep, type) {
- deep = deep !== false; // 默认采用深拷贝
+ // deep = deep !== false; // 默认采用深拷贝
var that = getThisTable(id);
if (!that) return;
that.reload(options, deep, type);
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/upload.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/upload.js
index 93520c9..9989981 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/modules/upload.js
+++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/upload.js
@@ -3,16 +3,22 @@
* 上传组件
*/
-layui.define(['lay','layer'], function(exports){
+layui.define(['lay', 'layer'], function(exports){
"use strict";
var $ = layui.$;
+ var lay = layui.lay;
var layer = layui.layer;
var device = layui.device();
+ // 模块名
+ var MOD_NAME = 'upload';
+ var MOD_INDEX = 'layui_'+ MOD_NAME +'_index'; // 模块索引名
+
// 外部接口
var upload = {
config: {}, // 全局配置项
+ index: layui[MOD_NAME] ? (layui[MOD_NAME].index + 10000) : 0, // 索引
// 设置全局项
set: function(options){
var that = this;
@@ -26,8 +32,13 @@ layui.define(['lay','layer'], function(exports){
};
// 操作当前实例
- var thisUpload = function(){
+ var thisModule = function(){
var that = this;
+ var options = that.config;
+ var id = options.id;
+
+ thisModule.that[id] = that; // 记录当前实例对象
+
return {
upload: function(files){
that.upload.call(that, files);
@@ -40,7 +51,6 @@ layui.define(['lay','layer'], function(exports){
};
// 字符常量
- var MOD_NAME = 'upload';
var ELEM = 'layui-upload';
var THIS = 'layui-this';
var SHOW = 'layui-show';
@@ -52,10 +62,12 @@ layui.define(['lay','layer'], function(exports){
var ELEM_IFRAME = 'layui-upload-iframe';
var ELEM_CHOOSE = 'layui-upload-choose';
var ELEM_DRAG = 'layui-upload-drag';
+ var UPLOADING = 'UPLOADING';
// 构造器
var Class = function(options){
var that = this;
+ that.index = ++upload.index;
that.config = $.extend({}, that.config, upload.config, options);
that.render();
};
@@ -85,15 +97,51 @@ layui.define(['lay','layer'], function(exports){
"limit-size": null // 限制 size 属性的提示 --- function
}
};
+
+ // 重载实例
+ Class.prototype.reload = function(options){
+ var that = this;
+ that.config = $.extend({}, that.config, options);
+ that.render(true);
+ };
// 初始渲染
- Class.prototype.render = function(options){
+ Class.prototype.render = function(rerender){
var that = this;
var options = that.config;
+ // 若 elem 非唯一
+ var elem = $(options.elem);
+ if (elem.length > 1) {
+ layui.each(elem, function() {
+ upload.render($.extend({}, options, {
+ elem: this
+ }));
+ });
+ return that;
+ }
+
+ // 合并 lay-options 属性上的配置信息
+ $.extend(options, lay.options(elem[0], {
+ attr: elem.attr('lay-data') ? 'lay-data' : null // 兼容旧版的 lay-data 属性
+ }));
+
+ // 若重复执行 render,则视为 reload 处理
+ if (!rerender && elem[0] && elem.data(MOD_INDEX)) {
+ var newThat = thisModule.getThis(elem.data(MOD_INDEX));
+ if(!newThat) return;
+
+ return newThat.reload(options);
+ }
+
options.elem = $(options.elem);
options.bindAction = $(options.bindAction);
+ // 初始化 id 属性 - 优先取 options > 元素 id > 自增索引
+ options.id = 'id' in options ? options.id : (
+ elem.attr('id') || that.index
+ );
+
that.file();
that.events();
};
@@ -218,30 +266,56 @@ layui.define(['lay','layer'], function(exports){
var request = function(sets){
var formData = new FormData();
+ // 恢复文件状态
+ var resetFileState = function(file) {
+ if (sets.unified) {
+ layui.each(items, function(index, file){
+ delete file[UPLOADING];
+ });
+ } else {
+ delete file[UPLOADING];
+ }
+ };
+
// 追加额外的参数
layui.each(options.data, function(key, value){
- value = typeof value === 'function' ? value() : value;
+ value = typeof value === 'function'
+ ? sets.unified ? value() : value(sets.index, sets.file)
+ : value;
formData.append(key, value);
});
- // 添加 file 到表单域
- sets.unified ? layui.each(items, function(index, file){
- formData.append(options.field, file);
- }) : formData.append(options.field, sets.file);
+ /*
+ * 添加 file 到表单域
+ */
+
+ // 是否统一上传
+ if (sets.unified) {
+ layui.each(items, function(index, file){
+ if (file[UPLOADING]) return;
+ file[UPLOADING] = true; // 上传中的标记
+ formData.append(options.field, file);
+ });
+ } else { // 逐一上传
+ if (sets.file[UPLOADING]) return;
+ formData.append(options.field, sets.file);
+ sets.file[UPLOADING] = true; // 上传中的标记
+ }
// ajax 参数
var opts = {
url: options.url,
type: 'post', // 统一采用 post 上传
data: formData,
+ dataType: options.dataType || 'json',
contentType: false,
processData: false,
- dataType: 'json',
headers: options.headers || {},
success: function(res){ // 成功回调
options.unified ? (successful += that.fileLength) : successful++;
done(sets.index, res);
- allDone();
+ allDone(sets.index);
+ resetFileState(sets.file);
},
error: function(e){ // 异常回调
options.unified ? (failed += that.fileLength) : failed++;
@@ -249,10 +323,12 @@ layui.define(['lay','layer'], function(exports){
'Upload failed, please try again.',
'status: '+ (e.status || '') +' - '+ (e.statusText || 'error')
].join('
'));
- error(sets.index);
- allDone();
+ error(sets.index, e.responseText);
+ allDone(sets.index);
+ resetFileState(sets.file);
}
};
+
// 进度条
if(typeof options.progress === 'function'){
opts.xhr = function(){
@@ -310,21 +386,41 @@ layui.define(['lay','layer'], function(exports){
}
}, 30);
};
-
+
+ // 强制返回的数据格式
+ var forceConvert = function(src) {
+ if(options.force === 'json'){
+ if(typeof src !== 'object'){
+ try {
+ return {
+ status: "CONVERTED",
+ data: JSON.parse(src)
+ };
+ } catch(e){
+ that.msg(text['data-format-error']);
+ return {
+ status: "FORMAT_ERROR",
+ data: {}
+ };
+ }
+ }
+ }
+ return { status: "DO_NOTHING", data: {} }
+ }
+
// 统一回调
var done = function(index, res){
that.elemFile.next('.'+ ELEM_CHOOSE).remove();
elemFile.value = '';
- if(options.force === 'json'){
- if(typeof res !== 'object'){
- try {
- res = JSON.parse(res);
- } catch(e){
- res = {};
- return that.msg(text['data-format-error']);
- }
- }
+ var convert = forceConvert(res);
+
+ switch(convert.status) {
+ case "CONVERTED":
+ res = convert.data;
+ break;
+ case "FORMAT_ERROR":
+ return;
}
typeof options.done === 'function' && options.done(res, index || 0, function(files){
@@ -333,13 +429,24 @@ layui.define(['lay','layer'], function(exports){
};
// 统一网络异常回调
- var error = function(index){
+ var error = function(index, res){
if(options.auto){
elemFile.value = '';
}
+
+ var convert = forceConvert(res);
+
+ switch(convert.status) {
+ case "CONVERTED":
+ res = convert.data;
+ break;
+ case "FORMAT_ERROR":
+ return;
+ }
+
typeof options.error === 'function' && options.error(index || 0, function(files){
that.upload(files);
- });
+ }, res);
};
var check;
@@ -377,20 +484,42 @@ layui.define(['lay','layer'], function(exports){
var newFile = new File([file], filename);
that.files = that.files || {};
that.files[index] = newFile;
+ },
+ // 获取本次选取的文件
+ getChooseFiles: function(){
+ return that.chooseFiles;
}
};
// 提交上传
- var send = function(){
- // 上传前的回调 - 如果回调函数明确返回 false,则停止上传
- if(options.before && (options.before(args) === false)) return;
-
- // IE 兼容处理
- if(device.ie){
- return device.ie > 9 ? ajaxSend() : iframeSend();
+ var send = function(){
+ var ready = function(){
+ // IE 兼容处理
+ if(device.ie){
+ return device.ie > 9 ? ajaxSend() : iframeSend();
+ }
+ ajaxSend();
+ }
+ // 上传前的回调 - 如果回调函数明确返回 false 或 Promise.reject,则停止上传
+ if(typeof options.before === 'function'){
+ upload.util.promiseLikeResolve(options.before(args))
+ .then(function(result){
+ if(result !== false){
+ ready();
+ } else {
+ if(options.auto){
+ elemFile.value = '';
+ }
+ }
+ }, function(error){
+ if(options.auto){
+ elemFile.value = '';
+ }
+ error !== undefined && layui.hint().error(error);
+ })
+ }else{
+ ready();
}
-
- ajaxSend();
};
// 文件类型名称
@@ -406,7 +535,8 @@ layui.define(['lay','layer'], function(exports){
? ((elemFile.value.match(/[^\/\\]+\..+/g)||[]) || '')
: value;
- if(value.length === 0) return;
+ // 若文件域值为空
+ if (value.length === 0) return;
// 根据文件类型校验
switch(options.accept){
@@ -433,7 +563,7 @@ layui.define(['lay','layer'], function(exports){
break;
default: // 图片文件
layui.each(value, function(i, item){
- if(!RegExp('.\\.('+ (exts || 'jpg|png|gif|bmp|jpeg|svg') +')$', 'i').test(escape(item))){
+ if(!RegExp('.\\.('+ (exts || 'jpg|png|gif|bmp|jpeg|svg|webp') +')$', 'i').test(escape(item))){
return check = true;
}
});
@@ -493,24 +623,6 @@ layui.define(['lay','layer'], function(exports){
send();
};
- //重置方法
- Class.prototype.reload = function(options){
- options = options || {};
- delete options.elem;
- delete options.bindAction;
-
- var that = this;
- var options = that.config = $.extend({}, that.config, upload.config, options);
- var next = options.elem.next();
-
- //更新文件域相关属性
- next.attr({
- name: options.name,
- accept: options.acceptMime,
- multiple: options.multiple
- });
- };
-
//事件处理
Class.prototype.events = function(){
var that = this;
@@ -541,23 +653,70 @@ layui.define(['lay','layer'], function(exports){
elemFile.after('
'+ value +' ');
};
- // 合并 lay-options/lay-data 属性配置项
- var extendAttrs = function(){
- var othis = $(this);
- var data = othis.attr('lay-data') || othis.attr('lay-options'); // 优先兼容旧版本
+ /**
+ * 判断文件是否加入排队
+ * @param {File} file
+ * @return {boolean}
+ */
+ var checkFile = function (file) {
+ var result = true;
+ layui.each(that.files, function (index, item) {
+ result = !(item.name === file.name);
+ if(!result) return true;
+ });
+ return result;
+ }
- if(data){
- that.config = $.extend({}, options, lay.options(this, {
- attr: othis.attr('lay-data') ? 'lay-data' : null
- }));
+ /**
+ * 扩展文件信息
+ * @template {File | FileList} T
+ * @param {T} obj
+ * @return {T}
+ */
+ var extendInfo = function (obj) {
+
+ var extInfo = function (file) {
+ //文件扩展名
+ file.ext = file.name.substr(file.name.lastIndexOf('.') + 1).toLowerCase();
+ // 文件大小
+ file.sizes = upload.util.parseSize(file.size);
+ // 可以继续扩展
}
- };
+
+ //FileList对象
+ if (obj instanceof FileList) {
+ layui.each(obj, function (index, item) {
+ extInfo(item);
+ });
+ } else {
+ extInfo(obj);
+ }
+
+ return obj;
+ }
+
+ /**
+ * 检查获取文件
+ * @param {FileList} files
+ * @return {Array
|FileList}
+ */
+ var getFiles = function (files) {
+ files = files || [];
+ if (!files.length) return [];
+ if (!that.files) return extendInfo(files);
+ var result = [];
+ layui.each(files, function (index, item) {
+ if (checkFile(item)) {
+ result.push(extendInfo(item));
+ }
+ });
+ return result;
+ }
// 点击上传容器
options.elem.off('upload.start').on('upload.start', function(){
var othis = $(this);
- extendAttrs.call(this);
that.config.item = othis;
that.elemFile[0].click();
});
@@ -574,10 +733,9 @@ layui.define(['lay','layer'], function(exports){
})
.off('upload.drop').on('upload.drop', function(e, param){
var othis = $(this);
- var files = param.originalEvent.dataTransfer.files || [];
+ var files = getFiles(param.originalEvent.dataTransfer.files);
othis.removeAttr('lay-over');
- extendAttrs.call(this);
setChooseFile(files);
options.auto ? that.upload() : setChooseText(files); // 是否自动触发上传
@@ -585,11 +743,13 @@ layui.define(['lay','layer'], function(exports){
}
// 文件选择
- that.elemFile.off('upload.change').on('upload.change', function(){
- var files = this.files || [];
+ that.elemFile.on('change', function(){
+ var files = getFiles(this.files);
+
+ if(files.length === 0) return;
- extendAttrs.call(this);
setChooseFile(files);
+
options.auto ? that.upload() : setChooseText(files); // 是否自动触发上传
});
@@ -597,19 +757,19 @@ layui.define(['lay','layer'], function(exports){
options.bindAction.off('upload.action').on('upload.action', function(){
that.upload();
});
-
+
+
// 防止事件重复绑定
- if(options.elem.data('haveEvents')) return;
-
- that.elemFile.on('change', function(){
- $(this).trigger('upload.change');
- });
-
+ if(options.elem.data(MOD_INDEX)) return;
+
+
+ // 目标元素 click 事件
options.elem.on('click', function(){
if(that.isFile()) return;
$(this).trigger('upload.start');
});
+ // 目标元素 drop 事件
if(options.drag){
options.elem.on('dragover', function(e){
e.preventDefault();
@@ -622,17 +782,67 @@ layui.define(['lay','layer'], function(exports){
});
}
+ // 手动上传时触发上传的元素 click 事件
options.bindAction.on('click', function(){
$(this).trigger('upload.action');
});
- options.elem.data('haveEvents', true);
+ // 绑定元素索引
+ options.elem.data(MOD_INDEX, options.id);
+ };
+
+ /**
+ * 上传组件辅助方法
+ */
+ upload.util = {
+ /**
+ * 文件大小处理
+ * @param {number | string} size -文件大小
+ * @param {number} [precision] - 数值精度
+ * @return {string}
+ */
+ parseSize: function (size, precision) {
+ precision = precision || 2;
+ if (null == size || !size) {
+ return '0';
+ }
+ var unitArr = ["Bytes", "Kb", "Mb", "Gb", "Tb", "Pb", "Eb", "Zb", "Yb"];
+ var index;
+ var formatSize = typeof size === 'string' ? parseFloat(size) : size;
+ index = Math.floor(Math.log(formatSize) / Math.log(1024));
+ size = formatSize / Math.pow(1024, index);
+ size = size % 1 === 0 ? size : parseFloat(size.toFixed(precision));//保留的小数位数
+ return size + unitArr[index];
+ },
+ /**
+ * 将给定的值转换为一个 JQueryDeferred 对象
+ */
+ promiseLikeResolve:function(value){
+ var deferred = $.Deferred();
+
+ if(value && typeof value.then === 'function'){
+ value.then(deferred.resolve, deferred.reject);
+ }else{
+ deferred.resolve(value);
+ }
+ return deferred.promise();
+ }
+ }
+
+ // 记录所有实例
+ thisModule.that = {}; // 记录所有实例对象
+
+ // 获取当前实例对象
+ thisModule.getThis = function(id){
+ var that = thisModule.that[id];
+ if(!that) hint.error(id ? (MOD_NAME +' instance with ID \''+ id +'\' not found') : 'ID argument required');
+ return that;
};
// 核心入口
upload.render = function(options){
var inst = new Class(options);
- return thisUpload.call(inst);
+ return thisModule.call(inst);
};
exports(MOD_NAME, upload);
diff --git a/HT.Cloud.Web/wwwroot/lib/layui/modules/util.js b/HT.Cloud.Web/wwwroot/lib/layui/modules/util.js
index d992f12..cc628ee 100644
--- a/HT.Cloud.Web/wwwroot/lib/layui/modules/util.js
+++ b/HT.Cloud.Web/wwwroot/lib/layui/modules/util.js
@@ -1,13 +1,13 @@
/**
- * util 工具组件
+ * util 工具组件
*/
layui.define('jquery', function(exports){
"use strict";
-
+
var $ = layui.$;
var hint = layui.hint();
-
+
// 外部接口
var util = {
// 固定块
@@ -19,7 +19,7 @@ layui.define('jquery', function(exports){
options = $.extend(true, {
target: 'body', // fixbar 的插入目标选择器
bars: [], // bar 信息
- default: true, // 是否显示默认 bar
+ "default": true, // 是否显示默认 bar
margin: 160, // 出现 top bar 的滚动条高度临界值
duration: 320 // top bar 等动画时长(毫秒)
}, options);
@@ -28,12 +28,12 @@ layui.define('jquery', function(exports){
var $target = $(options.target);
// 滚动条所在元素对象
- var $scroll = options.scroll
- ? $(options.scroll)
+ var $scroll = options.scroll
+ ? $(options.scroll)
: $(options.target === 'body' ? $doc : $target)
// 是否提供默认图标
- if(options.default){
+ if(options['default']){
// 兼容旧版本的一些属性
if(options.bar1){
options.bars.push({
@@ -72,8 +72,8 @@ layui.define('jquery', function(exports){
var type = $(this).attr('lay-type');
if(type === 'top'){
(
- options.target === 'body'
- ? $('html,body')
+ options.target === 'body'
+ ? $('html,body')
: $scroll
).animate({
scrollTop : 0
@@ -130,9 +130,9 @@ layui.define('jquery', function(exports){
timer = setTimeout(function(){
setTopBar();
}, 100);
- });
+ });
},
-
+
// 倒计时
countdown: function(options){
var that = this;
@@ -198,27 +198,27 @@ layui.define('jquery', function(exports){
if(countTime <= 0){
clearTimeout(inst.timer);
typeof options.done === 'function' && options.done(result, inst);
- };
+ }
return fn;
})();
-
+
return inst;
},
-
+
// 某个时间在当前时间的多久前
timeAgo: function(time, onlyDate){
var that = this;
var arr = [[], []];
var stamp = new Date().getTime() - new Date(time).getTime();
-
+
// 返回具体日期
if(stamp > 1000*60*60*24*31){
stamp = new Date(time);
arr[0][0] = that.digit(stamp.getFullYear(), 4);
arr[0][1] = that.digit(stamp.getMonth() + 1);
arr[0][2] = that.digit(stamp.getDate());
-
+
// 是否输出时间
if(!onlyDate){
arr[1][0] = that.digit(stamp.getHours());
@@ -227,7 +227,7 @@ layui.define('jquery', function(exports){
}
return arr[0].join('-') + ' ' + arr[1].join(':');
}
-
+
// 30 天以内,返回「多久前」
if(stamp >= 1000*60*60*24){
return ((stamp/1000/60/60/24)|0) + ' 天前';
@@ -241,7 +241,7 @@ layui.define('jquery', function(exports){
return '刚刚';
}
},
-
+
// 数字前置补零
digit: function(num, length){
var str = '';
@@ -252,39 +252,75 @@ layui.define('jquery', function(exports){
}
return num < Math.pow(10, length) ? str + (num|0) : num;
},
-
+
// 转化为日期格式字符
- toDateString: function(time, format){
- //若 null 或空字符,则返回空字符
+ toDateString: function(time, format, options){
+ // 若 null 或空字符,则返回空字符
if(time === null || time === '') return '';
-
- var that = this
- ,date = new Date(function(){
+
+ // 引用自 dayjs
+ // https://github.com/iamkun/dayjs/blob/v1.11.9/src/constant.js#L30
+ var REGEX_FORMAT = /\[([^\]]+)]|y{1,4}|M{1,2}|d{1,2}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|SSS/g;
+ var that = this;
+ var date = new Date(function(){
if(!time) return;
return isNaN(time) ? time : (typeof time === 'string' ? parseInt(time) : time)
}() || new Date())
- ,ymd = [
- that.digit(date.getFullYear(), 4)
- ,that.digit(date.getMonth() + 1)
- ,that.digit(date.getDate())
- ]
- ,hms = [
- that.digit(date.getHours())
- ,that.digit(date.getMinutes())
- ,that.digit(date.getSeconds())
- ];
-
- if(!date.getDate()) return hint.error('Invalid Msec for "util.toDateString(Msec)"'), '';
-
+
+ if(!date.getDate()) return hint.error('Invalid millisecond for "util.toDateString(millisecond)"'), '';
+
+ var years = date.getFullYear();
+ var month = date.getMonth();
+ var days = date.getDate();
+ var hours = date.getHours();
+ var minutes = date.getMinutes();
+ var seconds = date.getSeconds();
+ var milliseconds = date.getMilliseconds();
+
+ var defaultMeridiem = function(hours, minutes){
+ var hm = hours * 100 + minutes;
+ if (hm < 600) {
+ return '凌晨';
+ } else if (hm < 900) {
+ return '早上';
+ } else if (hm < 1100) {
+ return '上午';
+ } else if (hm < 1300) {
+ return '中午';
+ } else if (hm < 1800) {
+ return '下午';
+ }
+ return '晚上';
+ };
+
+ var meridiem = (options && options.customMeridiem) || defaultMeridiem;
+
+ var matches = {
+ yy: function(){return String(years).slice(-2);},
+ yyyy: function(){return that.digit(years, 4);},
+ M: function(){return String(month + 1);},
+ MM: function(){return that.digit(month + 1);},
+ d: function(){return String(days);},
+ dd: function(){return that.digit(days);},
+ H: function(){return String(hours);},
+ HH: function(){return that.digit(hours);},
+ h: function(){return String(hours % 12 || 12);},
+ hh: function(){return that.digit(hours % 12 || 12);},
+ A: function(){return meridiem(hours, minutes);},
+ m: function(){return String(minutes);},
+ mm: function(){return that.digit(minutes);},
+ s: function(){return String(seconds);},
+ ss: function(){return that.digit(seconds);},
+ SSS: function(){return that.digit(milliseconds, 3);}
+ }
+
format = format || 'yyyy-MM-dd HH:mm:ss';
- return format.replace(/yyyy/g, ymd[0])
- .replace(/MM/g, ymd[1])
- .replace(/dd/g, ymd[2])
- .replace(/HH/g, hms[0])
- .replace(/mm/g, hms[1])
- .replace(/ss/g, hms[2]);
+
+ return format.replace(REGEX_FORMAT, function(match, $1) {
+ return $1 || (matches[match] && matches[match]()) || match;
+ });
},
-
+
// 转义 html
escape: function(html){
var exp = /[<"'>]|&(?=#[a-zA-Z0-9]+)/g;
@@ -297,7 +333,7 @@ layui.define('jquery', function(exports){
.replace(//g, '>')
.replace(/'/g, ''').replace(/"/g, '"');
},
-
+
// 还原转义的 html
unescape: function(html){
if(html === undefined || html === null) html = '';
@@ -318,68 +354,102 @@ layui.define('jquery', function(exports){
win.document.write(options.content || '');
win.document.close();
},
-
+
// 让指定的元素保持在可视区域
toVisibleArea: function(options){
options = $.extend({
- margin: 160 //触发动作的边界值
- ,duration: 200 //动画持续毫秒数
- ,type: 'y' //触发方向,x 水平、y 垂直
+ margin: 160, // 触发动作的边界值
+ duration: 200, // 动画持续毫秒数
+ type: 'y' // 触发方向,x 水平、y 垂直
}, options);
-
+
if(!options.scrollElem[0] || !options.thisElem[0]) return;
-
- var scrollElem = options.scrollElem //滚动元素
- ,thisElem = options.thisElem //目标元素
- ,vertical = options.type === 'y' //是否垂直方向
- ,SCROLL_NAME = vertical ? 'scrollTop' : 'scrollLeft' //滚动方法
- ,OFFSET_NAME = vertical ? 'top' : 'left' //坐标方式
- ,scrollValue = scrollElem[SCROLL_NAME]() //当前滚动距离
- ,size = scrollElem[vertical ? 'height' : 'width']() //滚动元素的尺寸
- ,scrollOffet = scrollElem.offset()[OFFSET_NAME] //滚动元素所处位置
- ,thisOffset = thisElem.offset()[OFFSET_NAME] - scrollOffet //目标元素当前的所在位置
- ,obj = {};
-
- //边界满足条件
+
+ var scrollElem = options.scrollElem // 滚动元素
+ var thisElem = options.thisElem // 目标元素
+ var vertical = options.type === 'y' // 是否垂直方向
+ var SCROLL_NAME = vertical ? 'scrollTop' : 'scrollLeft' // 滚动方法
+ var OFFSET_NAME = vertical ? 'top' : 'left' // 坐标方式
+ var scrollValue = scrollElem[SCROLL_NAME]() // 当前滚动距离
+ var size = scrollElem[vertical ? 'height' : 'width']() // 滚动元素的尺寸
+ var scrollOffset = scrollElem.offset()[OFFSET_NAME] // 滚动元素所处位置
+ var thisOffset = thisElem.offset()[OFFSET_NAME] - scrollOffset // 目标元素当前的所在位置
+ var obj = {};
+
+ // 边界满足条件
if(thisOffset > size - options.margin || thisOffset < options.margin){
obj[SCROLL_NAME] = thisOffset - size/2 + scrollValue
scrollElem.animate(obj, options.duration);
}
},
-
- //批量事件
- event: function(attr, obj, eventType){
- var _body = $('body');
- eventType = eventType || 'click';
-
- //记录事件回调集合
- obj = util.event[attr] = $.extend(true, util.event[attr], obj) || {};
-
- //清除委托事件
- util.event.UTIL_EVENT_CALLBACK = util.event.UTIL_EVENT_CALLBACK || {};
- _body.off(eventType, '*['+ attr +']', util.event.UTIL_EVENT_CALLBACK[attr])
-
- //绑定委托事件
- util.event.UTIL_EVENT_CALLBACK[attr] = function(){
- var othis = $(this)
- ,key = othis.attr(attr);
- (typeof obj[key] === 'function') && obj[key].call(this, othis);
- };
- //清除旧事件,绑定新事件
- _body.on(eventType, '*['+ attr +']', util.event.UTIL_EVENT_CALLBACK[attr]);
-
- return obj;
+ /**
+ * 批量事件
+ * @param {string} [attr="lay-on"] - 触发事件的元素属性名
+ * @param {Object.} events - 事件集合
+ * @param {Object} [options] - 参数的更多选项
+ * @param {(string|HTMLElement|JQuery)} [options.elem="body"] - 触发事件的委托元素
+ * @param {string} [options.trigger="click"] - 事件触发的方式
+ * @returns {Object} 返回当前 events 参数设置的事件集合
+ */
+ on: function(attr, events, options) {
+ // 若参数一为 object 类型,则为事件集,且省略 attr
+ if (typeof attr === 'object') {
+ options = events || {};
+ events = attr;
+ attr = options.attr || 'lay-on'; // 默认属性名
+ }
+
+ // 更多选项
+ options = $.extend({
+ elem: 'body',
+ trigger: 'click'
+ }, typeof options === 'object' ? options : {
+ trigger: options // 兼容旧版
+ });
+
+ var elem = options.elem = $(options.elem);
+ var attrSelector = '['+ attr +']';
+ var DATANAME = 'UTIL_ON_DATA'; // 缓存在委托元素上的 data-* 属性名
+
+ if (!elem[0]) return; // 若委托元素不存在
+
+ // 初始化 data 默认值,以委托元素为存储单元
+ if (!elem.data(DATANAME)) {
+ elem.data(DATANAME, {
+ events: {},
+ callbacks: {}
+ });
+ }
+
+ // 读取 data 缓存
+ var dataCache = elem.data(DATANAME);
+ var callbacks = dataCache.callbacks;
+
+ // 根据 attr 记录事件集合
+ events = dataCache.events[attr] = $.extend(true, dataCache.events[attr], events);
+
+ // 清除事件委托,避免重复绑定
+ elem.off(options.trigger, attrSelector, callbacks[attr]);
+
+ // 绑定事件委托
+ elem.on(
+ options.trigger,
+ attrSelector,
+ callbacks[attr] = function(e) {
+ var othis = $(this);
+ var key = othis.attr(attr);
+ typeof events[key] === 'function' && events[key].call(this, othis, e);
+ }
+ );
+
+ return events;
}
};
- util.on = util.event;
-
- // DOM 尺寸变化,该创意来自:http://benalman.com/projects/jquery-resize-plugin/
- /*
- !function(a,b,c){"$:nomunge";function l(){f=b[g](function(){d.each(function(){var b=a(this),c=b.width(),d=b.height(),e=a.data(this,i);(c!==e.w||d!==e.h)&&b.trigger(h,[e.w=c,e.h=d])}),l()},e[j])}var f,d=a([]),e=a.resize=a.extend(a.resize,{}),g="setTimeout",h="resize",i=h+"-special-event",j="delay",k="throttleWindow";e[j]=250,e[k]=!0,a.event.special[h]={setup:function(){if(!e[k]&&this[g])return!1;var b=a(this);d=d.add(b),a.data(this,i,{w:b.width(),h:b.height()}),1===d.length&&l()},teardown:function(){if(!e[k]&&this[g])return!1;var b=a(this);d=d.not(b),b.removeData(i),d.length||clearTimeout(f)},add:function(b){function f(b,e,f){var g=a(this),h=a.data(this,i)||{};h.w=e!==c?e:g.width(),h.h=f!==c?f:g.height(),d.apply(this,arguments)}if(!e[k]&&this[g])return!1;var d;return a.isFunction(b)?(d=b,f):(d=b.handler,b.handler=f,void 0)}}}($,window);
- */
-
+ // 兼容旧版
+ util.event = util.on;
+
// 输出接口
exports('util', util);
-});
\ No newline at end of file
+});