layui.define(['jquery', 'dropdown', 'table', 'form'], function (exports) { "use strict"; var dropdown = layui.dropdown, //下拉菜单 table = layui.table, //table组件 $ = layui.jquery, //jQuery form = layui.form, //表单 moduleName = 'dropdownTable', //模块名 dropdownTable = { version: '1.0.4', config: { selectType: 'radio', emptyMsg: '点击此处选择' }, index: layui[moduleName] ? (layui[moduleName].index + 10000) : 0, set: function (options) { this.config = $.extend(true, {}, that.config, options); let config = this.config, selectType = config.selectType, selectField = { type: selectType, fixed: 'left' }, cols = config?.selectTable?.cols ?? [[]]; cols.forEach((item) => { if (JSON.stringify(item).indexOf(JSON.stringify(selectField)) < 0) { item.splice(0, 0, selectField); } }); return that; } }, //操作当前实例 thisModule = function () { let that = this, options = that.config, id = options.id || that.index; thisModule.that[id] = that; //记录当前实例对象 return { config: options, reload: function (options) { that.reload.call(that, options); } }; }, //构造器 Class = function (options) { let index = ++dropdownTable.index; this.index = index; this.tableId = 'dropdown-select-table-' + index; //初始化当前下拉表格的ID this.dropdownId = 'dropdown-' + index; //初始化当前下拉组件的ID //其中selectedIds为初始化被选择的值,selectedDisplayValues为初始化被选中值的显示值 this.config = $.extend(true, {}, dropdownTable.config, options, { selectedIds: [], selectedDisplayValues: [] }); let config = this.config, selectType = config.selectType, selectField = { type: selectType, fixed: 'left' }, selectTableCols = config?.selectTable?.cols ?? [[]]; if (selectType === 'checkbox') { selectTableCols.forEach((item) => { if (JSON.stringify(item).indexOf(JSON.stringify(selectField)) < 0) { item.splice(0, 0, selectField); } }); } this.render(); }; //重载表格实例 Class.prototype.reloadSelectTable = function (selectTableConfig) { let config = this.config; layui.each(selectTableConfig, function (key, item) { if (layui.type(item) === 'array') { delete config.selectTable[key]; } }); $.extend(true, config.selectTable, selectTableConfig); this.clearSelected(); }; //清空选中 Class.prototype.clearSelected = function () { let config = this.config, bindInput = config.bindInput; $(bindInput).val(""); $(bindInput)[0].dataset.displayValue = ''; $.extend(config, { selectedIds: [], selectedDisplayValues: [] }); this.setSelectedDisplayAndValue(); } //渲染 Class.prototype.render = function () { let that = this, options = that.config, _this = options.elem = $(options.elem); if (!_this[0]) { return; } that.initElemArea(); that.iniDropdown(); }; //初始化绑定元素区域 Class.prototype.initElemArea = function () { let that = this, config = this.config, elem = config.elem, searchName = this.config?.searchName ?? 'keywords'; $(elem).css({ 'display': 'inline-block', 'width': '80%', 'height': '100%', 'min-height': '35px', 'border': '1px solid #eee', 'line-height': '35px', 'box-sizing': 'border-box', 'padding': '0 10px', 'cursor': 'pointer' }); $(elem).hover(() => { $(elem).css({ 'border-color': '#e2e2e2' }); }, () => { $(elem).css({ 'border-color': '#eee' }); }); let selectButton = $("") selectButton.css({ 'display': 'inline-block', 'width': '20%', 'min-width': '45px', 'height': '100%', 'box-sizing': 'border-box', 'font-size': '12px', 'padding': '0', 'line-height': '36px' }); if (config?.needPopup ?? true) { $(elem).after(selectButton); } else { $(elem).css({ 'width': '100%' }); } let selectContent = `
选择
选择结果
` selectButton.click(() => { layer.open({ title: '选择', type: 1, area: ['70%', '80%'], maxmin: true, btn: ['确认', '取消'], content: selectContent, success: () => { renderSelectedTable(); renderDataTable(); bindTableEvent(); initSelectedTable(); bindDataTableSearchFormEvent(); }, yes: index => { let selectedData = table.getData('selected-table') ?? []; let selectedIds = selectedData.map(item => item.id); config.selectedIds = selectedIds; config.selectedDisplayValues = selectedData.map(item => item.displayValue); that.setSelectedDisplayAndValue(); layer.close(index); let onSelected = config.onSelected; if ($.isFunction(onSelected)) { onSelected(selectedIds); } } }); }); function renderDataTable() { let tableNeedConfig = { id: 'data-table', elem: '#data-table', done: function (res) { setDataTableSelected(); } }, tableConfig = $.extend({}, config.selectTable, tableNeedConfig); table.render(tableConfig); } function renderSelectedTable() { table.render({ elem: '#selected-table', cols: [ [ { field: 'id', title: 'ID', width: 80, sort: true }, { field: 'displayValue', title: '值' }, { field: 'originValue', title: '原始值', hide: true }, { fixed: 'right', title: '操作', width: 70, toolbar: '#selected-table-opt-bar' } ] ], data: [] }); } function bindDataTableSearchFormEvent() { $('#data-table-search-button').click(() => { let where = {}, searchValue = $('#data_table_' + searchName).val(); where[searchName] = searchValue; table.reloadData('data-table', { page: { curr: 1 }, where: where }); }); } function bindTableEvent() { table.on('row(data-table)', (obj) => { let data = obj.data; selectedTableReload({ 'id': data[config.selectTable.uniqueId], 'displayValue': data[config.selectTable.displayField], 'originValue': JSON.stringify(data) }); }); table.on('tool(selected-table)', obj => { if (obj.event === 'del') { obj.del(); setDataTableSelected(); } }); } function selectedTableReload(selectedData) { let originData = table.getData('selected-table') ?? []; if (originData.map(item => item.id).includes(selectedData.id)) { originData = originData.filter(item => item.id !== selectedData.id); } else { if (config.selectType === 'radio') { originData = []; } originData.push(selectedData) } table.reload('selected-table', { data: originData }); setDataTableSelected(); } function setDataTableSelected() { let selectedIds = (table.getData('selected-table') ?? []).map(item => item.id + ''); let data = (table.getData('data-table') ?? []); data.forEach((item, index) => { if (config.selectType === 'checkbox') { table.setRowChecked('data-table', { type: 'checkbox', index: index, checked: selectedIds.includes(item.id + '') }); } else if (selectedIds.includes(item.id + '')) { table.setRowChecked('data-table', { type: 'radio', index: index, checked: true }); } }); } function initSelectedTable() { let bindInput = config.bindInput, bindInputValue = $(bindInput).val() ?? '', bindInputDisplayValue = $(bindInput)[0].dataset.displayValue ?? ''; config.selectedIds = bindInputValue.split("$").filter(item => item !== ''); config.selectedDisplayValues = bindInputDisplayValue.split("$").filter(item => item !== ''); config.selectedIds.forEach((id, index) => { selectedTableReload({ 'id': id, 'displayValue': config.selectedDisplayValues[index] }); }); } } //初始化下拉组件 Class.prototype.iniDropdown = function () { let that = this, config = that.config, elem = config.elem; dropdown.render({ id: config.id ?? that.index, elem: elem, trigger: 'click', content: that.iniSelectTableHtml(), style: config?.style ?? 'min-width:450px;box-sizing:border-box; padding:10px;width:' + $(elem).width() + 'px', ready: () => { that.iniSelectTable(); that.bindRowCheckToSelectTable(); that.bindSelectBoxEventToSelectTable(); that.bindSearchToSelectTable(); } }); }; //初始化table的html文件 Class.prototype.iniSelectTableHtml = function () { let index = this.index, tableId = this.tableId, searchName = this.config?.searchName ?? 'keywords', selectTableSearchFormId = 'select-table-search-' + index, selectTableSearchButtonId = 'select-table-search-button-' + index; $.extend(this.config, { selectTableSearchFormId: selectTableSearchFormId, selectTableSearchButtonId: selectTableSearchButtonId }); return [ '
', '', '
', '
', ].join(''); } //初始化表格 Class.prototype.iniSelectTable = function () { let that = this, config = that.config, tableId = that.tableId, selectTable = config.selectTable, tableNeedConfig = { id: tableId, elem: '#' + tableId, toolbar: '#' + config.selectTableSearchFormId, defaultToolbar: ['filter'], done: function (res) { that.iniDefaultSelected(res.data) } }, tableConfig = $.extend({}, selectTable, tableNeedConfig); table.render(tableConfig); }; //处理默认选中值的问题 Class.prototype.iniDefaultSelected = function (tableData = []) { let that = this, tableId = that.tableId, config = that.config, selectType = config.selectType, bindInput = config.bindInput, bindInputValue = $(bindInput).val() ?? '', bindInputDisplayValue = $(bindInput)[0].dataset.displayValue ?? ''; config.selectedIds = bindInputValue.split("$").filter(item => item !== ''); config.selectedDisplayValues = bindInputDisplayValue.split("$").filter(item => item !== ''); if (tableData.length === 0) { that.setSelectedDisplayAndValue(); return; } table.setRowChecked(tableId, { index: 'all', checked: false }); let selectedIds = config.selectedIds; if (selectedIds.length > 0) { let tableIdData = tableData.map(item => item[config.selectTable.uniqueId].toString()); if (selectType === 'radio' && selectedIds.length === 1) { let selectedItemIndex = tableIdData.indexOf(selectedIds[0].toString()); if (selectedItemIndex >= 0) { table.setRowChecked(tableId, { type: selectType, index: selectedItemIndex, checked: true }) } } else { tableIdData.forEach(function (item, itemIndex) { table.setRowChecked(tableId, { type: selectType, index: itemIndex, checked: selectedIds.includes(item) }); }); } } that.setSelectedDisplayAndValue(); } //处理选择框事件 Class.prototype.bindSelectBoxEventToSelectTable = function () { let that = this, options = that.config, selectType = options.selectType, uniqueId = options.selectTable.uniqueId, displayField = options.selectTable.displayField, tableId = that.tableId; if (selectType === 'radio') { //单选 table.on('radio(' + tableId + ')', function (obj) { dealRadioSelectedData(obj.checked, obj.data); }); } else { //复选框 table.on('checkbox(' + tableId + ')', function (obj) { let eventType = obj.type, checked = obj.checked; if (eventType === 'all') { table.getData(tableId).forEach(function (rowData) { dealCheckboxSelectedData(checked, rowData); }); } if (eventType === 'one') { dealCheckboxSelectedData(checked, obj.data); } }); } function dealRadioSelectedData(checked, rowData) { let rowId = rowData[uniqueId].toString(); that.config.selectedIds = []; that.config.selectedDisplayValues = []; if (checked) { that.config.selectedIds.push(rowId); that.config.selectedDisplayValues.push(rowData[displayField]); } that.setSelectedDisplayAndValue(); } function dealCheckboxSelectedData(checked, rowData) { let rowId = rowData[uniqueId].toString(); //处理选中 if (checked && !that.config.selectedIds.includes(rowId)) { that.config.selectedIds.push(rowId); that.config.selectedDisplayValues.push(rowData[displayField]); } //处理未选中 if (!checked) { let cancelIndex = that.config.selectedIds.indexOf(rowId); if (rowId > -1) { that.config.selectedIds.splice(cancelIndex, 1); that.config.selectedDisplayValues.splice(cancelIndex, 1); } } that.setSelectedDisplayAndValue(); } } //绑定行点击事件到选择表中 Class.prototype.bindRowCheckToSelectTable = function () { let that = this, tableId = that.tableId, options = that.config, selectType = options.selectType, uniqueId = options.selectTable.uniqueId, displayField = options.selectTable.displayField; table.on('row(' + tableId + ')', function (obj) { let rowId = obj.data[uniqueId].toString(), checked; if (!that.config.selectedIds.includes(rowId)) { if (selectType === 'radio') { that.config.selectedIds = []; that.config.selectedDisplayValues = []; } that.config.selectedIds.push(rowId); that.config.selectedDisplayValues.push(obj.data[displayField]); checked = true; } else { let cancelSelectedIdIndex = that.config.selectedIds.indexOf(rowId); that.config.selectedIds.splice(cancelSelectedIdIndex, 1); that.config.selectedDisplayValues.splice(cancelSelectedIdIndex, 1); checked = false; } obj.setRowChecked({ type: selectType, checked: checked }); //加入选中事件 let onSelected = options.onSelected; if (checked && $.isFunction(onSelected)) { onSelected(new Array(obj.data[options.selectTable.uniqueId])); } that.setSelectedDisplayAndValue(); }); }; //绑定表格的搜索事件 Class.prototype.bindSearchToSelectTable = function () { let tableId = this.tableId, selectTableSearchButtonId = this.config.selectTableSearchButtonId; form.on('submit(' + selectTableSearchButtonId + ')', function (data) { table.reloadData(tableId, { page: { curr: 1 }, where: data.field }); return false; }); } //设置显示值和实际存储值 Class.prototype.setSelectedDisplayAndValue = function () { let that = this, tableId = that.tableId, options = that.config, elem = options.elem, bindInput = options.bindInput, selectedIds = options?.selectedIds ?? [], selectDisplayValues = options.selectedDisplayValues, emptyMsg = options.emptyMsg; elem.find("span").remove(); if (selectedIds.length > 0 && selectedIds.length === selectDisplayValues.length) { selectedIds.forEach((item, itemIndex) => { let selectedDisplayValue = selectDisplayValues[itemIndex], closeObject = $('×'), displayHtml = [ '' + selectedDisplayValue, '', ].join(''), displayObject = $(displayHtml).append(closeObject); displayObject.attr({ "style": "margin-left:5px;font-size:14px;padding:4px 6px" }); //绑定鼠标事件 closeObject.on('mouseenter mouseleave', function (event) { let optType = event.type, fontColor = optType === 'mouseleave' ? 'white' : 'red'; $(this).attr({ "style": "color:" + fontColor + ";margin-left:5px;cursor:pointer" }); }); closeObject.on('click', function () { let _this = this, tableIdData = table.getData(tableId).map(item => item[options.selectTable.uniqueId]), selectedId = _this.dataset.selectedId, cancelSelectedIdIndex = that.config.selectedIds.indexOf(selectedId); that.config.selectedIds.splice(cancelSelectedIdIndex, 1); that.config.selectedDisplayValues.splice(cancelSelectedIdIndex, 1); if (tableIdData.includes(selectedId)) { if (options.selectType === 'radio') { table.setRowChecked(tableId, { type: 'radio', index: 'all', checked: false }); } else { table.setRowChecked(tableId, { type: options.selectType, index: tableIdData.indexOf(selectedId), checked: false }); } } that.setSelectedDisplayAndValue(); }); elem.append(displayObject); }); } else { elem.append('' + emptyMsg + ''); } $(bindInput).val(selectedIds.join("$")); $(bindInput)[0].dataset.displayValue = selectDisplayValues.join("$"); } //记录所有实例 thisModule.that = {}; //记录所有实例对象 //获取当前实例对象 thisModule.getThis = function (id) { let that = thisModule.that[id]; if (!that) { hint.error(id ? (moduleName + ' instance with ID \'' + id + '\' not found') : 'ID argument required'); } return that; } //重载实例 dropdownTable.reloadSelectTable = function (id, selectTableConfig) { let that = thisModule.getThis(id); that.reloadSelectTable(selectTableConfig); return thisModule.call(that); } //请空已选择 dropdownTable.clearSelected = function (id) { let that = thisModule.getThis(id); that.clearSelected(); } //核心入口 dropdownTable.render = function (options) { let inst = new Class(options); if (dropdownTable.index === 1) { console.log("欢迎使用Hg科技的dropdownTable组件,version:" + dropdownTable.version + ",期待您的建议!"); } inst.iniDefaultSelected(); return thisModule.call(inst); } exports(moduleName, dropdownTable); });