UNPKG

ax5ui-grid

Version:

A grid plugin that works with Bootstrap & jQuery

1,105 lines (975 loc) 138 kB
// ax5.ui.grid.body (function () { const GRID = ax5.ui.grid; const U = ax5.util; const columnSelect = { focusClear: function () { let self = this, _column; for (let c in self.focusedColumn) { _column = self.focusedColumn[c]; if (_column) { self.$.panel[_column.panelName] .find('[data-ax5grid-tr-data-index="' + _column.dindex + '"]') .find('[data-ax5grid-column-rowindex="' + _column.rowIndex + '"][data-ax5grid-column-colindex="' + _column.colIndex + '"]') .removeAttr('data-ax5grid-column-focused'); } } self.focusedColumn = {}; }, clear: function () { let self = this, _column; for (let c in self.selectedColumn) { _column = self.selectedColumn[c]; if (_column) { self.$.panel[_column.panelName] .find('[data-ax5grid-tr-data-index="' + _column.dindex + '"]') .find('[data-ax5grid-column-rowindex="' + _column.rowIndex + '"][data-ax5grid-column-colindex="' + _column.colIndex + '"]') .removeAttr('data-ax5grid-column-selected'); } } self.selectedColumn = {}; }, init: function (column) { let self = this; if (this.isInlineEditing) { for (let editKey in this.inlineEditing) { if (editKey == column.dindex + "_" + column.colIndex + "_" + column.rowIndex) { return this; } } } // focus columnSelect.focusClear.call(self); self.focusedColumn[column.dindex + "_" + column.colIndex + "_" + column.rowIndex] = { panelName: column.panelName, dindex: column.dindex, doindex: column.doindex, rowIndex: column.rowIndex, colIndex: column.colIndex, colspan: column.colspan }; // select columnSelect.clear.call(self); self.xvar.selectedRange = { start: [column.dindex, column.rowIndex, column.colIndex, column.colspan - 1], end: null }; self.selectedColumn[column.dindex + "_" + column.colIndex + "_" + column.rowIndex] = (function (data) { if (data) { return false; } else { return { panelName: column.panelName, dindex: column.dindex, doindex: column.doindex, rowIndex: column.rowIndex, colIndex: column.colIndex, colspan: column.colspan } } })(self.selectedColumn[column.dindex + "_" + column.colIndex + "_" + column.rowIndex]); this.$.panel[column.panelName] .find('[data-ax5grid-tr-data-index="' + column.dindex + '"]') .find('[data-ax5grid-column-rowindex="' + column.rowIndex + '"][data-ax5grid-column-colindex="' + column.colIndex + '"]') .attr('data-ax5grid-column-focused', "true") .attr('data-ax5grid-column-selected', "true"); if (this.isInlineEditing) { GRID.body.inlineEdit.deActive.call(this, "RETURN"); } }, update: function (column) { const self = this; let dindex, doindex, colIndex, rowIndex, trl; self.xvar.selectedRange["end"] = [column.dindex, column.rowIndex, column.colIndex, column.colspan - 1]; columnSelect.clear.call(self); let range = { r: { s: Math.min(self.xvar.selectedRange["start"][0], self.xvar.selectedRange["end"][0]), e: Math.max(self.xvar.selectedRange["start"][0], self.xvar.selectedRange["end"][0]) }, c: { s: Math.min(self.xvar.selectedRange["start"][2], self.xvar.selectedRange["end"][2]), e: Math.max(self.xvar.selectedRange["start"][2] + self.xvar.selectedRange["start"][3], self.xvar.selectedRange["end"][2] + self.xvar.selectedRange["end"][3]) } }; dindex = range.r.s; for (; dindex <= range.r.e; dindex++) { trl = this.bodyRowTable.rows.length; rowIndex = 0; for (; rowIndex < trl; rowIndex++) { colIndex = range.c.s; for (; colIndex <= range.c.e; colIndex++) { var _panels = [], panelName = ""; if (self.xvar.frozenRowIndex > dindex) _panels.push("top"); if (self.xvar.frozenColumnIndex > colIndex) _panels.push("left"); _panels.push("body"); if (_panels[0] !== "top") _panels.push("scroll"); panelName = _panels.join("-"); self.selectedColumn[dindex + "_" + colIndex + "_" + rowIndex] = { panelName: panelName, dindex: dindex, rowIndex: rowIndex, colIndex: colIndex, colspan: column.colspan }; _panels = null; panelName = null; } } } dindex = null; doindex = null; colIndex = null; rowIndex = null; for (var c in self.selectedColumn) { var _column = self.selectedColumn[c]; if (_column) { self.$.panel[_column.panelName] .find('[data-ax5grid-tr-data-index="' + _column.dindex + '"]') .find('[data-ax5grid-column-rowindex="' + _column.rowIndex + '"][data-ax5grid-column-colindex="' + _column.colIndex + '"]') .attr('data-ax5grid-column-selected', 'true'); } } } }; const columnSelector = { "on": function (cell) { let self = this; if (this.inlineEditing[cell.dindex + "_" + cell.colIndex + "_" + cell.rowIndex]) { return; } columnSelect.init.call(self, cell); this.$["container"]["body"] .on("mousemove.ax5grid-" + this.instanceId, '[data-ax5grid-column-attr="default"]', function (e) { if (this.getAttribute("data-ax5grid-column-rowIndex")) { columnSelect.update.call(self, { panelName: this.getAttribute("data-ax5grid-panel-name"), dindex: Number(this.getAttribute("data-ax5grid-data-index")), doindex: Number(this.getAttribute("data-ax5grid-data-o-index")), rowIndex: Number(this.getAttribute("data-ax5grid-column-rowIndex")), colIndex: Number(this.getAttribute("data-ax5grid-column-colIndex")), colspan: Number(this.getAttribute("colspan")) }); U.stopEvent(e); } }) .on("mouseup.ax5grid-" + this.instanceId, function () { columnSelector.off.call(self); }) .on("mouseleave.ax5grid-" + this.instanceId, function () { columnSelector.off.call(self); }); jQuery(document.body) .attr('unselectable', 'on') .css('user-select', 'none') .on('selectstart', false); }, "off": function () { this.$["container"]["body"] .off("mousemove.ax5grid-" + this.instanceId) .off("mouseup.ax5grid-" + this.instanceId) .off("mouseleave.ax5grid-" + this.instanceId); jQuery(document.body) .removeAttr('unselectable') .css('user-select', 'auto') .off('selectstart'); } }; const updateRowState = function (_states, _dindex, _doindex, _data) { let self = this, cfg = this.config, processor = { "selected": function (_dindex, _doindex) { if (this.list[_doindex]) { let i = this.$.livePanelKeys.length; while (i--) { this.$.panel[this.$.livePanelKeys[i]] .find('[data-ax5grid-tr-data-index="' + _dindex + '"]') .attr("data-ax5grid-selected", this.list[_doindex][cfg.columnKeys.selected]); } } }, "selectedClear": function () { let di = this.list.length; let pi; if (!this.proxyList) { while (di--) { if (this.list[di][cfg.columnKeys.selected]) { pi = this.$.livePanelKeys.length; while (pi--) { this.$.panel[this.$.livePanelKeys[pi]] .find('[data-ax5grid-tr-data-index="' + di + '"]') .attr("data-ax5grid-selected", false); } } this.list[di][cfg.columnKeys.selected] = false; } } else { while (di--) { this.list[di][cfg.columnKeys.selected] = false; } di = this.proxyList.length; while (di--) { if (this.list[doi][cfg.columnKeys.selected]) { pi = this.$.livePanelKeys.length; while (pi--) { this.$.panel[this.$.livePanelKeys[pi]] .find('[data-ax5grid-tr-data-index="' + di + '"]') .attr("data-ax5grid-selected", false); } } this.proxyList[di][cfg.columnKeys.selected] = false; let doi = this.proxyList[di].__original_index__; } } }, "cellChecked": function (_dindex, _doindex, _data) { let key = _data.key, rowIndex = _data.rowIndex, colIndex = _data.colIndex; let panelName = (function () { let _panels = []; if (this.xvar.frozenRowIndex > _dindex) _panels.push("top"); if (this.xvar.frozenColumnIndex > colIndex) _panels.push("left"); _panels.push("body"); if (_panels[0] !== "top") _panels.push("scroll"); return _panels.join("-"); }).call(this); this.$.panel[panelName] .find('[data-ax5grid-tr-data-index="' + _dindex + '"]') .find('[data-ax5grid-column-rowIndex="' + rowIndex + '"][data-ax5grid-column-colIndex="' + colIndex + '"]') .find('[data-ax5grid-editor="checkbox"]') .attr("data-ax5grid-checked", '' + _data.checked); } }; if (typeof _doindex === "undefined") _doindex = _dindex; _states.forEach(function (_state) { if (!processor[_state]) throw 'invaild state name'; processor[_state].call(self, _dindex, _doindex, _data); }); }; const updateRowStateAll = function (_states, _data) { let self = this, cfg = this.config, processor = { "selected": function (_dindex) { GRID.body.repaint.call(this, true); } }; _states.forEach(function (_state) { if (!processor[_state]) throw 'invaild state name'; processor[_state].call(self, _data); }); }; const init = function () { let self = this; this.$["container"]["body"].on("click", '[data-ax5grid-column-attr]', function (e) { let panelName, attr, row, col, dindex, doindex, rowIndex, colIndex, disableSelection, targetClick = { "default": function (_column) { let column = self.bodyRowMap[_column.rowIndex + "_" + _column.colIndex], that = { self: self, page: self.page, list: self.list, item: self.list[_column.doindex], dindex: _column.dindex, doindex: _column.doindex, rowIndex: _column.rowIndex, colIndex: _column.colIndex, column: column, value: self.list[_column.dindex][column.key] }; if (column.editor && column.editor.type === "checkbox") { // todo : GRID.inlineEditor에서 처리 할수 있도록 구문 변경 필요. let value = GRID.data.getValue.call(self, _column.dindex, _column.doindex, column.key), checked, newValue; if (column.editor.config && column.editor.config.trueValue) { if (checked = !(value == column.editor.config.trueValue)) { newValue = column.editor.config.trueValue; } else { newValue = column.editor.config.falseValue; } } else { newValue = checked = (value == false || value == "false" || value < "1") ? "true" : "false"; } GRID.data.setValue.call(self, _column.dindex, _column.doindex, column.key, newValue); updateRowState.call(self, ["cellChecked"], _column.dindex, _column.doindex, { key: column.key, rowIndex: _column.rowIndex, colIndex: _column.colIndex, editorConfig: column.editor.config, checked: checked }); } if (self.config.body.onClick) { self.config.body.onClick.call(that, that, e); } }, "rowSelector": function (_column) { let item = self.list[_column.doindex]; if (item[self.config.columnKeys.disableSelection]) { return false; } if (!self.config.multipleSelect && self.selectedDataIndexs[0] !== _column.doindex) { updateRowState.call(self, ["selectedClear"]); GRID.data.clearSelect.call(self); } GRID.data.select.call(self, _column.dindex, _column.doindex, undefined, { internalCall: true }); updateRowState.call(self, ["selected"], _column.dindex, _column.doindex); }, "lineNumber": function (_column) { }, "tree-control": function (_column, _el) { //console.log(_column); toggleCollapse.call(self, _column.dindex, _column.doindex); } }; panelName = this.getAttribute("data-ax5grid-panel-name"); attr = this.getAttribute("data-ax5grid-column-attr"); row = Number(this.getAttribute("data-ax5grid-column-row")); col = Number(this.getAttribute("data-ax5grid-column-col")); rowIndex = Number(this.getAttribute("data-ax5grid-column-rowIndex")); colIndex = Number(this.getAttribute("data-ax5grid-column-colIndex")); dindex = Number(this.getAttribute("data-ax5grid-data-index")); doindex = Number(this.getAttribute("data-ax5grid-data-o-index")); if (attr in targetClick) { targetClick[attr]({ panelName: panelName, attr: attr, row: row, col: col, dindex: dindex, doindex: doindex, rowIndex: rowIndex, colIndex: colIndex }, this); } }); this.$["container"]["body"].on("dblclick", '[data-ax5grid-column-attr]', function (e) { let panelName, attr, row, col, dindex, doindex, rowIndex, colIndex, targetDBLClick = { "default": function (_column) { if (self.isInlineEditing) { for (let columnKey in self.inlineEditing) { if (columnKey == _column.dindex + "_" + _column.colIndex + "_" + _column.rowIndex) { return this; } } } let column = self.bodyRowMap[_column.rowIndex + "_" + _column.colIndex], value = ""; if (column) { if (!self.list[dindex].__isGrouping) { value = GRID.data.getValue.call(self, dindex, doindex, column.key); } } let editor = self.colGroup[_column.colIndex].editor; if (U.isObject(editor)) { GRID.body.inlineEdit.active.call(self, self.focusedColumn, e, value); } else { // 더블클릭 실행 if (self.config.body.onDBLClick) { let that = { self: self, page: self.page, list: self.list, item: self.list[_column.dindex], dindex: _column.dindex, doindex: _column.doindex, rowIndex: _column.rowIndex, colIndex: _column.colIndex, column: column, value: self.list[_column.dindex][column.key] }; self.config.body.onDBLClick.call(that); } } }, "rowSelector": function (_column) { }, "lineNumber": function (_column) { } }; panelName = this.getAttribute("data-ax5grid-panel-name"); attr = this.getAttribute("data-ax5grid-column-attr"); row = Number(this.getAttribute("data-ax5grid-column-row")); col = Number(this.getAttribute("data-ax5grid-column-col")); rowIndex = Number(this.getAttribute("data-ax5grid-column-rowIndex")); colIndex = Number(this.getAttribute("data-ax5grid-column-colIndex")); dindex = Number(this.getAttribute("data-ax5grid-data-index")); doindex = Number(this.getAttribute("data-ax5grid-data-o-index")); if (attr in targetDBLClick) { targetDBLClick[attr]({ panelName: panelName, attr: attr, row: row, col: col, dindex: dindex, doindex: doindex, rowIndex: rowIndex, colIndex: colIndex }); } }); if (this.config.contextMenu) { this.$["container"]["body"].on("contextmenu", function (e) { let target, dindex, doindex, rowIndex, colIndex, item, column, param = {}; target = U.findParentNode(e.target, function (t) { if (t.getAttribute("data-ax5grid-column-attr")) { return true; } }); if (target) { // item 찾기 rowIndex = Number(target.getAttribute("data-ax5grid-column-rowIndex")); colIndex = Number(target.getAttribute("data-ax5grid-column-colIndex")); dindex = Number(target.getAttribute("data-ax5grid-data-index")); doindex = Number(target.getAttribute("data-ax5grid-data-o-index")); column = self.bodyRowMap[rowIndex + "_" + colIndex]; item = self.list[dindex]; } if (!self.contextMenu) { self.contextMenu = new ax5.ui.menu(); } self.contextMenu.setConfig(self.config.contextMenu); param = { element: target, dindex: dindex, doindex: doindex, rowIndex: rowIndex, colIndex: colIndex, item: item, column: column, gridSelf: self }; self.contextMenu.popup(e, { filter: function () { return self.config.contextMenu.popupFilter.call(this, this, param); }, param: param }); U.stopEvent(e.originalEvent); target = null; dindex = null; doindex = null; rowIndex = null; colIndex = null; item = null; column = null; param = null; }); } this.$["container"]["body"] .on("mousedown", '[data-ax5grid-column-attr="default"]', function (e) { if (self.xvar.touchmoved) return false; if (this.getAttribute("data-ax5grid-column-rowIndex")) { columnSelector.on.call(self, { panelName: this.getAttribute("data-ax5grid-panel-name"), dindex: Number(this.getAttribute("data-ax5grid-data-index")), doindex: Number(this.getAttribute("data-ax5grid-data-o-index")), rowIndex: Number(this.getAttribute("data-ax5grid-column-rowIndex")), colIndex: Number(this.getAttribute("data-ax5grid-column-colIndex")), colspan: Number(this.getAttribute("colspan")) }); } }) .on("dragstart", function (e) { U.stopEvent(e); return false; }); resetFrozenColumn.call(this); // 그리드 바디에 출력할 여유 카운트 this.xvar.paintRowCountMargin = this.config.virtualScrollYCountMargin; this.xvar.paintRowCountTopMargin = this.config.virtualScrollYCountMargin - Math.floor(this.config.virtualScrollYCountMargin / 2); if (this.config.virtualScrollAccelerated) { this.__throttledScroll = U.throttle(function (css, opts) { if (this.config.virtualScrollY && !opts.noRepaint && "top" in css) { repaint.call(this); } else if (this.config.virtualScrollX && !opts.noRepaint && "left" in css) { repaint.call(this); } if (opts.callback) { opts.callback(); } }, this.config.virtualScrollAcceleratedDelayTime); } else { this.__throttledScroll = false; } }; const resetFrozenColumn = function () { let cfg = this.config, dividedBodyRowObj = GRID.util.divideTableByFrozenColumnIndex(this.bodyRowTable, this.xvar.frozenColumnIndex); this.asideBodyRowData = (function (dataTable) { let data = {rows: []}; for (let i = 0, l = dataTable.rows.length; i < l; i++) { data.rows[i] = {cols: []}; if (i === 0) { let col = { label: "", colspan: 1, rowspan: dataTable.rows.length, colIndex: null }, _col = {}; if (cfg.showLineNumber) { _col = jQuery.extend({}, col, { width: cfg.lineNumberColumnWidth, _width: cfg.lineNumberColumnWidth, columnAttr: "lineNumber", label: "&nbsp;", key: "__d-index__" }); data.rows[i].cols.push(_col); } if (cfg.showRowSelector) { _col = jQuery.extend({}, col, { width: cfg.rowSelectorColumnWidth, _width: cfg.rowSelectorColumnWidth, columnAttr: "rowSelector", label: "", key: "__d-checkbox__" }); data.rows[i].cols.push(_col); } } } return data; }).call(this, this.bodyRowTable); //console.log(dividedBodyRowObj); this.leftBodyRowData = dividedBodyRowObj.leftData; this.bodyRowData = dividedBodyRowObj.rightData; if (cfg.body.grouping) { let dividedBodyGroupingObj = GRID.util.divideTableByFrozenColumnIndex(this.bodyGroupingTable, this.xvar.frozenColumnIndex); this.asideBodyGroupingData = (function (dataTable) { let data = {rows: []}; for (let i = 0, l = dataTable.rows.length; i < l; i++) { data.rows[i] = {cols: []}; if (i === 0) { let col = { label: "", colspan: 1, rowspan: dataTable.rows.length, colIndex: null }, _col = {}; if (cfg.showLineNumber) { _col = jQuery.extend({}, col, { width: cfg.lineNumberColumnWidth, _width: cfg.lineNumberColumnWidth, columnAttr: "lineNumber", label: "&nbsp;", key: "__d-index__" }); data.rows[i].cols.push(_col); } if (cfg.showRowSelector) { _col = jQuery.extend({}, col, { width: cfg.rowSelectorColumnWidth, _width: cfg.rowSelectorColumnWidth, columnAttr: "rowSelector", label: "", key: "__d-checkbox__" }); data.rows[i].cols.push(_col); } } } return data; }).call(this, this.bodyGroupingTable); this.leftBodyGroupingData = dividedBodyGroupingObj.leftData; this.bodyGroupingData = dividedBodyGroupingObj.rightData; this.bodyGroupingMap = GRID.util.makeBodyRowMap.call(this, this.bodyGroupingTable); } this.leftFootSumData = {}; this.footSumData = {}; if (this.config.footSum) { let dividedFootSumObj = GRID.util.divideTableByFrozenColumnIndex(this.footSumTable, this.xvar.frozenColumnIndex); this.leftFootSumData = dividedFootSumObj.leftData; this.footSumData = dividedFootSumObj.rightData; } }; const getFieldValue = function (_list, _item, _index, _col, _value, _returnPlainText) { let _key = _col.key, tagsToReplace = { '<': '&lt;', '>': '&gt;' }; if (_key === "__d-index__") { return (typeof _item["__index"] !== "undefined") ? _item["__index"] + 1 : ""; } else if (_key === "__d-checkbox__") { return `<div class="checkBox" style="max-height: ${_col.width - 10}px;min-height: ${_col.width - 10}px;"></div>`; } else { if (_col.editor && (function (_editor) { if (_editor.type in GRID.inlineEditor) { return (GRID.inlineEditor[_editor.type].editMode == "inline"); } return false; })(_col.editor)) { // editor가 inline타입이라면 _value = _value || GRID.data.getValue.call(this, _index, _item.__origin_index__, _key); if (U.isFunction(_col.editor.disabled)) { if (_col.editor.disabled.call({ list: _list, dindex: _index, item: _list[_index], key: _key, value: _value })) { return _value; } } // print editor return _returnPlainText ? _value : GRID.inlineEditor[_col.editor.type].getHtml(this, _col.editor, _value); } const valueProcessor = { "formatter": function () { let that = { key: _key, value: _value || GRID.data.getValue.call(this, _index, _item.__origin_index__, _key), dindex: _index, item: _item, list: _list }; if (U.isFunction(_col.formatter)) { return _col.formatter.call(that); } else { return GRID.formatter[_col.formatter].call(that); } }, "default": function () { let returnValue = ""; if (typeof _value !== "undefined") { returnValue = _value; } else { if (/[\.\[\]]/.test(_key)) { _value = GRID.data.getValue.call(this, _index, _item.__origin_index__, _key); } else { _value = _item[_key]; } if (_value !== null && typeof _value !== "undefined") returnValue = _value; } // 키값이 Boolean일때 오류 발생하여 수정. return (typeof returnValue !== "string") ? returnValue : returnValue.replace(/[<>]/g, function (tag) { return tagsToReplace[tag] || tag; }); }, "treeControl": function (__value) { let cfg = this.config, keys = this.config.tree.columnKeys, indentNodeHtml = ''; if (_item[keys.children].length) { indentNodeHtml += '<a ' + 'data-ax5grid-data-index="' + _index + '" ' + 'data-ax5grid-column-attr="tree-control" ' + 'data-ax5grid-tnode-arrow="" ' + 'style="width: ' + cfg.tree.arrowWidth + 'px;padding-left:' + (_item[keys.depth] * cfg.tree.indentWidth) + 'px;"' + '>'; indentNodeHtml += (_item[keys.collapse]) ? cfg.tree.icons.collapsedArrow : cfg.tree.icons.openedArrow; indentNodeHtml += '</a>'; } else { indentNodeHtml += '<span ' + 'data-ax5grid-tnode-arrow="" ' + 'style="width: ' + cfg.tree.arrowWidth + 'px;padding-left:' + (_item[keys.depth] * cfg.tree.indentWidth) + 'px;"' + '>&nbsp;</span>'; } indentNodeHtml += '<span ' + 'data-ax5grid-tnode-item="' + ((_item[keys.children].length) ? 'group' : 'item') + '" ' + 'style="width: ' + cfg.tree.iconWidth + 'px;"' + '>'; indentNodeHtml += (_item[keys.children].length) ? (_item[keys.collapse]) ? cfg.tree.icons.collapsedGroupIcon : cfg.tree.icons.groupIcon : cfg.tree.icons.itemIcon; indentNodeHtml += '</span>'; return indentNodeHtml + __value; } }; let returnValue = (_col.formatter) ? valueProcessor.formatter.call(this) : valueProcessor.default.call(this); if (this.config.tree.use && _col.treeControl) { returnValue = valueProcessor.treeControl.call(this, returnValue); } return returnValue; } }; const getGroupingValue = function (_item, _index, _col) { let value, that, _key = _col.key, _label = _col.label; if (typeof _key === "undefined") { that = { key: _key, list: _item.__groupingList, groupBy: _item.__groupingBy }; if (U.isFunction(_label)) { value = _label.call(that); } else { value = _label; } _item[_col.colIndex] = value; return value; } else if (_key === "__d-index__") { return ''; } else if (_key === "__d-checkbox__") { return ''; } else { if (_col.collector) { that = { key: _key, list: _item.__groupingList }; if (U.isFunction(_col.collector)) { value = _col.collector.call(that); } else { value = GRID.collector[_col.collector].call(that); } _item[_col.colIndex] = value; if (_col.formatter) { that.value = value; if (U.isFunction(_col.formatter)) { return _col.formatter.call(that); } else { return GRID.formatter[_col.formatter].call(that); } } else { return value; } } else { return "&nbsp;"; } } }; const getSumFieldValue = function (_list, _col) { let _key = _col.key, _label = _col.label; //, _collector, _formatter if (typeof _key === "undefined") { return _label; } else if (_key === "__d-index__" || _key === "__d-checkbox__") { return '&nbsp;'; } else { if (_col.collector) { let that = { key: _key, list: _list }, value; if (U.isFunction(_col.collector)) { value = _col.collector.call(that); } else { value = GRID.collector[_col.collector].call(that); } if (_col.formatter) { that.value = value; if (U.isFunction(_col.formatter)) { return _col.formatter.call(that); } else { return GRID.formatter[_col.formatter].call(that); } } else { return value; } } else { return "&nbsp;"; } } }; const repaint = function (_reset) { // debugger; let cfg = this.config, list = (this.proxyList) ? this.proxyList : this.list; /// repaint reset 타입이면 고정컬럼을 재조정 if (_reset) { resetFrozenColumn.call(this); // 틀고정 이 변경되면 출력 시작 인덱스 값을 초기화 this.xvar.paintStartRowIndex = undefined; this.xvar.paintStartColumnIndex = undefined; } /// 출력시작 인덱스 let paintStartRowIndex, virtualPaintStartRowIndex; if (this.config.virtualScrollY) { virtualPaintStartRowIndex = paintStartRowIndex = Math.floor(-(this.$.panel["body-scroll"].position().top) / this.xvar.bodyTrHeight) + this.xvar.frozenRowIndex; if (this.xvar.paintRowCountTopMargin < paintStartRowIndex) { paintStartRowIndex -= this.xvar.paintRowCountTopMargin; } } else { paintStartRowIndex = this.xvar.frozenRowIndex; } if (isNaN(paintStartRowIndex)) return this; let paintStartColumnIndex = 0, paintEndColumnIndex = 0, nopaintLeftColumnsWidth = null, nopaintRightColumnsWidth = null; let bodyScrollLeft = -(this.$.panel["body-scroll"].position().left); if (this.config.virtualScrollX) { // 페인트 시작컬럼위치와 종료컬럼위치 구하기 for (let ci = this.xvar.frozenColumnIndex; ci < this.colGroup.length; ci++) { // bodyScrollLeft this.colGroup[ci]._sx = (ci == this.xvar.frozenColumnIndex) ? 0 : this.colGroup[ci - 1]._ex; this.colGroup[ci]._ex = this.colGroup[ci]._sx + this.colGroup[ci]._width; if (this.colGroup[ci]._sx <= bodyScrollLeft && this.colGroup[ci]._ex >= bodyScrollLeft) { paintStartColumnIndex = ci; } if (this.colGroup[ci]._sx <= (bodyScrollLeft + this.xvar.bodyWidth) && this.colGroup[ci]._ex >= (bodyScrollLeft + this.xvar.bodyWidth)) { paintEndColumnIndex = ci; if (nopaintLeftColumnsWidth === null) nopaintLeftColumnsWidth = this.colGroup[paintStartColumnIndex]._sx; if (nopaintRightColumnsWidth === null) nopaintRightColumnsWidth = this.xvar.scrollContentWidth - this.colGroup[ci]._ex; } } if (nopaintLeftColumnsWidth === null) nopaintLeftColumnsWidth = 0; if (nopaintRightColumnsWidth === null) nopaintRightColumnsWidth = 0; this.$.panel["top-body-scroll"].css({"padding-left": nopaintLeftColumnsWidth, "padding-right": nopaintRightColumnsWidth}); this.$.panel["body-scroll"].css({"padding-left": nopaintLeftColumnsWidth, "padding-right": nopaintRightColumnsWidth}); this.$.panel["bottom-body-scroll"].css({"padding-left": nopaintLeftColumnsWidth, "padding-right": nopaintRightColumnsWidth}); } let isFirstPaint = (typeof this.xvar.paintStartRowIndex === "undefined"), headerColGroup = this.headerColGroup, asideBodyRowData = this.asideBodyRowData, leftBodyRowData = this.leftBodyRowData, bodyRowData = this.bodyRowData, leftFootSumData = this.leftFootSumData, footSumData = this.footSumData, asideBodyGroupingData = this.asideBodyGroupingData, leftBodyGroupingData = this.leftBodyGroupingData, bodyGroupingData = this.bodyGroupingData, bodyAlign = cfg.body.align, paintRowCount, virtualPaintRowCount; if (!this.config.virtualScrollY) { virtualPaintRowCount = paintRowCount = list.length; } else { virtualPaintRowCount = Math.ceil(this.xvar.bodyHeight / this.xvar.bodyTrHeight); paintRowCount = virtualPaintRowCount + (this.xvar.paintRowCountMargin || 1); } // 여유범위 안에 있으면 페인팅 안할수 있게 paintStartRowIndex 변경하지 않음. if (this.xvar.paintRowCountTopMargin < paintStartRowIndex && Math.abs(this.xvar.paintStartRowIndex - paintStartRowIndex) <= this.xvar.paintRowCountTopMargin) { paintStartRowIndex = this.xvar.paintStartRowIndex; } if ( this.xvar.dataRowCount === list.length && this.xvar.paintStartRowIndex === paintStartRowIndex && this.xvar.paintRowCount === paintRowCount && this.xvar.paintStartColumnIndex === paintStartColumnIndex && this.xvar.paintEndColumnIndex === paintEndColumnIndex ) return this; // 스크롤 포지션 변경 여부에 따라 프로세스 진행여부 결정 // bodyRowData 수정 : 페인트 컬럼 포지션이 달라지므로 if (nopaintLeftColumnsWidth || nopaintRightColumnsWidth) { headerColGroup = [].concat(headerColGroup).splice(paintStartColumnIndex - this.xvar.frozenColumnIndex, paintEndColumnIndex - paintStartColumnIndex + 1 + this.xvar.frozenColumnIndex); bodyRowData = GRID.util.getTableByStartEndColumnIndex(bodyRowData, paintStartColumnIndex, paintEndColumnIndex); if (cfg.body.grouping) { bodyGroupingData = GRID.util.getTableByStartEndColumnIndex(bodyGroupingData, paintStartColumnIndex, paintEndColumnIndex); } if (cfg.footSum) { footSumData = GRID.util.getTableByStartEndColumnIndex(footSumData, paintStartColumnIndex, paintEndColumnIndex); } if (this.xvar.paintStartColumnIndex !== paintStartColumnIndex || this.xvar.paintEndColumnIndex !== paintEndColumnIndex) { this.needToPaintSum = true; } } /// 스크롤 컨텐츠의 높이 : 그리드 스크롤의 실제 크기와는 관계 없이 데이터 갯수에 따라 스크롤 컨텐츠 높이값 구해서 저장해두기. // todo scrollContentHeight this.xvar.scrollContentHeight = this.xvar.bodyTrHeight * (list.length - this.xvar.frozenRowIndex); if (this.xvar.scrollContentHeight < 0) this.xvar.scrollContentHeight = 0; /// 사용된 패널들의 키 모음 this.$.livePanelKeys = []; // 그리드 바디 영역 페인트 함수 /** * @param _elTargetKey * @param _colGroup * @param _bodyRow * @param _groupRow * @param _list * @param [_scrollConfig] * @returns {boolean} */ let repaintBody = function (_elTargetKey, _colGroup, _bodyRow, _groupRow, _list, _scrollConfig) { let _elTarget = this.$.panel[_elTargetKey]; if (!isFirstPaint && !_scrollConfig) { this.$.livePanelKeys.push(_elTargetKey); // 사용중인 패널키를 모아둠. (뷰의 상태 변경시 사용하려고) return false; } let SS = [], cgi, cgl, di, dl, tri, trl, ci, cl, col, cellHeight, colAlign, isScrolled = (function () { // 스크롤값이 변경되거나 처음 호출되었습니까? if (typeof _scrollConfig === "undefined" || typeof _scrollConfig['paintStartRowIndex'] === "undefined") { _scrollConfig = { paintStartRowIndex: 0, paintRowCount: _list.length }; return false; } else { return true; } })(), stripeString = '#fff 0px, #fff ' + (cfg.body.columnHeight - cfg.body.columnBorderWidth) + 'px, #eee ' + (cfg.body.columnHeight - cfg.body.columnBorderWidth) + 'px, #eee ' + (cfg.body.columnHeight) + 'px'; if (isScrolled) { SS.push('<div style="background:repeating-linear-gradient(to top, ' + stripeString + ');' + 'font-size:0;' + 'line-height:0;height: ' + (_scrollConfig.paintStartRowIndex - this.xvar.frozenRowIndex) * _scrollConfig.bodyTrHeight + 'px;"></div>'); } SS.push('<table border="0" cellpadding="0" cellspacing="0">'); SS.push('<colgroup>'); for (cgi = 0, cgl = _colGroup.length; cgi < cgl; cgi++) { SS.push('<col style="width:' + _colGroup[cgi]._width + 'px;" />'); } SS.push('<col />'); SS.push('</colgroup>'); di = _scrollConfig.paintStartRowIndex; for (dl = (function () { let len; len = _list.length; if (_scrollConfig.paintRowCount + _scrollConfig.paintStartRowIndex < len) { len = _scrollConfig.paintRowCount + _scrollConfig.paintStartRowIndex; } return len; })(); di < dl; di++) { if (_list[di]) { let isGroupingRow = false, rowTable, odi = (typeof _list[di].__origin_index__ !== "undefined") ? _list[di].__origin_index__ : di; if (_groupRow && "__isGrouping" in _list[di]) { rowTable = _groupRow; isGroupingRow = true; } else { rowTable = _bodyRow; } for (tri = 0, trl = rowTable.rows.length; tri < trl; tri++) { SS.push('<tr class="tr-' + (di % 4) + '', (cfg.body.trStyleClass) ? (U.isFunction(cfg.body.trStyleClass)) ? ' ' + cfg.body.trStyleClass.call({ item: _list[di], index: di }, _list[di], di) : ' ' + cfg.body.trStyleClass : '', '"', (isGroupingRow) ? ' data-ax5grid-grouping-tr="true"' : '', ' data-ax5grid-tr-data-index="' + di + '"', ' data-ax5grid-tr-data-o-index="' + odi + '"', ' data-ax5grid-selected="' + (_list[di][cfg.columnKeys.selected] || "false") + '"', ' data-ax5grid-disable-selection="' + (_list[di][cfg.columnKeys.disableSelection] || "false") + '"', '>'); for (ci = 0, cl = rowTable.rows[tri].cols.length; ci < cl; ci++) { col = rowTable.rows[tri].cols[ci]; cellHeight = cfg.body.columnHeight * col.rowspan - cfg.body.columnBorderWidth; colAlign = col.align || bodyAlign; SS.push('<td ', 'data-ax5grid-panel-name="' + _elTargetKey + '" ', 'data-ax5grid-data-index="' + di + '" ', 'data-ax5grid-data-o-index="' + odi + '" ', 'data-ax5grid-column-row="' + tri + '" ', 'data-ax5grid-column-col="' + ci + '" ', 'data-ax5grid-column-rowIndex="' + col.rowIndex + '" ', 'data-ax5grid-column-colIndex="' + col.colIndex + '" ', 'data-ax5grid-column-attr="' + (col.columnAttr || "default") + '" ', (function (_focusedColumn, _selectedColumn) { let attrs = ""; if (_focusedColumn) { attrs += 'data-ax5grid-column-focused="true" '; } if (_selectedColumn) { attrs += 'data-ax5grid-column-selected="true" '; } return attrs; })(this.focusedColumn[di + "_" + col.colIndex + "_" + col.rowIndex], this.selectedColumn[di + "_" + col.colIndex + "_" + col.rowIndex]), 'colspan="' + col.colspan + '" ', 'rowspan="' + col.rowspan + '" ', 'class="' + (function (_col) { let tdCSS_class = ""; if (_col.styleClass) { if (U.isFunction(_col.styleClass)) { tdCSS_class += _col.styleClass.call({ column: _col, key: _col.key, item: _list[di], index: di }) + " "; } else { tdCSS_class += _col.styleClass + " "; } }