ax5ui-grid
Version:
A grid plugin that works with Bootstrap & jQuery
1,105 lines (975 loc) • 138 kB
JavaScript
// 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: " ", 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: " ", 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 = {
'<': '<',
'>': '>'
};
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;"' +
'> </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 " ";
}
}
};
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 ' ';
}
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 " ";
}
}
};
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 + " ";
}
}