ninegrid2 6.315.0 → 6.317.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai/aiMessage.js +5 -23
- package/dist/bundle.cjs.js +1050 -1050
- package/dist/bundle.esm.js +1050 -1050
- package/dist/etc/ninegridContainer.js +2 -1
- package/dist/index.js +3 -1
- package/dist/utils/ninegrid.js +12 -0
- package/package.json +1 -1
- package/src/ai/aiMessage.js +5 -23
- package/src/etc/ninegridContainer.js +2 -1
- package/src/index.js +3 -1
- package/src/utils/ngFiltering.js +392 -0
- package/src/utils/ninegrid.js +12 -0
- package/src/etc/ngFiltering.js.bak +0 -532
- /package/{src/etc → dist/utils}/ngFiltering.js +0 -0
package/dist/bundle.cjs.js
CHANGED
|
@@ -11036,6 +11036,18 @@ class ninegrid {
|
|
|
11036
11036
|
static nvl = (v, v2) => {
|
|
11037
11037
|
return ninegrid.isNvl(v) ? v2 : v;
|
|
11038
11038
|
};
|
|
11039
|
+
|
|
11040
|
+
static isEllipsis = (element) => {
|
|
11041
|
+
const clone = element.cloneNode(true);
|
|
11042
|
+
clone.style.width = "auto";
|
|
11043
|
+
clone.style.visibility = "hidden";
|
|
11044
|
+
document.body.appendChild(clone);
|
|
11045
|
+
|
|
11046
|
+
const isTruncated = clone.scrollWidth > element.clientWidth;
|
|
11047
|
+
document.body.removeChild(clone);
|
|
11048
|
+
|
|
11049
|
+
return isTruncated;
|
|
11050
|
+
}
|
|
11039
11051
|
|
|
11040
11052
|
static oppositeColor = (bgColor, lightColor, darkColor) => {
|
|
11041
11053
|
var color = (bgColor.charAt(0) === '#') ? bgColor.substring(1, 7) : bgColor;
|
|
@@ -17824,581 +17836,190 @@ class ngFields
|
|
|
17824
17836
|
};
|
|
17825
17837
|
}
|
|
17826
17838
|
|
|
17827
|
-
|
|
17828
|
-
* button.filterOptions = [{
|
|
17829
|
-
* colnm: "userId",
|
|
17830
|
-
* data: [],
|
|
17831
|
-
* }]
|
|
17832
|
-
* button.
|
|
17833
|
-
*/
|
|
17834
|
-
class ngFiltering
|
|
17839
|
+
class ngFoot extends HTMLElement
|
|
17835
17840
|
{
|
|
17836
17841
|
#owner;
|
|
17837
|
-
#isFiltering;
|
|
17838
|
-
|
|
17839
|
-
constructor(owner) {
|
|
17840
|
-
this.#owner = owner;
|
|
17841
|
-
this.#isFiltering = false;
|
|
17842
|
-
|
|
17843
|
-
const filterPanel = document.createElement("ng-filter-panel"); // ✅ 필터 패널 생성
|
|
17844
|
-
filterPanel.style.display = "none"; // ✅ 숨김 처리
|
|
17845
|
-
this.#owner.shadowRoot.appendChild(filterPanel); // ✅ Shadow DOM 내부에 추가
|
|
17846
|
-
}
|
|
17847
|
-
|
|
17848
|
-
initialize = () => {
|
|
17849
|
-
/**
|
|
17850
|
-
* 1. grid attr == filter : on();
|
|
17851
|
-
*/
|
|
17852
|
-
this.#isFiltering = false;
|
|
17853
|
-
this.#owner.data.clearFilter();
|
|
17854
|
-
};
|
|
17855
|
-
|
|
17856
|
-
isFiltering = () => {
|
|
17857
|
-
return this.#isFiltering;
|
|
17858
|
-
};
|
|
17859
17842
|
|
|
17860
|
-
|
|
17843
|
+
constructor () {
|
|
17844
|
+
super();
|
|
17861
17845
|
|
|
17862
|
-
this
|
|
17863
|
-
const lastRowIndex = this.#getLastRowIndex();
|
|
17864
|
-
|
|
17865
|
-
this.#owner.body.querySelectorAll(".ng-table thead th, .ng-table thead td").forEach((td) => {
|
|
17866
|
-
const rowIndex = td.closest("tr")?.sectionRowIndex;
|
|
17867
|
-
if (rowIndex !== undefined && rowIndex + td.rowSpan - 1 === lastRowIndex) {
|
|
17868
|
-
const options = Array.from(this.#owner.activeTmpl.querySelectorAll(`[data-col="${td.dataset.col}"]`))
|
|
17869
|
-
.map(el => el.dataset.bind ? { colnm: el.dataset.bind, data: [] } : null)
|
|
17870
|
-
.filter(Boolean); // ✅ `null` 제거
|
|
17871
|
-
|
|
17872
|
-
if (options.length > 0) {
|
|
17873
|
-
td.querySelector("ng-filter-button")?.remove();
|
|
17874
|
-
|
|
17875
|
-
const filterButton = document.createElement("ng-filter-button");
|
|
17876
|
-
td.appendChild(filterButton);
|
|
17877
|
-
filterButton.filterOptions = options;
|
|
17878
|
-
}
|
|
17879
|
-
}
|
|
17880
|
-
});
|
|
17881
|
-
};
|
|
17882
|
-
|
|
17883
|
-
off = () => {
|
|
17884
|
-
this.#isFiltering = false;
|
|
17885
|
-
|
|
17886
|
-
this.#owner.body.querySelectorAll(".ng-table ng-filter-button").forEach((el) => {
|
|
17887
|
-
el.remove(); // ✅ 요소 삭제
|
|
17888
|
-
});
|
|
17889
|
-
};
|
|
17890
|
-
|
|
17891
|
-
/**
|
|
17892
|
-
clear = () => {
|
|
17893
|
-
console.log(this.#owner.dataManager.rawRecords);
|
|
17894
|
-
this.#owner.dataManager.rawRecords.map(item => { item.__ng.filtered = false; });
|
|
17895
|
-
|
|
17896
|
-
|
|
17897
|
-
this.#records = this.#owner.dataManager.rawRecords.filter(item => { return !item.__ng.deleted && !item.__ng.filtered; } );
|
|
17898
|
-
return this.#records;
|
|
17846
|
+
this.attachShadow({ mode: 'open' });
|
|
17899
17847
|
}
|
|
17900
17848
|
|
|
17901
|
-
|
|
17902
|
-
this.#records = this.#owner.dataManager.rawRecords.filter(item => { return !item.__ng.deleted && !item.__ng.filtered; } );
|
|
17903
|
-
//this.#records.forEach((o,i) => { o.__ng.rowidx = i; });
|
|
17904
|
-
//this.getValidData().forEach((o,i) => { o.__ng._[ninegrid.ROW.ORDER] = i + 1; });
|
|
17905
|
-
this.#resetOrder();
|
|
17906
|
-
return this.#records;
|
|
17907
|
-
} */
|
|
17908
|
-
|
|
17909
|
-
|
|
17910
|
-
/**
|
|
17911
|
-
* oFilter : {
|
|
17912
|
-
* col1 : [],
|
|
17913
|
-
* col2 : []
|
|
17914
|
-
* }
|
|
17915
|
-
*/
|
|
17916
|
-
set = (oFilter) => {
|
|
17917
|
-
|
|
17918
|
-
this.on();
|
|
17919
|
-
|
|
17920
|
-
// ✅ JSON 변환 (배열 → 객체)
|
|
17921
|
-
let jsonFilter = Array.isArray(oFilter)
|
|
17922
|
-
? Object.fromEntries(Object.keys(oFilter[0]).map(key => [key, [...new Set(oFilter.map(item => item[key]))]]))
|
|
17923
|
-
: oFilter;
|
|
17924
|
-
|
|
17925
|
-
this.#owner.data.clearFilter();
|
|
17926
|
-
|
|
17927
|
-
Object.entries(jsonFilter).forEach(([key, arr]) => {
|
|
17928
|
-
const idx = this.#owner.fields.indexOf(key);
|
|
17929
|
-
|
|
17930
|
-
// ✅ 숫자 판별 및 변환
|
|
17931
|
-
if (this.#owner.data.getValidData().some(o => typeof o.v[idx] === "number")) {
|
|
17932
|
-
arr = arr.map(Number);
|
|
17933
|
-
}
|
|
17934
|
-
|
|
17935
|
-
// ✅ 필터 적용
|
|
17936
|
-
this.#owner.data.getValidData()
|
|
17937
|
-
.filter(m => arr.nineBinarySearch(m.v[idx] || '') < 0)
|
|
17938
|
-
.forEach(m => { m.__ng.filtered = true; });
|
|
17939
|
-
});
|
|
17940
|
-
|
|
17941
|
-
|
|
17942
|
-
this.#owner.data.refreshFilter();
|
|
17943
|
-
|
|
17944
|
-
// ✅ 필터 버튼 초기화
|
|
17945
|
-
this.#owner.shadowRoot.querySelectorAll("ng-filter-button").forEach(el => {
|
|
17946
|
-
el.filterOptions.forEach(opt => { opt.data = []; });
|
|
17947
|
-
});
|
|
17948
|
-
|
|
17949
|
-
Object.entries(jsonFilter).forEach(([key, arr]) => {
|
|
17950
|
-
this.#owner.shadowRoot.querySelectorAll("ng-filter-button").forEach(el => {
|
|
17951
|
-
|
|
17952
|
-
let options = el.filterOptions;
|
|
17953
|
-
|
|
17954
|
-
options.forEach(opt => {
|
|
17955
|
-
if (opt.colnm === key) opt.data = arr;
|
|
17956
|
-
});
|
|
17957
|
-
|
|
17958
|
-
el.filterOptions = options;
|
|
17959
|
-
});
|
|
17960
|
-
});
|
|
17849
|
+
connectedCallback() {
|
|
17961
17850
|
|
|
17851
|
+
this.#owner = this.getRootNode().host;//this.closest("nine-grid");
|
|
17962
17852
|
|
|
17963
|
-
this
|
|
17853
|
+
this.shadowRoot.innerHTML = `
|
|
17854
|
+
<style>
|
|
17855
|
+
@import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/ngFoot.css";
|
|
17856
|
+
${ninegrid.getCustomPath(this,"ngFoot.css")}
|
|
17857
|
+
</style>
|
|
17858
|
+
|
|
17859
|
+
<ng-layout></ng-layout>
|
|
17860
|
+
<ng-paging></ng-paging>
|
|
17861
|
+
`;
|
|
17964
17862
|
|
|
17965
|
-
this.#owner.paging.reset();
|
|
17966
17863
|
};
|
|
17967
|
-
|
|
17968
|
-
#getLastRowIndex = (v = "thead") =>
|
|
17969
|
-
[...this.#owner.body.querySelectorAll(`.ng-table ${v}`)]
|
|
17970
|
-
.reduce((maxIndex, el) => Math.max(el.rows.length - 1, maxIndex), 0);
|
|
17971
|
-
|
|
17972
17864
|
}
|
|
17973
17865
|
|
|
17974
|
-
class
|
|
17866
|
+
class ngLayout extends HTMLElement
|
|
17975
17867
|
{
|
|
17976
17868
|
#owner;
|
|
17977
|
-
#
|
|
17869
|
+
#tables;
|
|
17870
|
+
#wrap;
|
|
17871
|
+
#at;
|
|
17978
17872
|
|
|
17979
17873
|
constructor () {
|
|
17980
17874
|
super();
|
|
17875
|
+
|
|
17876
|
+
this.#tables = [];
|
|
17877
|
+
this.#at = 0;
|
|
17981
17878
|
}
|
|
17982
|
-
|
|
17879
|
+
|
|
17983
17880
|
connectedCallback() {
|
|
17984
|
-
this.#owner = this.getRootNode().host;//this.closest("nine-grid");
|
|
17881
|
+
this.#owner = this.getRootNode().host.getRootNode().host;//this.closest("nine-grid");
|
|
17882
|
+
|
|
17883
|
+
this.innerHTML =`<div class="ng-wrap"></div>`;
|
|
17884
|
+
this.#wrap = this.querySelector(".ng-wrap");
|
|
17885
|
+
};
|
|
17886
|
+
|
|
17887
|
+
add = (arr) => {
|
|
17985
17888
|
|
|
17986
|
-
this.
|
|
17987
|
-
|
|
17889
|
+
this.#tables.push(...arr);
|
|
17890
|
+
|
|
17891
|
+
var i = 0;
|
|
17892
|
+
for (const tbl of this.#tables) {
|
|
17893
|
+
i++;
|
|
17894
|
+
const caption = tbl.querySelector("caption");
|
|
17895
|
+
const sheetName = caption ? caption.innerHTML : `Sheet${i}`;
|
|
17896
|
+
|
|
17897
|
+
$(this.#wrap).append(`<button class="ng-button" value="${i-1}" title="${sheetName.replaceAll('"', "'")}">${sheetName}</button>`);
|
|
17898
|
+
}
|
|
17899
|
+
|
|
17900
|
+
if (this.#tables.length <= 1) $(this.#wrap).hide();
|
|
17901
|
+
|
|
17902
|
+
//$("button", this.#wrap).eq(0).addClass("ng-active");
|
|
17903
|
+
ninegrid.j.querySelectorAll(this.#wrap.querySelector("button")).addClass("ng-active");
|
|
17904
|
+
|
|
17905
|
+
$("button", this.#wrap).on("click", this.#onClick);
|
|
17988
17906
|
};
|
|
17989
17907
|
|
|
17990
|
-
get
|
|
17991
|
-
return this.#
|
|
17908
|
+
get tables() {
|
|
17909
|
+
return this.#tables;
|
|
17910
|
+
};
|
|
17911
|
+
get currentTable() {
|
|
17912
|
+
return this.#tables[this.#at];
|
|
17992
17913
|
};
|
|
17993
|
-
set filterOptions(v) {
|
|
17994
|
-
this.#filterOptions = v;
|
|
17995
|
-
this.classList.toggle('filtered', this.#filterOptions.some(item => item.data.length > 0));
|
|
17996
|
-
}
|
|
17997
17914
|
|
|
17998
|
-
|
|
17999
|
-
|
|
18000
|
-
e.stopPropagation();
|
|
18001
|
-
|
|
18002
|
-
const panel = this.#owner.shadowRoot.querySelector("ng-filter-panel");
|
|
18003
|
-
const col = this.closest("th,td")?.dataset.col; // ✅ `?.` 활용하여 안전한 접근
|
|
18004
|
-
|
|
18005
|
-
panel.col === col ? panel.close() : panel.open(this);
|
|
18006
|
-
};
|
|
18007
|
-
}
|
|
17915
|
+
resize = () => {
|
|
17916
|
+
const overflow = $(this.#wrap).width() > $(this).width();
|
|
18008
17917
|
|
|
18009
|
-
|
|
18010
|
-
|
|
18011
|
-
|
|
18012
|
-
|
|
18013
|
-
|
|
17918
|
+
$(this.#wrap).css({
|
|
17919
|
+
"width": overflow ? "100%" : "unset",
|
|
17920
|
+
"justify-content": overflow ? "space-evenly" : "unset",
|
|
17921
|
+
});
|
|
17922
|
+
};
|
|
18014
17923
|
|
|
18015
|
-
|
|
18016
|
-
|
|
18017
|
-
|
|
18018
|
-
|
|
18019
|
-
|
|
18020
|
-
|
|
18021
|
-
|
|
18022
|
-
|
|
17924
|
+
#onClick = e => {
|
|
17925
|
+
|
|
17926
|
+
if (ninegrid.j.querySelectorAll(e.currentTarget).hasClass("ng-active")) return;
|
|
17927
|
+
|
|
17928
|
+
const oldIndex = this.#at;
|
|
17929
|
+
|
|
17930
|
+
this.#at = parseInt(e.currentTarget.value);
|
|
17931
|
+
|
|
17932
|
+
this.#owner.changeRayout(this.#at);
|
|
17933
|
+
|
|
17934
|
+
ninegrid.j.querySelectorAll("button", this.#wrap).removeClass("ng-active");
|
|
17935
|
+
ninegrid.j.querySelectorAll(e.currentTarget).addClass("ng-active");
|
|
17936
|
+
|
|
17937
|
+
var customEvent = new CustomEvent(ninegrid.EVENT.LAYOUT_CHANGED, { bubbles: true, detail: {} });
|
|
17938
|
+
customEvent.oldIndex = oldIndex;
|
|
17939
|
+
customEvent.newIndex = this.#at;
|
|
17940
|
+
|
|
17941
|
+
this.#owner.dispatchEvent(customEvent);
|
|
17942
|
+
};
|
|
17943
|
+
}
|
|
18023
17944
|
|
|
18024
|
-
|
|
17945
|
+
customElements.define("ng-layout", ngLayout);
|
|
17946
|
+
customElements.define("ng-foot", ngFoot);
|
|
18025
17947
|
|
|
18026
|
-
|
|
18027
|
-
|
|
18028
|
-
|
|
18029
|
-
|
|
18030
|
-
|
|
18031
|
-
|
|
18032
|
-
|
|
18033
|
-
|
|
18034
|
-
|
|
18035
|
-
|
|
18036
|
-
|
|
18037
|
-
|
|
18038
|
-
|
|
18039
|
-
|
|
18040
|
-
|
|
18041
|
-
|
|
18042
|
-
|
|
18043
|
-
|
|
18044
|
-
|
|
18045
|
-
|
|
18046
|
-
|
|
18047
|
-
|
|
18048
|
-
|
|
18049
|
-
|
|
18050
|
-
|
|
18051
|
-
|
|
18052
|
-
|
|
18053
|
-
|
|
18054
|
-
|
|
18055
|
-
|
|
18056
|
-
|
|
18057
|
-
|
|
18058
|
-
|
|
18059
|
-
|
|
18060
|
-
|
|
18061
|
-
|
|
18062
|
-
|
|
18063
|
-
|
|
18064
|
-
this.
|
|
18065
|
-
|
|
18066
|
-
|
|
18067
|
-
|
|
18068
|
-
|
|
18069
|
-
|
|
18070
|
-
|
|
18071
|
-
|
|
18072
|
-
|
|
18073
|
-
|
|
18074
|
-
|
|
18075
|
-
|
|
18076
|
-
|
|
18077
|
-
|
|
18078
|
-
|
|
18079
|
-
|
|
18080
|
-
|
|
18081
|
-
|
|
18082
|
-
|
|
18083
|
-
|
|
18084
|
-
|
|
18085
|
-
|
|
18086
|
-
|
|
18087
|
-
|
|
18088
|
-
|
|
18089
|
-
|
|
18090
|
-
|
|
18091
|
-
|
|
18092
|
-
|
|
18093
|
-
|
|
18094
|
-
|
|
18095
|
-
|
|
18096
|
-
|
|
18097
|
-
|
|
18098
|
-
|
|
18099
|
-
|
|
18100
|
-
|
|
18101
|
-
this.style.display = 'none';
|
|
18102
|
-
};
|
|
18103
|
-
|
|
18104
|
-
#onSelectAll = (e) => {
|
|
18105
|
-
const grd = this.shadowRoot.querySelector("nine-grid");
|
|
18106
|
-
const idx = grd.fields.indexOf("CHK");
|
|
18107
|
-
const isChecked = e.target.checked; // ✅ jQuery 없이 `checked` 값 가져오기
|
|
18108
|
-
|
|
18109
|
-
grd.data.getValidData().forEach(m => {
|
|
18110
|
-
m.v[idx] = isChecked ? "Y" : "N"; // ✅ `Y` 또는 `N` 값 설정
|
|
18111
|
-
});
|
|
18112
|
-
|
|
18113
|
-
grd.refreshData();
|
|
18114
|
-
};
|
|
18115
|
-
|
|
18116
|
-
|
|
18117
|
-
|
|
18118
|
-
#onInput = (e) => {
|
|
18119
|
-
const grd = this.shadowRoot.querySelector("nine-grid");
|
|
18120
|
-
|
|
18121
|
-
grd.classList.add("loading");
|
|
18122
|
-
|
|
18123
|
-
const data = grd.dataManager.rawRecords;
|
|
18124
|
-
data.forEach(m => { m.__ng.filtered = false; });
|
|
18125
|
-
|
|
18126
|
-
const v = e.target.value.toLowerCase(); // ✅ jQuery 없이 값 가져오기
|
|
18127
|
-
const [LVL_IDX, DATA_IDX] = ["LVL", "DATA"].map(field => grd.fields.indexOf(field));
|
|
18128
|
-
|
|
18129
|
-
data.forEach(m => {
|
|
18130
|
-
m.__ng.filtered = m.v[LVL_IDX] === 2 && !String(m.v[DATA_IDX] || "").toLowerCase().includes(v);
|
|
18131
|
-
});
|
|
18132
|
-
|
|
18133
|
-
grd.data.resetRecords();
|
|
18134
|
-
|
|
18135
|
-
clearTimeout(this.#timer);
|
|
18136
|
-
this.#timer = setTimeout(() => {
|
|
18137
|
-
grd.dataManager.viewRecords.reset();
|
|
18138
|
-
grd.dataManager.viewRecords.touch();
|
|
18139
|
-
}, 200);
|
|
18140
|
-
};
|
|
18141
|
-
|
|
18142
|
-
close = () => {
|
|
18143
|
-
this.col = null;
|
|
18144
|
-
this.style.display = 'none';
|
|
18145
|
-
};
|
|
18146
|
-
|
|
18147
|
-
open = (filterButton) => {
|
|
18148
|
-
|
|
18149
|
-
/** 위치 */
|
|
18150
|
-
const cell = filterButton.closest("th,td");
|
|
18151
|
-
|
|
18152
|
-
const { left: btnLeft } = filterButton.getBoundingClientRect();
|
|
18153
|
-
const { left: ownerLeft, width: ownerWidth, top: ownerTop } = this.#owner.getBoundingClientRect();
|
|
18154
|
-
const { top: cellTop, height: cellHeight } = cell.getBoundingClientRect();
|
|
18155
|
-
const { width: targetWidth } = this.getBoundingClientRect();
|
|
18156
|
-
|
|
18157
|
-
let l = Math.max(0, btnLeft - ownerLeft);
|
|
18158
|
-
l = Math.min(l, ownerWidth - targetWidth - 5);
|
|
18159
|
-
|
|
18160
|
-
const t = cellTop + cellHeight - ownerTop;
|
|
18161
|
-
|
|
18162
|
-
Object.assign(this.style, { left: `${l}px`, top: `${t}px`, display: "flex" });
|
|
18163
|
-
this.classList.add("loading");
|
|
18164
|
-
|
|
18165
|
-
this.shadowRoot.querySelector("input[type=text]").value = "";
|
|
18166
|
-
|
|
18167
|
-
setTimeout(() => {
|
|
18168
|
-
const data = this.#owner.data.getValidDataNF();
|
|
18169
|
-
const col = cell.dataset.col;
|
|
18170
|
-
this.col = col;
|
|
18171
|
-
this.#button = filterButton;
|
|
18172
|
-
|
|
18173
|
-
const ds = filterButton.filterOptions.map((opt, i) => {
|
|
18174
|
-
const groupLabel = `<span class="group">${cell.textContent}${filterButton.filterOptions.length > 1 ? ` #${i + 1} (${opt.colnm})` : ""}</span>`;
|
|
18175
|
-
|
|
18176
|
-
const cellEl = this.#owner.activeTmpl.querySelector(`[data-col="${col}"][data-bind="${opt.colnm}"]`);
|
|
18177
|
-
const expr = cellEl?.getAttribute("data-expr");
|
|
18178
|
-
const exprFunc = expr ? this.#owner.exprFunction(expr) : null;
|
|
18179
|
-
|
|
18180
|
-
const data2 = data.map(rowData => {
|
|
18181
|
-
const idx = this.#owner.fields.indexOf(opt.colnm);
|
|
18182
|
-
return expr ? { v: rowData.v[idx], v2: exprFunc(this.#owner.data.conv(rowData), rowData.__ng.rowidx, this.#owner.data) } : { v: rowData.v[idx], v2: rowData.v[idx] };
|
|
18183
|
-
});
|
|
18184
|
-
|
|
18185
|
-
return [
|
|
18186
|
-
{ LVL: 1, CHK: "N", DATA2: groupLabel },
|
|
18187
|
-
...[...new Set(data2.map(JSON.stringify))]
|
|
18188
|
-
.map(JSON.parse)
|
|
18189
|
-
.sort((a, b) => (a.v2 || "") > (b.v2 || "") ? 1 : (a.v2 || "") < (b.v2 || "") ? -1 : 0)
|
|
18190
|
-
.map(o => ({
|
|
18191
|
-
LVL: 2,
|
|
18192
|
-
DATA: o.v,
|
|
18193
|
-
DATA2: o.v2 || ` <span class="empty">(empty)</span> ${o.v}`,
|
|
18194
|
-
COLNM: opt.colnm,
|
|
18195
|
-
CHK: opt.data.length === 0 || opt.data.nineBinarySearch(o.v || "") >= 0 ? "Y" : "N",
|
|
18196
|
-
}))
|
|
18197
|
-
];
|
|
18198
|
-
}).flat();
|
|
18199
|
-
|
|
18200
|
-
const grd = this.shadowRoot.querySelector("nine-grid");
|
|
18201
|
-
grd.fields.add(["DATA","DATA2","COLNM"]);
|
|
18202
|
-
grd.data.set(ds);
|
|
18203
|
-
|
|
18204
|
-
// ✅ 데이터 필터링 및 체크 상태 결정
|
|
18205
|
-
const checkbox = this.shadowRoot.querySelector("input[type=checkbox]");
|
|
18206
|
-
checkbox.checked = grd.data.getValidData().every(item => !(item.LVL === 2 && item.CHK !== "Y"));
|
|
18207
|
-
|
|
18208
|
-
this.shadowRoot.querySelector("input").focus();
|
|
18209
|
-
this.classList.remove("loading");
|
|
18210
|
-
});
|
|
18211
|
-
};
|
|
18212
|
-
}
|
|
18213
|
-
|
|
18214
|
-
|
|
18215
|
-
customElements.define("ng-filter-button", ngFilterButton);
|
|
18216
|
-
customElements.define("ng-filter-panel", ngFilterPanel);
|
|
18217
|
-
|
|
18218
|
-
class ngFoot extends HTMLElement
|
|
18219
|
-
{
|
|
18220
|
-
#owner;
|
|
18221
|
-
|
|
18222
|
-
constructor () {
|
|
18223
|
-
super();
|
|
18224
|
-
|
|
18225
|
-
this.attachShadow({ mode: 'open' });
|
|
18226
|
-
}
|
|
18227
|
-
|
|
18228
|
-
connectedCallback() {
|
|
18229
|
-
|
|
18230
|
-
this.#owner = this.getRootNode().host;//this.closest("nine-grid");
|
|
18231
|
-
|
|
18232
|
-
this.shadowRoot.innerHTML = `
|
|
18233
|
-
<style>
|
|
18234
|
-
@import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/ngFoot.css";
|
|
18235
|
-
${ninegrid.getCustomPath(this,"ngFoot.css")}
|
|
18236
|
-
</style>
|
|
18237
|
-
|
|
18238
|
-
<ng-layout></ng-layout>
|
|
18239
|
-
<ng-paging></ng-paging>
|
|
18240
|
-
`;
|
|
18241
|
-
|
|
18242
|
-
};
|
|
18243
|
-
}
|
|
18244
|
-
|
|
18245
|
-
class ngLayout extends HTMLElement
|
|
18246
|
-
{
|
|
18247
|
-
#owner;
|
|
18248
|
-
#tables;
|
|
18249
|
-
#wrap;
|
|
18250
|
-
#at;
|
|
18251
|
-
|
|
18252
|
-
constructor () {
|
|
18253
|
-
super();
|
|
18254
|
-
|
|
18255
|
-
this.#tables = [];
|
|
18256
|
-
this.#at = 0;
|
|
18257
|
-
}
|
|
18258
|
-
|
|
18259
|
-
connectedCallback() {
|
|
18260
|
-
this.#owner = this.getRootNode().host.getRootNode().host;//this.closest("nine-grid");
|
|
18261
|
-
|
|
18262
|
-
this.innerHTML =`<div class="ng-wrap"></div>`;
|
|
18263
|
-
this.#wrap = this.querySelector(".ng-wrap");
|
|
18264
|
-
};
|
|
18265
|
-
|
|
18266
|
-
add = (arr) => {
|
|
18267
|
-
|
|
18268
|
-
this.#tables.push(...arr);
|
|
18269
|
-
|
|
18270
|
-
var i = 0;
|
|
18271
|
-
for (const tbl of this.#tables) {
|
|
18272
|
-
i++;
|
|
18273
|
-
const caption = tbl.querySelector("caption");
|
|
18274
|
-
const sheetName = caption ? caption.innerHTML : `Sheet${i}`;
|
|
18275
|
-
|
|
18276
|
-
$(this.#wrap).append(`<button class="ng-button" value="${i-1}" title="${sheetName.replaceAll('"', "'")}">${sheetName}</button>`);
|
|
18277
|
-
}
|
|
18278
|
-
|
|
18279
|
-
if (this.#tables.length <= 1) $(this.#wrap).hide();
|
|
18280
|
-
|
|
18281
|
-
//$("button", this.#wrap).eq(0).addClass("ng-active");
|
|
18282
|
-
ninegrid.j.querySelectorAll(this.#wrap.querySelector("button")).addClass("ng-active");
|
|
18283
|
-
|
|
18284
|
-
$("button", this.#wrap).on("click", this.#onClick);
|
|
18285
|
-
};
|
|
18286
|
-
|
|
18287
|
-
get tables() {
|
|
18288
|
-
return this.#tables;
|
|
18289
|
-
};
|
|
18290
|
-
get currentTable() {
|
|
18291
|
-
return this.#tables[this.#at];
|
|
18292
|
-
};
|
|
18293
|
-
|
|
18294
|
-
resize = () => {
|
|
18295
|
-
const overflow = $(this.#wrap).width() > $(this).width();
|
|
18296
|
-
|
|
18297
|
-
$(this.#wrap).css({
|
|
18298
|
-
"width": overflow ? "100%" : "unset",
|
|
18299
|
-
"justify-content": overflow ? "space-evenly" : "unset",
|
|
18300
|
-
});
|
|
18301
|
-
};
|
|
18302
|
-
|
|
18303
|
-
#onClick = e => {
|
|
18304
|
-
|
|
18305
|
-
if (ninegrid.j.querySelectorAll(e.currentTarget).hasClass("ng-active")) return;
|
|
18306
|
-
|
|
18307
|
-
const oldIndex = this.#at;
|
|
18308
|
-
|
|
18309
|
-
this.#at = parseInt(e.currentTarget.value);
|
|
18310
|
-
|
|
18311
|
-
this.#owner.changeRayout(this.#at);
|
|
18312
|
-
|
|
18313
|
-
ninegrid.j.querySelectorAll("button", this.#wrap).removeClass("ng-active");
|
|
18314
|
-
ninegrid.j.querySelectorAll(e.currentTarget).addClass("ng-active");
|
|
18315
|
-
|
|
18316
|
-
var customEvent = new CustomEvent(ninegrid.EVENT.LAYOUT_CHANGED, { bubbles: true, detail: {} });
|
|
18317
|
-
customEvent.oldIndex = oldIndex;
|
|
18318
|
-
customEvent.newIndex = this.#at;
|
|
18319
|
-
|
|
18320
|
-
this.#owner.dispatchEvent(customEvent);
|
|
18321
|
-
};
|
|
18322
|
-
}
|
|
18323
|
-
|
|
18324
|
-
customElements.define("ng-layout", ngLayout);
|
|
18325
|
-
customElements.define("ng-foot", ngFoot);
|
|
18326
|
-
|
|
18327
|
-
class ngHead extends HTMLElement
|
|
18328
|
-
{
|
|
18329
|
-
#owner;
|
|
18330
|
-
|
|
18331
|
-
constructor () {
|
|
18332
|
-
super();
|
|
18333
|
-
|
|
18334
|
-
this.attachShadow({ mode: 'open' });
|
|
18335
|
-
}
|
|
18336
|
-
|
|
18337
|
-
connectedCallback() {
|
|
18338
|
-
|
|
18339
|
-
this.#owner = this.getRootNode().host;
|
|
18340
|
-
|
|
18341
|
-
if (ninegrid.j.querySelectorAll(this.#owner).hasClass("simple")) return;
|
|
18342
|
-
|
|
18343
|
-
this.shadowRoot.innerHTML = `
|
|
18344
|
-
<style>
|
|
18345
|
-
@import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/ngHead.css";
|
|
18346
|
-
${ninegrid.getCustomPath(this,"ngHead.css")}
|
|
18347
|
-
</style>
|
|
18348
|
-
|
|
18349
|
-
<ng-menu></ng-menu>
|
|
18350
|
-
<ng-title></ng-title>
|
|
18351
|
-
<ng-custom></ng-custom>
|
|
18352
|
-
`;
|
|
18353
|
-
};
|
|
18354
|
-
}
|
|
18355
|
-
|
|
18356
|
-
class ngTitle extends HTMLElement
|
|
18357
|
-
{
|
|
18358
|
-
#owner;
|
|
18359
|
-
|
|
18360
|
-
constructor () {
|
|
18361
|
-
super();
|
|
18362
|
-
}
|
|
18363
|
-
|
|
18364
|
-
connectedCallback() {
|
|
18365
|
-
if (!this.getRootNode().host) return;
|
|
18366
|
-
|
|
18367
|
-
this.#owner = this.getRootNode().host.getRootNode().host;
|
|
18368
|
-
|
|
18369
|
-
this.innerHTML = `<span>${this.#owner.getAttribute("caption")}</span>`;
|
|
18370
|
-
|
|
18371
|
-
$("span", this).on("dblclick", e => {
|
|
18372
|
-
const link = '<font color="green">https://www.ninegrid.net</font>';
|
|
18373
|
-
e.currentTarget.innerHTML = e.currentTarget.innerHTML == link ? `<span>${this.#owner.getAttribute("caption")}</span>` : link;
|
|
18374
|
-
});
|
|
18375
|
-
};
|
|
18376
|
-
}
|
|
18377
|
-
|
|
18378
|
-
class ngCustom extends HTMLElement
|
|
18379
|
-
{
|
|
18380
|
-
#owner;
|
|
18381
|
-
|
|
18382
|
-
constructor () {
|
|
18383
|
-
super();
|
|
18384
|
-
}
|
|
18385
|
-
|
|
18386
|
-
connectedCallback() {
|
|
18387
|
-
if (!this.getRootNode().host) return;
|
|
18388
|
-
|
|
18389
|
-
this.#owner = this.getRootNode().host.getRootNode().host;
|
|
18390
|
-
|
|
18391
|
-
this.innerHTML = `<div></div>`;
|
|
18392
|
-
};
|
|
18393
|
-
|
|
18394
|
-
add = (element) => {
|
|
18395
|
-
this.querySelector("div:first-child").append(element);
|
|
18396
|
-
};
|
|
18397
|
-
}
|
|
18398
|
-
|
|
18399
|
-
customElements.define("ng-title", ngTitle);
|
|
18400
|
-
customElements.define("ng-custom", ngCustom);
|
|
18401
|
-
customElements.define("ng-head", ngHead);
|
|
17948
|
+
class ngHead extends HTMLElement
|
|
17949
|
+
{
|
|
17950
|
+
#owner;
|
|
17951
|
+
|
|
17952
|
+
constructor () {
|
|
17953
|
+
super();
|
|
17954
|
+
|
|
17955
|
+
this.attachShadow({ mode: 'open' });
|
|
17956
|
+
}
|
|
17957
|
+
|
|
17958
|
+
connectedCallback() {
|
|
17959
|
+
|
|
17960
|
+
this.#owner = this.getRootNode().host;
|
|
17961
|
+
|
|
17962
|
+
if (ninegrid.j.querySelectorAll(this.#owner).hasClass("simple")) return;
|
|
17963
|
+
|
|
17964
|
+
this.shadowRoot.innerHTML = `
|
|
17965
|
+
<style>
|
|
17966
|
+
@import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/ngHead.css";
|
|
17967
|
+
${ninegrid.getCustomPath(this,"ngHead.css")}
|
|
17968
|
+
</style>
|
|
17969
|
+
|
|
17970
|
+
<ng-menu></ng-menu>
|
|
17971
|
+
<ng-title></ng-title>
|
|
17972
|
+
<ng-custom></ng-custom>
|
|
17973
|
+
`;
|
|
17974
|
+
};
|
|
17975
|
+
}
|
|
17976
|
+
|
|
17977
|
+
class ngTitle extends HTMLElement
|
|
17978
|
+
{
|
|
17979
|
+
#owner;
|
|
17980
|
+
|
|
17981
|
+
constructor () {
|
|
17982
|
+
super();
|
|
17983
|
+
}
|
|
17984
|
+
|
|
17985
|
+
connectedCallback() {
|
|
17986
|
+
if (!this.getRootNode().host) return;
|
|
17987
|
+
|
|
17988
|
+
this.#owner = this.getRootNode().host.getRootNode().host;
|
|
17989
|
+
|
|
17990
|
+
this.innerHTML = `<span>${this.#owner.getAttribute("caption")}</span>`;
|
|
17991
|
+
|
|
17992
|
+
$("span", this).on("dblclick", e => {
|
|
17993
|
+
const link = '<font color="green">https://www.ninegrid.net</font>';
|
|
17994
|
+
e.currentTarget.innerHTML = e.currentTarget.innerHTML == link ? `<span>${this.#owner.getAttribute("caption")}</span>` : link;
|
|
17995
|
+
});
|
|
17996
|
+
};
|
|
17997
|
+
}
|
|
17998
|
+
|
|
17999
|
+
class ngCustom extends HTMLElement
|
|
18000
|
+
{
|
|
18001
|
+
#owner;
|
|
18002
|
+
|
|
18003
|
+
constructor () {
|
|
18004
|
+
super();
|
|
18005
|
+
}
|
|
18006
|
+
|
|
18007
|
+
connectedCallback() {
|
|
18008
|
+
if (!this.getRootNode().host) return;
|
|
18009
|
+
|
|
18010
|
+
this.#owner = this.getRootNode().host.getRootNode().host;
|
|
18011
|
+
|
|
18012
|
+
this.innerHTML = `<div></div>`;
|
|
18013
|
+
};
|
|
18014
|
+
|
|
18015
|
+
add = (element) => {
|
|
18016
|
+
this.querySelector("div:first-child").append(element);
|
|
18017
|
+
};
|
|
18018
|
+
}
|
|
18019
|
+
|
|
18020
|
+
customElements.define("ng-title", ngTitle);
|
|
18021
|
+
customElements.define("ng-custom", ngCustom);
|
|
18022
|
+
customElements.define("ng-head", ngHead);
|
|
18402
18023
|
|
|
18403
18024
|
class ngIcon extends HTMLElement
|
|
18404
18025
|
{
|
|
@@ -23464,596 +23085,987 @@ class ngTreeItem extends ngCellEx
|
|
|
23464
23085
|
|
|
23465
23086
|
customElements.define("ng-tree-item", ngTreeItem);
|
|
23466
23087
|
|
|
23467
|
-
//import { ngData } from "./ngData.js";
|
|
23088
|
+
//import { ngData } from "./ngData.js";
|
|
23089
|
+
|
|
23090
|
+
class ngView
|
|
23091
|
+
{
|
|
23092
|
+
#owner;
|
|
23093
|
+
#rawIndex;
|
|
23094
|
+
#height;
|
|
23095
|
+
#ing;
|
|
23096
|
+
#timers = [];
|
|
23097
|
+
|
|
23098
|
+
constructor(owner) {
|
|
23099
|
+
this.#owner = owner;
|
|
23100
|
+
|
|
23101
|
+
this.#ing = false;
|
|
23102
|
+
|
|
23103
|
+
this.init();
|
|
23104
|
+
}
|
|
23105
|
+
|
|
23106
|
+
/**
|
|
23107
|
+
* changelayout
|
|
23108
|
+
* resize
|
|
23109
|
+
*/
|
|
23110
|
+
init = () => {
|
|
23111
|
+
|
|
23112
|
+
//if (this.#ing) return;
|
|
23113
|
+
|
|
23114
|
+
this.#height = {
|
|
23115
|
+
body : $(".ng-container-body", this.#owner.body).height() || 0,
|
|
23116
|
+
thead : $(".ng-container-body thead", this.#owner.body).height() || 0,
|
|
23117
|
+
tfoot : $(".ng-container-body tfoot", this.#owner.body).height() || 0,
|
|
23118
|
+
};
|
|
23119
|
+
|
|
23120
|
+
if (this.#ing) return;
|
|
23121
|
+
|
|
23122
|
+
$(".ng-container tbody.bindable tr.nodata", this.#owner.body).height(this.#height.body);
|
|
23123
|
+
|
|
23124
|
+
this.#ing = true;
|
|
23125
|
+
};
|
|
23126
|
+
|
|
23127
|
+
redraw = () => {
|
|
23128
|
+
|
|
23129
|
+
this.#owner.touchEvent.scrollTop();
|
|
23130
|
+
|
|
23131
|
+
this.init();
|
|
23132
|
+
|
|
23133
|
+
if (!this.#owner.dataManager) return;
|
|
23134
|
+
|
|
23135
|
+
this.#rawIndex = this.#owner.dataManager.viewRecords.rawIndex || 0;
|
|
23136
|
+
|
|
23137
|
+
this.#resetTR3();
|
|
23138
|
+
|
|
23139
|
+
this.#r();
|
|
23140
|
+
|
|
23141
|
+
this.#owner.body.querySelector("ng-vscrollbar").refresh();
|
|
23142
|
+
};
|
|
23143
|
+
|
|
23144
|
+
redrawV2 = () => {
|
|
23145
|
+
|
|
23146
|
+
this.#owner.touchEvent.scrollTop();
|
|
23147
|
+
|
|
23148
|
+
this.init();
|
|
23149
|
+
|
|
23150
|
+
this.#rawIndex = this.#owner.dataManager.viewRecords.rawIndex || 0;
|
|
23151
|
+
|
|
23152
|
+
this.#resetTR3V2();
|
|
23153
|
+
|
|
23154
|
+
this.#r();
|
|
23155
|
+
this.#owner.body.querySelector("ng-vscrollbar").refreshV2();
|
|
23156
|
+
};
|
|
23157
|
+
|
|
23158
|
+
redrawV3 = () => {
|
|
23159
|
+
|
|
23160
|
+
this.init();
|
|
23161
|
+
|
|
23162
|
+
this.#rawIndex = this.#owner.dataManager.viewRecords.rawIndex || 0;
|
|
23163
|
+
|
|
23164
|
+
//this.#resetTR3V2();
|
|
23165
|
+
|
|
23166
|
+
this.#r();
|
|
23167
|
+
//this.#owner.body.querySelector("ng-vscrollbar").refreshV2();
|
|
23168
|
+
};
|
|
23169
|
+
|
|
23170
|
+
|
|
23171
|
+
#getPinHeight = () => {
|
|
23172
|
+
var h = 0;
|
|
23173
|
+
|
|
23174
|
+
$(".ng-container-body tbody.fixed tr", this.#owner.body).each((i, tr) => {
|
|
23175
|
+
if (tr.data && tr.data.__ng) {
|
|
23176
|
+
h += this.#owner.matrix.getHeight(tr.data.__ng.height[parseInt(i % this.#owner.template.length)]);
|
|
23177
|
+
}
|
|
23178
|
+
});
|
|
23179
|
+
|
|
23180
|
+
return h;
|
|
23181
|
+
}
|
|
23182
|
+
|
|
23183
|
+
#getTrHeight = () => {
|
|
23184
|
+
var h = this.#getPinHeight();
|
|
23185
|
+
|
|
23186
|
+
const startRow = parseInt(this.#rawIndex * this.#owner.template.length);
|
|
23187
|
+
|
|
23188
|
+
$(".ng-container-body tbody.bindable tr:not(.nodata)", this.#owner.body).each((i, tr) => {
|
|
23189
|
+
h += this.#owner.matrix.getHeight(startRow + i);
|
|
23190
|
+
});
|
|
23191
|
+
|
|
23192
|
+
return h;
|
|
23193
|
+
}
|
|
23194
|
+
|
|
23195
|
+
#getRowCount = () => {
|
|
23196
|
+
|
|
23197
|
+
const displayRowCount = parseInt(this.#owner.getAttribute("display-row-count"));
|
|
23198
|
+
|
|
23199
|
+
if (this.#owner.closest("dialog") && ninegrid.j.querySelectorAll(this.#owner).hasClass("simple")) return 1;
|
|
23200
|
+
if ([ninegrid.PAGINGTYPE.CLIENT,ninegrid.PAGINGTYPE.SERVER].includes(this.#owner.paging.type)) return this.#owner.paging.linesPerPage;
|
|
23201
|
+
if (!isNaN(displayRowCount)) {
|
|
23202
|
+
|
|
23203
|
+
/**
|
|
23204
|
+
* 데이타가 적을 경우 rawIndex = 0;
|
|
23205
|
+
* 마지막 페이지 인경우 rawIndex 계산
|
|
23206
|
+
*/
|
|
23207
|
+
if (this.#rawIndex + displayRowCount > this.#owner.data.count()) {
|
|
23208
|
+
this.#rawIndex = (displayRowCount >= this.#owner.data.count()) ? 0 : this.#owner.data.count() - displayRowCount;
|
|
23209
|
+
this.#owner.dataManager.viewRecords.rawIndex = this.#rawIndex;
|
|
23210
|
+
|
|
23211
|
+
}
|
|
23212
|
+
|
|
23213
|
+
|
|
23214
|
+
return displayRowCount;
|
|
23215
|
+
}
|
|
23216
|
+
|
|
23217
|
+
const totalHeight = this.#height.body - this.#height.thead - this.#height.tfoot - this.#getPinHeight();
|
|
23218
|
+
|
|
23219
|
+
var rowCount = 0;
|
|
23220
|
+
var h = 0;
|
|
23221
|
+
while (h < totalHeight) {
|
|
23222
|
+
h += this.getRowHeight(this.#rawIndex + rowCount++);
|
|
23223
|
+
}
|
|
23224
|
+
|
|
23225
|
+
if (this.#rawIndex + rowCount > this.#owner.data.count()) {
|
|
23226
|
+
|
|
23227
|
+
rowCount = 0;
|
|
23228
|
+
h = 0;
|
|
23229
|
+
for (var i = this.#owner.data.count() - 1; i >= 0 && h < totalHeight; i--) {
|
|
23230
|
+
h += this.getRowHeight(i);
|
|
23231
|
+
rowCount++;
|
|
23232
|
+
}
|
|
23233
|
+
|
|
23234
|
+
if (h > totalHeight) rowCount --;
|
|
23235
|
+
|
|
23236
|
+
this.#rawIndex = this.#owner.data.count() - rowCount;
|
|
23237
|
+
|
|
23238
|
+
this.#owner.dataManager.viewRecords.rawIndex = this.#rawIndex;
|
|
23239
|
+
}
|
|
23240
|
+
|
|
23241
|
+
|
|
23242
|
+
return rowCount;
|
|
23243
|
+
};
|
|
23244
|
+
|
|
23245
|
+
#createTR = () => {
|
|
23246
|
+
|
|
23247
|
+
// 1. 스크린에 보여질 TR 갯수 계산
|
|
23248
|
+
var rowCount = this.#getRowCount();
|
|
23249
|
+
|
|
23250
|
+
// 0. TR 생성여부 판단
|
|
23251
|
+
//if (!this.#owner.body.querySelector(".ng-container-body tbody.bindable tr:not(.nodata)") || this.isLastPage) {
|
|
23252
|
+
// 2. TR 생성
|
|
23253
|
+
var startRow = $(".ng-container-body tbody.bindable tr", this.#owner.body).not('tr.nodata').length / (this.#owner.template.length || 1);
|
|
23254
|
+
|
|
23255
|
+
|
|
23256
|
+
const leftTmpl = this.#owner.template.clone();
|
|
23257
|
+
const rightTmpl = leftTmpl.clone();//this.#owner.template.clone();
|
|
23258
|
+
const bodyTmpl = leftTmpl.clone();//this.#owner.template.clone();
|
|
23259
|
+
|
|
23260
|
+
leftTmpl .find("th,td").not("[fixed=left]").remove();
|
|
23261
|
+
rightTmpl .find("th,td").not("[fixed=right]").remove();
|
|
23262
|
+
bodyTmpl .find("th[fixed=left],td[fixed=left],th[fixed=right],td[fixed=right]").remove();
|
|
23263
|
+
|
|
23264
|
+
const leftNoData = $("tr.nodata", this.#owner.body.querySelector(".ng-container-left"));
|
|
23265
|
+
const rightNoData = $("tr.nodata", this.#owner.body.querySelector(".ng-container-right"));
|
|
23266
|
+
const bodyNoData = $("tr.nodata", this.#owner.body.querySelector(".ng-container-body"));
|
|
23267
|
+
|
|
23268
|
+
for (var i = startRow; i < rowCount; i++) {
|
|
23269
|
+
|
|
23270
|
+
|
|
23271
|
+
leftTmpl .each((i,tr) => { leftNoData .before(tr.outerHTML); });
|
|
23272
|
+
rightTmpl .each((i,tr) => { rightNoData .before(tr.outerHTML); });
|
|
23273
|
+
bodyTmpl .each((i,tr) => { bodyNoData .before(tr.outerHTML); });
|
|
23274
|
+
}
|
|
23275
|
+
//}
|
|
23276
|
+
|
|
23277
|
+
|
|
23278
|
+
|
|
23279
|
+
// 3. 불필요 TR 제거
|
|
23280
|
+
/**
|
|
23281
|
+
rowCount = Math.min(rowCount, this.#owner.data.count());// + ($(".ng-container-body tbody.fixed tr", this.#owner.body).length / this.#owner.template.length);
|
|
23282
|
+
$(".ng-container tbody.bindable tr", this.#owner.body).not(".nodata").each((i,tr) => {
|
|
23283
|
+
if (parseInt(tr.sectionRowIndex / this.#owner.template.length) >= rowCount) {
|
|
23284
|
+
$(tr).remove();
|
|
23285
|
+
}
|
|
23286
|
+
}); */
|
|
23287
|
+
|
|
23288
|
+
return;
|
|
23289
|
+
|
|
23290
|
+
// 4. row resize
|
|
23291
|
+
var trsBody = $(".ng-container-body tbody.bindable tr:not(.nodata)", this.#owner.body);
|
|
23292
|
+
|
|
23293
|
+
if (trsBody.length > 0) {
|
|
23294
|
+
var startRow = parseInt(this.#rawIndex * this.#owner.template.length);
|
|
23295
|
+
}
|
|
23296
|
+
};
|
|
23297
|
+
|
|
23298
|
+
#removeGarbageTR = () => {
|
|
23299
|
+
|
|
23300
|
+
var rowCount = Math.min(this.#getRowCount(), this.#owner.data.count());// + this.pin.count();
|
|
23301
|
+
|
|
23302
|
+
|
|
23303
|
+
$(".ng-container tbody.bindable tr:not(.nodata)", this.#owner.body).each((i,tr) => {
|
|
23304
|
+
if (parseInt(tr.sectionRowIndex / this.#owner.template.length) >= rowCount) {
|
|
23305
|
+
$(tr).remove();
|
|
23306
|
+
}
|
|
23307
|
+
});
|
|
23308
|
+
|
|
23309
|
+
this.#owner.body.querySelectorAll(".ng-container tbody.bindable tr:not(.nodata)").forEach(tr => {
|
|
23310
|
+
const row = this.#rawIndex + parseInt(tr.sectionRowIndex / this.#owner.template.length);
|
|
23311
|
+
if (row >= this.#owner.data.count()) {
|
|
23312
|
+
$(tr).remove();
|
|
23313
|
+
}
|
|
23314
|
+
});
|
|
23315
|
+
};
|
|
23316
|
+
|
|
23317
|
+
#resetTR3 = () => {
|
|
23318
|
+
|
|
23319
|
+
// 1. TR 생성
|
|
23320
|
+
this.#createTR();
|
|
23321
|
+
|
|
23322
|
+
this.#removeGarbageTR();
|
|
23323
|
+
|
|
23324
|
+
// 5. nodata resize
|
|
23325
|
+
|
|
23326
|
+
var h = this.#height.body - this.#height.thead - this.#height.tfoot - this.#getTrHeight();
|
|
23327
|
+
$(".ng-container tbody.bindable tr.nodata", this.#owner.body).height(h);
|
|
23328
|
+
|
|
23329
|
+
/**
|
|
23330
|
+
this.#owner.body.querySelector(".ng-container-body .ng-table").style.top = 0;
|
|
23331
|
+
this.#owner.body.querySelector(".ng-container-left .ng-table").style.top = 0;
|
|
23332
|
+
this.#owner.body.querySelector(".ng-container-right .ng-table").style.top = 0;
|
|
23333
|
+
*/
|
|
23334
|
+
|
|
23335
|
+
//$('.ng-container .ng-table', this.#owner.body).offset({top:$('.ng-container .ng-table', this.#owner.body).offset().top});
|
|
23336
|
+
//$('.ng-container .ng-table', this.#owner.body).offset({top:$('.ng-container .ng-table', this.#owner.body).offset().top});
|
|
23337
|
+
//this.isLastPage = h > 0 ? true : false;
|
|
23338
|
+
|
|
23339
|
+
|
|
23340
|
+
if (this.#owner.closest("dialog") && ninegrid.j.querySelectorAll(this.#owner).hasClass("simple")) {
|
|
23341
|
+
$("tr.nodata", this.#owner.body).height(0);
|
|
23342
|
+
|
|
23343
|
+
var h = 47;//this.#getTrHeight();
|
|
23344
|
+
$('.ng-container-body tbody.bindable tr', this.#owner.body).not('.nodata').each((i,tr) => {
|
|
23345
|
+
h += $(tr).height();
|
|
23346
|
+
});
|
|
23347
|
+
|
|
23348
|
+
$(this.#owner.closest("dialog")).height(h);
|
|
23349
|
+
}
|
|
23350
|
+
};
|
|
23351
|
+
|
|
23352
|
+
#resetTR3V2 = () => {
|
|
23353
|
+
|
|
23354
|
+
// 1. TR 생성
|
|
23355
|
+
//this.#owner.isLastPage = rows[rows.length-1] == this.#owner.data.count() - 1 ? true : false;//this.#isLastPage();
|
|
23356
|
+
|
|
23357
|
+
//if (this.#owner.isLastPage) {
|
|
23358
|
+
//if (this.#isLastPage) {
|
|
23359
|
+
|
|
23360
|
+
//if (this.#owner.isLastPage) {
|
|
23361
|
+
this.#createTR();
|
|
23362
|
+
//}
|
|
23363
|
+
/**
|
|
23364
|
+
if ($(".ng-container-body tbody.bindable tr.nodata", this.#owner.body).height() > 0) {
|
|
23365
|
+
this.#createTR();
|
|
23366
|
+
} */
|
|
23367
|
+
|
|
23368
|
+
this.#removeGarbageTR();
|
|
23369
|
+
|
|
23370
|
+
|
|
23371
|
+
// 5. nodata resize
|
|
23372
|
+
/**
|
|
23373
|
+
if (this.#owner.isFirstPage || this.#owner.isLastPage) {
|
|
23374
|
+
var h = this.#owner.body.querySelector("ng-vscrollbar").bodyHeight - $(".ng-container-body .ng-table", this.#owner.body).height() + $('.ng-container-body .ng-table tr.nodata', this.#owner.body).height();
|
|
23375
|
+
$(".ng-container tbody.bindable tr.nodata", this.#owner.body).height(h);
|
|
23376
|
+
}*/
|
|
23377
|
+
//$(".ng-container tbody.bindable tr.nodata", this.#owner.body).height(700);
|
|
23378
|
+
|
|
23379
|
+
if (this.#owner.isLastPage) ;
|
|
23380
|
+
|
|
23381
|
+
|
|
23382
|
+
//this.isLastPage = h > 0 ? true : false;
|
|
23383
|
+
|
|
23384
|
+
|
|
23385
|
+
//this.nodata = h > 0 ? true : false;
|
|
23386
|
+
|
|
23387
|
+
// 6. 마지막 TR tabindex
|
|
23388
|
+
};
|
|
23389
|
+
|
|
23390
|
+
#refreshData = () => {
|
|
23391
|
+
|
|
23392
|
+
for (const v of this.#timers) {
|
|
23393
|
+
clearTimeout(v);
|
|
23394
|
+
}
|
|
23395
|
+
this.#timers = [];
|
|
23396
|
+
|
|
23397
|
+
this.#timers.push(setTimeout(() => {
|
|
23398
|
+
|
|
23399
|
+
this.#ing = false;
|
|
23400
|
+
|
|
23401
|
+
// 4. row resize
|
|
23402
|
+
var trsBody = $(".ng-container-body tbody.bindable tr", this.#owner.body).not(".nodata");
|
|
23403
|
+
var trsLeft = $(".ng-container-left tbody.bindable tr", this.#owner.body).not(".nodata");
|
|
23404
|
+
var trsRight= $(".ng-container-right tbody.bindable tr", this.#owner.body).not(".nodata");
|
|
23405
|
+
|
|
23406
|
+
if (trsBody.length > 0) {
|
|
23407
|
+
var startRow = parseInt(trsBody[0].dataset.row * this.#owner.template.length);
|
|
23408
|
+
|
|
23409
|
+
trsBody.each((i, tr) => {
|
|
23410
|
+
var h = this.#owner.matrix.getHeight(startRow + i);// || 32;
|
|
23411
|
+
|
|
23412
|
+
$("canvas.chart", tr).css({ "height" : h-4 });
|
|
23413
|
+
$("canvas.chart", trsLeft.eq(i)).css({ "height" : h-4 });
|
|
23414
|
+
$("canvas.chart", trsRight.eq(i)).css({ "height" : h-4 });
|
|
23415
|
+
|
|
23416
|
+
$(tr).css({ "height" : h }).height(h);
|
|
23417
|
+
trsLeft.eq(i).css({ "height" : h }).height(h);
|
|
23418
|
+
trsRight.eq(i).css({ "height" : h }).height(h);
|
|
23419
|
+
});
|
|
23420
|
+
}
|
|
23421
|
+
|
|
23422
|
+
this.#owner.cell.refresh();
|
|
23423
|
+
|
|
23424
|
+
//row resize
|
|
23425
|
+
$('ng-row-indicator', this.#owner.body).each((i,el) => {
|
|
23426
|
+
el.refresh();
|
|
23427
|
+
});
|
|
23428
|
+
|
|
23429
|
+
//5. nodata resize
|
|
23430
|
+
var h = this.#height.body - this.#height.thead - this.#height.tfoot - this.#getTrHeight();
|
|
23431
|
+
$(".ng-container tbody.bindable tr.nodata", this.#owner.body).height(h);
|
|
23432
|
+
|
|
23433
|
+
//this.isLastPage = h > 0 ? true : false;
|
|
23434
|
+
|
|
23435
|
+
|
|
23436
|
+
this.#owner.refreshBindRows();
|
|
23437
|
+
|
|
23438
|
+
this.#owner.refreshData();
|
|
23439
|
+
|
|
23440
|
+
this.#owner.paging.totalCount = this.#owner.data.countNF();
|
|
23441
|
+
|
|
23442
|
+
this.#owner.body.querySelector("ng-vscrollbar").refresh();
|
|
23468
23443
|
|
|
23469
|
-
|
|
23470
|
-
|
|
23471
|
-
|
|
23472
|
-
|
|
23473
|
-
|
|
23474
|
-
|
|
23475
|
-
|
|
23476
|
-
|
|
23477
|
-
|
|
23478
|
-
|
|
23479
|
-
|
|
23480
|
-
|
|
23444
|
+
ninegrid.j.querySelectorAll(".ng-table tbody tr", this.#owner.body).removeClass("hover");
|
|
23445
|
+
ninegrid.j.querySelectorAll(this.#owner).removeClass("loading");
|
|
23446
|
+
ninegrid.j.querySelectorAll("ng-filter-panel").removeClass("loading");
|
|
23447
|
+
|
|
23448
|
+
/**
|
|
23449
|
+
this.#owner.body.querySelector(".ng-container-left").style.position = "sticky";
|
|
23450
|
+
this.#owner.body.querySelector(".ng-container-right").style.position = "sticky";
|
|
23451
|
+
this.#owner.body.querySelector(".ng-container-body").style.position = "sticky";
|
|
23452
|
+
this.#owner.body.querySelector(".ng-container-left").style.top = "0px";
|
|
23453
|
+
this.#owner.body.querySelector(".ng-container-right").style.top = "0px";
|
|
23454
|
+
this.#owner.body.querySelector(".ng-container-body").style.top = "0px";
|
|
23455
|
+
|
|
23456
|
+
setTimeout(() => {
|
|
23457
|
+
this.#owner.body.querySelector(".ng-container-left").style.position = "relative";
|
|
23458
|
+
this.#owner.body.querySelector(".ng-container-right").style.position = "relative";
|
|
23459
|
+
this.#owner.body.querySelector(".ng-container-body").style.position = "relative";
|
|
23460
|
+
this.#owner.body.querySelector(".ng-container-left").style.top = "0px";
|
|
23461
|
+
this.#owner.body.querySelector(".ng-container-right").style.top = "0px";
|
|
23462
|
+
this.#owner.body.querySelector(".ng-container-body").style.top = "0px";
|
|
23463
|
+
}, 1000); */
|
|
23464
|
+
|
|
23465
|
+
}, 300));
|
|
23481
23466
|
|
|
23482
|
-
this.
|
|
23467
|
+
//if (!this.timers) this.timers = [];
|
|
23468
|
+
this.#timers.push(setTimeout(() => {
|
|
23469
|
+
this.#owner.refreshDataV2();
|
|
23470
|
+
}));
|
|
23483
23471
|
}
|
|
23484
23472
|
|
|
23485
|
-
|
|
23486
|
-
|
|
23487
|
-
|
|
23488
|
-
|
|
23489
|
-
|
|
23490
|
-
|
|
23491
|
-
//if (this.#ing) return;
|
|
23492
|
-
|
|
23493
|
-
this.#height = {
|
|
23494
|
-
body : $(".ng-container-body", this.#owner.body).height() || 0,
|
|
23495
|
-
thead : $(".ng-container-body thead", this.#owner.body).height() || 0,
|
|
23496
|
-
tfoot : $(".ng-container-body tfoot", this.#owner.body).height() || 0,
|
|
23497
|
-
};
|
|
23498
|
-
|
|
23499
|
-
if (this.#ing) return;
|
|
23473
|
+
#r = () => {
|
|
23474
|
+
|
|
23475
|
+
var rows = [];
|
|
23476
|
+
this.#owner.body.querySelectorAll(".ng-container-body tbody.bindable tr:not(.nodata)").forEach(tr => {
|
|
23477
|
+
rows.push(this.#rawIndex + parseInt(tr.sectionRowIndex / this.#owner.template.length));
|
|
23478
|
+
});
|
|
23500
23479
|
|
|
23501
|
-
|
|
23480
|
+
rows = [...new Set(rows)];
|
|
23502
23481
|
|
|
23503
|
-
this.#
|
|
23504
|
-
|
|
23505
|
-
|
|
23506
|
-
redraw = () => {
|
|
23482
|
+
this.#owner.body.querySelectorAll(".ng-container tbody.bindable tr:not(.nodata)").forEach(tr => {
|
|
23483
|
+
const index = parseInt(tr.sectionRowIndex / this.#owner.template.length);
|
|
23507
23484
|
|
|
23508
|
-
|
|
23509
|
-
|
|
23510
|
-
|
|
23485
|
+
tr.dataset.row = rows[index];
|
|
23486
|
+
tr.dataset.matrixRow = parseInt(rows[index] * this.#owner.template.length) + parseInt(tr.sectionRowIndex % this.#owner.template.length);
|
|
23487
|
+
|
|
23488
|
+
for (const cell of tr.cells) {
|
|
23489
|
+
cell.dataset.row = tr.dataset.row;
|
|
23490
|
+
cell.dataset.matrixRow = tr.dataset.matrixRow;
|
|
23491
|
+
}
|
|
23492
|
+
});
|
|
23511
23493
|
|
|
23512
|
-
if (!this.#owner.dataManager) return;
|
|
23513
23494
|
|
|
23514
|
-
|
|
23495
|
+
rows.forEach(row => {
|
|
23496
|
+
const data = this.#owner.data.get(row);
|
|
23515
23497
|
|
|
23516
|
-
|
|
23498
|
+
this.#owner.body.querySelectorAll(`.ng-container tbody.bindable tr[data-row="${row}"]`).forEach(tr => {
|
|
23499
|
+
tr.data = data;
|
|
23500
|
+
});
|
|
23501
|
+
});
|
|
23517
23502
|
|
|
23518
|
-
this.#
|
|
23503
|
+
this.#rawIndex = parseInt(this.#owner.body.querySelector(".ng-container-body tbody.bindable tr:first-of-type").getAttribute("data-row"));
|
|
23504
|
+
|
|
23505
|
+
this.#owner.dataManager.viewRecords.rawIndex = this.#rawIndex;
|
|
23519
23506
|
|
|
23520
|
-
this.#owner.body.querySelector("ng-vscrollbar").refresh();
|
|
23521
|
-
};
|
|
23522
|
-
|
|
23523
|
-
redrawV2 = () => {
|
|
23524
23507
|
|
|
23525
|
-
this.#
|
|
23526
|
-
|
|
23527
|
-
this.init();
|
|
23508
|
+
this.#refreshData();
|
|
23528
23509
|
|
|
23529
|
-
this.#
|
|
23510
|
+
//this.#owner.isFirstPage = this.#rawIndex == this.#owner.cell.firstRow() ? true : false;
|
|
23511
|
+
this.#owner.isFirstPage = this.#rawIndex == 0 ? true : false;
|
|
23512
|
+
//this.#owner.isLastPage = this.isLastPage;
|
|
23530
23513
|
|
|
23531
|
-
this.#resetTR3V2();
|
|
23532
23514
|
|
|
23533
|
-
this.#
|
|
23534
|
-
this.#owner.body.
|
|
23515
|
+
this.#owner.isLastPage = rows[rows.length-1] == this.#owner.data.count() - 1 ? true : false;//this.#isLastPage();
|
|
23516
|
+
//this.#owner.lastHidden = (parseInt($(".ng-container-body", this.#owner.body).height() - ($(".ng-container-body tfoot", this.#owner.body).height() || 0) + 2) >= t + h) ? false : true;
|
|
23517
|
+
|
|
23518
|
+
//this.#owner.body.querySelector("ng-vscrollbar").refresh();
|
|
23535
23519
|
};
|
|
23536
23520
|
|
|
23537
|
-
|
|
23538
|
-
|
|
23539
|
-
|
|
23540
|
-
|
|
23541
|
-
this.#rawIndex = this.#owner.dataManager.viewRecords.rawIndex || 0;
|
|
23542
|
-
|
|
23543
|
-
//this.#resetTR3V2();
|
|
23521
|
+
getVisibleFirstRow = () => {
|
|
23522
|
+
var tr = this.#owner.body.querySelector(".ng-container-body tbody.bindable tr:first-child");
|
|
23523
|
+
return parseInt(tr.dataset.row);
|
|
23524
|
+
};
|
|
23544
23525
|
|
|
23545
|
-
|
|
23546
|
-
|
|
23526
|
+
getVisibleLastRow = () => {
|
|
23527
|
+
var trs = this.#owner.body.querySelectorAll(".ng-container-body tbody.bindable tr:not(.nodata)");
|
|
23528
|
+
return (trs.length > 0) ? parseInt(trs[trs.length - 1].dataset.row) : -1;
|
|
23547
23529
|
};
|
|
23548
|
-
|
|
23549
23530
|
|
|
23550
|
-
|
|
23551
|
-
|
|
23531
|
+
getRowHeight = (rowIndex) => {
|
|
23532
|
+
let h = 0;
|
|
23552
23533
|
|
|
23553
|
-
|
|
23554
|
-
|
|
23555
|
-
|
|
23556
|
-
}
|
|
23557
|
-
});
|
|
23534
|
+
for (var i = 0; i < this.#owner.template.length; i++) {
|
|
23535
|
+
h += this.#owner.matrix.getHeight(parseInt(rowIndex * this.#owner.template.length + i));
|
|
23536
|
+
}
|
|
23558
23537
|
|
|
23559
23538
|
return h;
|
|
23560
|
-
}
|
|
23539
|
+
};
|
|
23561
23540
|
|
|
23562
|
-
|
|
23563
|
-
|
|
23564
|
-
|
|
23565
|
-
|
|
23566
|
-
|
|
23567
|
-
|
|
23568
|
-
h += this.#owner.matrix.getHeight(startRow + i);
|
|
23569
|
-
});
|
|
23541
|
+
getTranslateY = () => {
|
|
23542
|
+
const tbody = this.#owner.body.querySelector(".ng-container-body tbody.bindable");
|
|
23543
|
+
return (!tbody || !tbody.style || !tbody.style.transform) ? 0 : parseFloat(tbody.style.transform.replace("translateY(", "").replace(")", ""));
|
|
23544
|
+
};
|
|
23545
|
+
|
|
23546
|
+
getTotalSpace = () => {
|
|
23570
23547
|
|
|
23571
|
-
return
|
|
23572
|
-
|
|
23548
|
+
return $(this.#owner.body.querySelector(".ng-container-body")).height()
|
|
23549
|
+
- ($(this.#owner.body.querySelector(".ng-container-body thead")).height() || 0)
|
|
23550
|
+
- ($(this.#owner.body.querySelector(".ng-container-body tfoot")).height() || 0)
|
|
23551
|
+
- ($(this.#owner.body.querySelector(".ng-container-body tbody.fixed")).height() || 0);
|
|
23552
|
+
//- this.getTranslateY();
|
|
23553
|
+
};
|
|
23573
23554
|
|
|
23574
|
-
|
|
23555
|
+
fitPage = () => {
|
|
23556
|
+
const lastRow = this.getVisibleLastRow();
|
|
23557
|
+
const totalSpace = this.getTotalSpace();
|
|
23575
23558
|
|
|
23576
|
-
|
|
23577
|
-
|
|
23578
|
-
|
|
23579
|
-
if (
|
|
23580
|
-
|
|
23581
|
-
|
|
23582
|
-
|
|
23583
|
-
|
|
23584
|
-
|
|
23585
|
-
|
|
23586
|
-
|
|
23587
|
-
|
|
23588
|
-
this.#owner.dataManager.viewRecords.rawIndex = this.#rawIndex;
|
|
23589
|
-
|
|
23559
|
+
/**
|
|
23560
|
+
* 마지막 페이지 정리
|
|
23561
|
+
*/
|
|
23562
|
+
if (lastRow == this.#owner.data.count() - 1) {
|
|
23563
|
+
var h = 0;
|
|
23564
|
+
for (var i = lastRow; i >= 0; i--) {
|
|
23565
|
+
h += this.getRowHeight(i);
|
|
23566
|
+
|
|
23567
|
+
if (h > totalSpace) {
|
|
23568
|
+
this.#owner.scrollTo(i + 1);
|
|
23569
|
+
break;
|
|
23570
|
+
}
|
|
23590
23571
|
}
|
|
23591
|
-
|
|
23592
|
-
|
|
23593
|
-
return displayRowCount;
|
|
23594
|
-
}
|
|
23595
|
-
|
|
23596
|
-
const totalHeight = this.#height.body - this.#height.thead - this.#height.tfoot - this.#getPinHeight();
|
|
23597
|
-
|
|
23598
|
-
var rowCount = 0;
|
|
23599
|
-
var h = 0;
|
|
23600
|
-
while (h < totalHeight) {
|
|
23601
|
-
h += this.getRowHeight(this.#rawIndex + rowCount++);
|
|
23602
23572
|
}
|
|
23573
|
+
}
|
|
23574
|
+
/**
|
|
23575
|
+
#isLastPage = () => {
|
|
23576
|
+
const arr = this.#owner.body.querySelectorAll(".ng-container-body tbody.bindable tr:not(.nodata)");
|
|
23577
|
+
if (arr.length <= 0) return null;
|
|
23603
23578
|
|
|
23604
|
-
|
|
23605
|
-
|
|
23606
|
-
|
|
23607
|
-
|
|
23608
|
-
|
|
23609
|
-
|
|
23610
|
-
|
|
23611
|
-
|
|
23612
|
-
|
|
23613
|
-
|
|
23579
|
+
return arr[arr.length - 1].dataset.row == this.#owner.data.count() - 1 ? true : false;
|
|
23580
|
+
}*/
|
|
23581
|
+
|
|
23582
|
+
|
|
23583
|
+
/**
|
|
23584
|
+
* grid.selectCell(row, colnm, subrow) => scrollTo
|
|
23585
|
+
* grid.selectCol(fromColNm, toColNm)
|
|
23586
|
+
* grid.selectRow(row) => scrollTo
|
|
23587
|
+
* grid.selectArea(row1, col1, row2, col2) => scrollTo
|
|
23588
|
+
*
|
|
23589
|
+
* grid.clearSelect()
|
|
23590
|
+
*
|
|
23591
|
+
* grid.selection.currentCell;
|
|
23592
|
+
* grid.selection.currentRow;
|
|
23593
|
+
* grid.selection.currentSubRow;
|
|
23594
|
+
* grid.selection.currentCol;
|
|
23595
|
+
* grid.selection.firstRow
|
|
23596
|
+
* grid.selection.firstCol
|
|
23597
|
+
* grid.selection.lastRow
|
|
23598
|
+
* grid.selection.lastCol
|
|
23599
|
+
*/
|
|
23600
|
+
|
|
23601
|
+
selectArea = (oRow1, oCol1, oRow2, oCol2) => {
|
|
23614
23602
|
|
|
23615
|
-
|
|
23616
|
-
|
|
23617
|
-
|
|
23618
|
-
|
|
23603
|
+
const row1 = this.#getRowIndex(oRow1);
|
|
23604
|
+
const row2 = this.#getRowIndex(oRow2);
|
|
23605
|
+
const col1 = this.#getColIndex(oCol1);
|
|
23606
|
+
const col2 = this.#getColIndex(oCol2);
|
|
23607
|
+
const matrixRow1= parseInt(row1 * this.#owner.template.length);
|
|
23608
|
+
const matrixRow2= parseInt(row2 * this.#owner.template.length) + this.#owner.template.length - 1;
|
|
23619
23609
|
|
|
23620
|
-
|
|
23621
|
-
|
|
23610
|
+
this.#owner.row.at = row1;
|
|
23611
|
+
|
|
23612
|
+
(row1 >= 0 && row2 >= 0) ? this.#owner.selection.selectArea(matrixRow1, col1, matrixRow2, col2) : this.clearSelection();
|
|
23622
23613
|
};
|
|
23623
23614
|
|
|
23624
|
-
|
|
23625
|
-
|
|
23626
|
-
// 1. 스크린에 보여질 TR 갯수 계산
|
|
23627
|
-
var rowCount = this.#getRowCount();
|
|
23628
|
-
|
|
23629
|
-
// 0. TR 생성여부 판단
|
|
23630
|
-
//if (!this.#owner.body.querySelector(".ng-container-body tbody.bindable tr:not(.nodata)") || this.isLastPage) {
|
|
23631
|
-
// 2. TR 생성
|
|
23632
|
-
var startRow = $(".ng-container-body tbody.bindable tr", this.#owner.body).not('tr.nodata').length / (this.#owner.template.length || 1);
|
|
23633
|
-
|
|
23634
|
-
|
|
23635
|
-
const leftTmpl = this.#owner.template.clone();
|
|
23636
|
-
const rightTmpl = leftTmpl.clone();//this.#owner.template.clone();
|
|
23637
|
-
const bodyTmpl = leftTmpl.clone();//this.#owner.template.clone();
|
|
23638
|
-
|
|
23639
|
-
leftTmpl .find("th,td").not("[fixed=left]").remove();
|
|
23640
|
-
rightTmpl .find("th,td").not("[fixed=right]").remove();
|
|
23641
|
-
bodyTmpl .find("th[fixed=left],td[fixed=left],th[fixed=right],td[fixed=right]").remove();
|
|
23642
|
-
|
|
23643
|
-
const leftNoData = $("tr.nodata", this.#owner.body.querySelector(".ng-container-left"));
|
|
23644
|
-
const rightNoData = $("tr.nodata", this.#owner.body.querySelector(".ng-container-right"));
|
|
23645
|
-
const bodyNoData = $("tr.nodata", this.#owner.body.querySelector(".ng-container-body"));
|
|
23615
|
+
selectRow = (oRow1, oRow2) => {
|
|
23646
23616
|
|
|
23647
|
-
|
|
23648
|
-
|
|
23649
|
-
|
|
23650
|
-
|
|
23651
|
-
rightTmpl .each((i,tr) => { rightNoData .before(tr.outerHTML); });
|
|
23652
|
-
bodyTmpl .each((i,tr) => { bodyNoData .before(tr.outerHTML); });
|
|
23653
|
-
}
|
|
23654
|
-
//}
|
|
23617
|
+
const row1 = this.#getRowIndex(oRow1);
|
|
23618
|
+
const row2 = ninegrid.isNull(oRow2) ? row1 : this.#getRowIndex(oRow2);
|
|
23619
|
+
const matrixRow1= parseInt(row1 * this.#owner.template.length);
|
|
23620
|
+
const matrixRow2= parseInt(row2 * this.#owner.template.length) + this.#owner.template.length - 1;
|
|
23655
23621
|
|
|
23656
|
-
|
|
23622
|
+
this.#owner.row.at = row1;
|
|
23657
23623
|
|
|
23658
|
-
|
|
23659
|
-
|
|
23660
|
-
|
|
23661
|
-
|
|
23662
|
-
|
|
23663
|
-
|
|
23664
|
-
|
|
23665
|
-
|
|
23624
|
+
(row1 >= 0 && row2 >= 0) ? this.#owner.selection.selectArea(matrixRow1, this.#owner.firstCol, matrixRow2, this.#owner.lastCol) : this.clearSelection();
|
|
23625
|
+
};
|
|
23626
|
+
|
|
23627
|
+
selectCol = (oCol1, oCol2) => {
|
|
23628
|
+
const col1 = this.#getColIndex(oCol1);
|
|
23629
|
+
const col2 = ninegrid.isNull(oCol2) ? col1 : this.#getColIndex(oCol2);
|
|
23630
|
+
const matrixRow1= 0;
|
|
23631
|
+
const matrixRow2= parseInt(this.#owner.data.count() * this.#owner.template.length - 1);
|
|
23632
|
+
|
|
23633
|
+
(col1 >= 0 && col2 >= 0) ? this.#owner.selection.selectArea(matrixRow1, col1, matrixRow2, col2) : this.clearSelection();
|
|
23634
|
+
};
|
|
23635
|
+
|
|
23636
|
+
selectCell = (oRow, oCol, subrow) => {
|
|
23666
23637
|
|
|
23667
|
-
|
|
23638
|
+
const row = this.#getRowIndex(oRow);
|
|
23639
|
+
const col = this.#getColIndex(oCol);
|
|
23640
|
+
const matrixRow = parseInt(row * this.#owner.template.length) + ninegrid.nvl(subrow, 0);
|
|
23668
23641
|
|
|
23669
|
-
|
|
23670
|
-
var trsBody = $(".ng-container-body tbody.bindable tr:not(.nodata)", this.#owner.body);
|
|
23642
|
+
this.#owner.row.at = row;
|
|
23671
23643
|
|
|
23672
|
-
|
|
23673
|
-
|
|
23644
|
+
(row >= 0) ? this.#owner.selection.selectArea(matrixRow, col, matrixRow, col) : this.clearSelection();
|
|
23645
|
+
};
|
|
23646
|
+
|
|
23647
|
+
#getRowIndex = (oRow) => {
|
|
23648
|
+
if (typeof oRow === "number") {
|
|
23649
|
+
return oRow;
|
|
23650
|
+
}
|
|
23651
|
+
else if (typeof oRow === "function") {
|
|
23652
|
+
return this.#owner.data.findIndex(oRow);
|
|
23653
|
+
}
|
|
23654
|
+
else {
|
|
23655
|
+
throw `invalid ${oRow}`;
|
|
23674
23656
|
}
|
|
23675
23657
|
};
|
|
23676
23658
|
|
|
23677
|
-
#
|
|
23678
|
-
|
|
23679
|
-
|
|
23659
|
+
#getColIndex = (oCol) => {
|
|
23660
|
+
if (typeof oCol === "number") {
|
|
23661
|
+
return oCol;
|
|
23662
|
+
}
|
|
23663
|
+
else if (typeof oCol === "string" && this.#owner.fields.includes(oCol)) {
|
|
23664
|
+
return parseInt($(`[data-bind="${oCol}"]`, this.#owner.template)[0].dataset.col);
|
|
23665
|
+
}
|
|
23666
|
+
else {
|
|
23667
|
+
throw `invalid ${oCol}`;
|
|
23668
|
+
}
|
|
23669
|
+
};
|
|
23670
|
+
|
|
23671
|
+
|
|
23672
|
+
|
|
23673
|
+
moveTo = (at) => {
|
|
23674
|
+
this.#owner.scrollTo(at);
|
|
23675
|
+
}
|
|
23676
|
+
}
|
|
23680
23677
|
|
|
23681
|
-
|
|
23682
|
-
|
|
23683
|
-
|
|
23684
|
-
|
|
23685
|
-
|
|
23686
|
-
|
|
23678
|
+
/**
|
|
23679
|
+
* button.filterOptions = [{
|
|
23680
|
+
* colnm: "userId",
|
|
23681
|
+
* data: [],
|
|
23682
|
+
* }]
|
|
23683
|
+
* button.
|
|
23684
|
+
*/
|
|
23685
|
+
class ngFiltering
|
|
23686
|
+
{
|
|
23687
|
+
#owner;
|
|
23688
|
+
#isFiltering;
|
|
23689
|
+
|
|
23690
|
+
constructor(owner) {
|
|
23691
|
+
this.#owner = owner;
|
|
23692
|
+
this.#isFiltering = false;
|
|
23687
23693
|
|
|
23688
|
-
|
|
23689
|
-
|
|
23690
|
-
|
|
23691
|
-
|
|
23692
|
-
|
|
23693
|
-
|
|
23694
|
+
const filterPanel = document.createElement("ng-filter-panel"); // ✅ 필터 패널 생성
|
|
23695
|
+
filterPanel.style.display = "none"; // ✅ 숨김 처리
|
|
23696
|
+
this.#owner.shadowRoot.appendChild(filterPanel); // ✅ Shadow DOM 내부에 추가
|
|
23697
|
+
}
|
|
23698
|
+
|
|
23699
|
+
initialize = () => {
|
|
23700
|
+
/**
|
|
23701
|
+
* 1. grid attr == filter : on();
|
|
23702
|
+
*/
|
|
23703
|
+
this.#isFiltering = false;
|
|
23704
|
+
this.#owner.data.clearFilter();
|
|
23694
23705
|
};
|
|
23695
23706
|
|
|
23696
|
-
|
|
23697
|
-
|
|
23698
|
-
|
|
23699
|
-
|
|
23707
|
+
isFiltering = () => {
|
|
23708
|
+
return this.#isFiltering;
|
|
23709
|
+
};
|
|
23710
|
+
|
|
23711
|
+
on = (v) => {
|
|
23712
|
+
|
|
23713
|
+
this.#isFiltering = true;
|
|
23714
|
+
const lastRowIndex = this.#getLastRowIndex();
|
|
23700
23715
|
|
|
23701
|
-
this.#
|
|
23716
|
+
this.#owner.body.querySelectorAll(".ng-table thead th, .ng-table thead td").forEach((td) => {
|
|
23717
|
+
const rowIndex = td.closest("tr")?.sectionRowIndex;
|
|
23718
|
+
if (rowIndex !== undefined && rowIndex + td.rowSpan - 1 === lastRowIndex) {
|
|
23719
|
+
const options = Array.from(this.#owner.activeTmpl.querySelectorAll(`[data-col="${td.dataset.col}"]`))
|
|
23720
|
+
.map(el => el.dataset.bind ? { colnm: el.dataset.bind, data: [] } : null)
|
|
23721
|
+
.filter(Boolean); // ✅ `null` 제거
|
|
23702
23722
|
|
|
23703
|
-
|
|
23723
|
+
if (options.length > 0) {
|
|
23724
|
+
td.querySelector("ng-filter-button")?.remove();
|
|
23704
23725
|
|
|
23705
|
-
|
|
23706
|
-
|
|
23707
|
-
|
|
23708
|
-
|
|
23709
|
-
|
|
23710
|
-
|
|
23711
|
-
|
|
23712
|
-
*/
|
|
23713
|
-
|
|
23714
|
-
//$('.ng-container .ng-table', this.#owner.body).offset({top:$('.ng-container .ng-table', this.#owner.body).offset().top});
|
|
23715
|
-
//$('.ng-container .ng-table', this.#owner.body).offset({top:$('.ng-container .ng-table', this.#owner.body).offset().top});
|
|
23716
|
-
//this.isLastPage = h > 0 ? true : false;
|
|
23726
|
+
const filterButton = document.createElement("ng-filter-button");
|
|
23727
|
+
td.appendChild(filterButton);
|
|
23728
|
+
filterButton.filterOptions = options;
|
|
23729
|
+
}
|
|
23730
|
+
}
|
|
23731
|
+
});
|
|
23732
|
+
};
|
|
23717
23733
|
|
|
23718
|
-
|
|
23719
|
-
|
|
23720
|
-
$("tr.nodata", this.#owner.body).height(0);
|
|
23721
|
-
|
|
23722
|
-
var h = 47;//this.#getTrHeight();
|
|
23723
|
-
$('.ng-container-body tbody.bindable tr', this.#owner.body).not('.nodata').each((i,tr) => {
|
|
23724
|
-
h += $(tr).height();
|
|
23725
|
-
});
|
|
23734
|
+
off = () => {
|
|
23735
|
+
this.#isFiltering = false;
|
|
23726
23736
|
|
|
23727
|
-
|
|
23728
|
-
|
|
23737
|
+
this.#owner.body.querySelectorAll(".ng-table ng-filter-button").forEach((el) => {
|
|
23738
|
+
el.remove(); // ✅ 요소 삭제
|
|
23739
|
+
});
|
|
23729
23740
|
};
|
|
23730
23741
|
|
|
23731
|
-
|
|
23732
|
-
|
|
23733
|
-
|
|
23734
|
-
|
|
23735
|
-
|
|
23736
|
-
//if (this.#owner.isLastPage) {
|
|
23737
|
-
//if (this.#isLastPage) {
|
|
23742
|
+
/**
|
|
23743
|
+
clear = () => {
|
|
23744
|
+
console.log(this.#owner.dataManager.rawRecords);
|
|
23745
|
+
this.#owner.dataManager.rawRecords.map(item => { item.__ng.filtered = false; });
|
|
23738
23746
|
|
|
23739
|
-
//if (this.#owner.isLastPage) {
|
|
23740
|
-
this.#createTR();
|
|
23741
|
-
//}
|
|
23742
|
-
/**
|
|
23743
|
-
if ($(".ng-container-body tbody.bindable tr.nodata", this.#owner.body).height() > 0) {
|
|
23744
|
-
this.#createTR();
|
|
23745
|
-
} */
|
|
23746
23747
|
|
|
23747
|
-
this.#
|
|
23748
|
+
this.#records = this.#owner.dataManager.rawRecords.filter(item => { return !item.__ng.deleted && !item.__ng.filtered; } );
|
|
23749
|
+
return this.#records;
|
|
23750
|
+
}
|
|
23751
|
+
|
|
23752
|
+
refresh = () => {
|
|
23753
|
+
this.#records = this.#owner.dataManager.rawRecords.filter(item => { return !item.__ng.deleted && !item.__ng.filtered; } );
|
|
23754
|
+
//this.#records.forEach((o,i) => { o.__ng.rowidx = i; });
|
|
23755
|
+
//this.getValidData().forEach((o,i) => { o.__ng._[ninegrid.ROW.ORDER] = i + 1; });
|
|
23756
|
+
this.#resetOrder();
|
|
23757
|
+
return this.#records;
|
|
23758
|
+
} */
|
|
23759
|
+
|
|
23760
|
+
|
|
23761
|
+
/**
|
|
23762
|
+
* oFilter : {
|
|
23763
|
+
* col1 : [],
|
|
23764
|
+
* col2 : []
|
|
23765
|
+
* }
|
|
23766
|
+
*/
|
|
23767
|
+
set = (oFilter) => {
|
|
23748
23768
|
|
|
23769
|
+
this.on();
|
|
23770
|
+
|
|
23771
|
+
// ✅ JSON 변환 (배열 → 객체)
|
|
23772
|
+
let jsonFilter = Array.isArray(oFilter)
|
|
23773
|
+
? Object.fromEntries(Object.keys(oFilter[0]).map(key => [key, [...new Set(oFilter.map(item => item[key]))]]))
|
|
23774
|
+
: oFilter;
|
|
23749
23775
|
|
|
23750
|
-
|
|
23751
|
-
/**
|
|
23752
|
-
if (this.#owner.isFirstPage || this.#owner.isLastPage) {
|
|
23753
|
-
var h = this.#owner.body.querySelector("ng-vscrollbar").bodyHeight - $(".ng-container-body .ng-table", this.#owner.body).height() + $('.ng-container-body .ng-table tr.nodata', this.#owner.body).height();
|
|
23754
|
-
$(".ng-container tbody.bindable tr.nodata", this.#owner.body).height(h);
|
|
23755
|
-
}*/
|
|
23756
|
-
//$(".ng-container tbody.bindable tr.nodata", this.#owner.body).height(700);
|
|
23757
|
-
|
|
23758
|
-
if (this.#owner.isLastPage) ;
|
|
23759
|
-
|
|
23776
|
+
this.#owner.data.clearFilter();
|
|
23760
23777
|
|
|
23761
|
-
|
|
23778
|
+
Object.entries(jsonFilter).forEach(([key, arr]) => {
|
|
23779
|
+
const idx = this.#owner.fields.indexOf(key);
|
|
23780
|
+
|
|
23781
|
+
// ✅ 숫자 판별 및 변환
|
|
23782
|
+
if (this.#owner.data.getValidData().some(o => typeof o.v[idx] === "number")) {
|
|
23783
|
+
arr = arr.map(Number);
|
|
23784
|
+
}
|
|
23762
23785
|
|
|
23786
|
+
// ✅ 필터 적용
|
|
23787
|
+
this.#owner.data.getValidData()
|
|
23788
|
+
.filter(m => arr.nineBinarySearch(m.v[idx] || '') < 0)
|
|
23789
|
+
.forEach(m => { m.__ng.filtered = true; });
|
|
23790
|
+
});
|
|
23763
23791
|
|
|
23764
|
-
//this.nodata = h > 0 ? true : false;
|
|
23765
23792
|
|
|
23766
|
-
|
|
23767
|
-
};
|
|
23768
|
-
|
|
23769
|
-
#refreshData = () => {
|
|
23793
|
+
this.#owner.data.refreshFilter();
|
|
23770
23794
|
|
|
23771
|
-
|
|
23772
|
-
|
|
23773
|
-
|
|
23774
|
-
|
|
23775
|
-
|
|
23776
|
-
|
|
23777
|
-
|
|
23778
|
-
this.#ing = false;
|
|
23779
|
-
|
|
23780
|
-
// 4. row resize
|
|
23781
|
-
var trsBody = $(".ng-container-body tbody.bindable tr", this.#owner.body).not(".nodata");
|
|
23782
|
-
var trsLeft = $(".ng-container-left tbody.bindable tr", this.#owner.body).not(".nodata");
|
|
23783
|
-
var trsRight= $(".ng-container-right tbody.bindable tr", this.#owner.body).not(".nodata");
|
|
23784
|
-
|
|
23785
|
-
if (trsBody.length > 0) {
|
|
23786
|
-
var startRow = parseInt(trsBody[0].dataset.row * this.#owner.template.length);
|
|
23787
|
-
|
|
23788
|
-
trsBody.each((i, tr) => {
|
|
23789
|
-
var h = this.#owner.matrix.getHeight(startRow + i);// || 32;
|
|
23795
|
+
// ✅ 필터 버튼 초기화
|
|
23796
|
+
this.#owner.shadowRoot.querySelectorAll("ng-filter-button").forEach(el => {
|
|
23797
|
+
el.filterOptions.forEach(opt => { opt.data = []; });
|
|
23798
|
+
});
|
|
23799
|
+
|
|
23800
|
+
Object.entries(jsonFilter).forEach(([key, arr]) => {
|
|
23801
|
+
this.#owner.shadowRoot.querySelectorAll("ng-filter-button").forEach(el => {
|
|
23790
23802
|
|
|
23791
|
-
|
|
23792
|
-
$("canvas.chart", trsLeft.eq(i)).css({ "height" : h-4 });
|
|
23793
|
-
$("canvas.chart", trsRight.eq(i)).css({ "height" : h-4 });
|
|
23803
|
+
let options = el.filterOptions;
|
|
23794
23804
|
|
|
23795
|
-
|
|
23796
|
-
|
|
23797
|
-
trsRight.eq(i).css({ "height" : h }).height(h);
|
|
23805
|
+
options.forEach(opt => {
|
|
23806
|
+
if (opt.colnm === key) opt.data = arr;
|
|
23798
23807
|
});
|
|
23799
|
-
}
|
|
23800
|
-
|
|
23801
|
-
this.#owner.cell.refresh();
|
|
23802
|
-
|
|
23803
|
-
//row resize
|
|
23804
|
-
$('ng-row-indicator', this.#owner.body).each((i,el) => {
|
|
23805
|
-
el.refresh();
|
|
23806
|
-
});
|
|
23807
|
-
|
|
23808
|
-
//5. nodata resize
|
|
23809
|
-
var h = this.#height.body - this.#height.thead - this.#height.tfoot - this.#getTrHeight();
|
|
23810
|
-
$(".ng-container tbody.bindable tr.nodata", this.#owner.body).height(h);
|
|
23811
|
-
|
|
23812
|
-
//this.isLastPage = h > 0 ? true : false;
|
|
23813
23808
|
|
|
23814
|
-
|
|
23815
|
-
|
|
23809
|
+
el.filterOptions = options;
|
|
23810
|
+
});
|
|
23811
|
+
});
|
|
23812
|
+
|
|
23813
|
+
|
|
23814
|
+
this.#owner.scrollTo_V1(0);
|
|
23815
|
+
|
|
23816
|
+
this.#owner.paging.reset();
|
|
23817
|
+
};
|
|
23818
|
+
|
|
23819
|
+
#getLastRowIndex = (v = "thead") =>
|
|
23820
|
+
[...this.#owner.body.querySelectorAll(`.ng-table ${v}`)]
|
|
23821
|
+
.reduce((maxIndex, el) => Math.max(el.rows.length - 1, maxIndex), 0);
|
|
23816
23822
|
|
|
23817
|
-
|
|
23818
|
-
|
|
23819
|
-
this.#owner.paging.totalCount = this.#owner.data.countNF();
|
|
23820
|
-
|
|
23821
|
-
this.#owner.body.querySelector("ng-vscrollbar").refresh();
|
|
23823
|
+
}
|
|
23822
23824
|
|
|
23823
|
-
|
|
23824
|
-
|
|
23825
|
-
|
|
23826
|
-
|
|
23827
|
-
|
|
23828
|
-
|
|
23829
|
-
|
|
23830
|
-
|
|
23831
|
-
this.#owner.body.querySelector(".ng-container-left").style.top = "0px";
|
|
23832
|
-
this.#owner.body.querySelector(".ng-container-right").style.top = "0px";
|
|
23833
|
-
this.#owner.body.querySelector(".ng-container-body").style.top = "0px";
|
|
23834
|
-
|
|
23835
|
-
setTimeout(() => {
|
|
23836
|
-
this.#owner.body.querySelector(".ng-container-left").style.position = "relative";
|
|
23837
|
-
this.#owner.body.querySelector(".ng-container-right").style.position = "relative";
|
|
23838
|
-
this.#owner.body.querySelector(".ng-container-body").style.position = "relative";
|
|
23839
|
-
this.#owner.body.querySelector(".ng-container-left").style.top = "0px";
|
|
23840
|
-
this.#owner.body.querySelector(".ng-container-right").style.top = "0px";
|
|
23841
|
-
this.#owner.body.querySelector(".ng-container-body").style.top = "0px";
|
|
23842
|
-
}, 1000); */
|
|
23825
|
+
class ngFilterButton extends HTMLElement
|
|
23826
|
+
{
|
|
23827
|
+
#owner;
|
|
23828
|
+
#filterOptions;
|
|
23829
|
+
|
|
23830
|
+
constructor () {
|
|
23831
|
+
super();
|
|
23832
|
+
}
|
|
23843
23833
|
|
|
23844
|
-
|
|
23834
|
+
connectedCallback() {
|
|
23835
|
+
this.#owner = this.getRootNode().host;//this.closest("nine-grid");
|
|
23845
23836
|
|
|
23846
|
-
|
|
23847
|
-
this
|
|
23848
|
-
|
|
23849
|
-
|
|
23837
|
+
this.removeEventListener("click", this.#onClick);
|
|
23838
|
+
this.addEventListener("click", this.#onClick);
|
|
23839
|
+
};
|
|
23840
|
+
|
|
23841
|
+
get filterOptions() {
|
|
23842
|
+
return this.#filterOptions;
|
|
23843
|
+
};
|
|
23844
|
+
set filterOptions(v) {
|
|
23845
|
+
this.#filterOptions = v;
|
|
23846
|
+
this.classList.toggle('filtered', this.#filterOptions.some(item => item.data.length > 0));
|
|
23850
23847
|
}
|
|
23851
23848
|
|
|
23852
|
-
#
|
|
23849
|
+
#onClick = (e) => {
|
|
23850
|
+
e.preventDefault();
|
|
23851
|
+
e.stopPropagation();
|
|
23853
23852
|
|
|
23854
|
-
|
|
23855
|
-
|
|
23856
|
-
rows.push(this.#rawIndex + parseInt(tr.sectionRowIndex / this.#owner.template.length));
|
|
23857
|
-
});
|
|
23858
|
-
|
|
23859
|
-
rows = [...new Set(rows)];
|
|
23860
|
-
|
|
23861
|
-
this.#owner.body.querySelectorAll(".ng-container tbody.bindable tr:not(.nodata)").forEach(tr => {
|
|
23862
|
-
const index = parseInt(tr.sectionRowIndex / this.#owner.template.length);
|
|
23853
|
+
const panel = this.#owner.shadowRoot.querySelector("ng-filter-panel");
|
|
23854
|
+
const col = this.closest("th,td")?.dataset.col; // ✅ `?.` 활용하여 안전한 접근
|
|
23863
23855
|
|
|
23864
|
-
|
|
23865
|
-
|
|
23866
|
-
|
|
23867
|
-
for (const cell of tr.cells) {
|
|
23868
|
-
cell.dataset.row = tr.dataset.row;
|
|
23869
|
-
cell.dataset.matrixRow = tr.dataset.matrixRow;
|
|
23870
|
-
}
|
|
23871
|
-
});
|
|
23872
|
-
|
|
23856
|
+
panel.col === col ? panel.close() : panel.open(this);
|
|
23857
|
+
};
|
|
23858
|
+
}
|
|
23873
23859
|
|
|
23874
|
-
|
|
23875
|
-
|
|
23860
|
+
class ngFilterPanel extends HTMLElement
|
|
23861
|
+
{
|
|
23862
|
+
#owner;
|
|
23863
|
+
#button;
|
|
23864
|
+
#timer;
|
|
23865
|
+
|
|
23866
|
+
constructor () {
|
|
23867
|
+
super();
|
|
23868
|
+
this.attachShadow({ mode: 'open' });
|
|
23869
|
+
}
|
|
23876
23870
|
|
|
23877
|
-
|
|
23878
|
-
tr.data = data;
|
|
23879
|
-
});
|
|
23880
|
-
});
|
|
23881
|
-
|
|
23882
|
-
this.#rawIndex = parseInt(this.#owner.body.querySelector(".ng-container-body tbody.bindable tr:first-of-type").getAttribute("data-row"));
|
|
23883
|
-
|
|
23884
|
-
this.#owner.dataManager.viewRecords.rawIndex = this.#rawIndex;
|
|
23871
|
+
connectedCallback() {
|
|
23885
23872
|
|
|
23873
|
+
this.#owner = this.getRootNode().host;
|
|
23886
23874
|
|
|
23887
|
-
this
|
|
23875
|
+
const cssPath = this.getRootNode().host.closest("nine-grid").getAttribute("css-path") || "";
|
|
23876
|
+
|
|
23877
|
+
this.shadowRoot.innerHTML = `
|
|
23878
|
+
<style>
|
|
23879
|
+
@import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/ngFilterPanel.css";
|
|
23880
|
+
${ninegrid.getCustomPath(this,"ngFilterPanel.css")}
|
|
23881
|
+
</style>
|
|
23882
|
+
|
|
23883
|
+
<div class="head">
|
|
23884
|
+
<input type="text">
|
|
23885
|
+
</div>
|
|
23886
|
+
<nine-grid class="simple filter" css-path="${cssPath}" select-type="row" auto-fit-col="true" col-indicator-type="collapse">
|
|
23887
|
+
<table style="display: none;">
|
|
23888
|
+
<colgroup>
|
|
23889
|
+
<col width="180" />
|
|
23890
|
+
<col width="30" />
|
|
23891
|
+
</colgroup>
|
|
23892
|
+
<tbody>
|
|
23893
|
+
<tr style="height: 24px;">
|
|
23894
|
+
<td data-bind="LVL" data-expr="data.DATA2">
|
|
23895
|
+
<ng-tree-item />
|
|
23896
|
+
</td>
|
|
23897
|
+
<td data-bind="CHK">
|
|
23898
|
+
<ng-checkbox update-row-state="false" visible="data.LVL!=1" selected-border-color="white" />
|
|
23899
|
+
</td>
|
|
23900
|
+
</tr>
|
|
23901
|
+
</tbody>
|
|
23902
|
+
</table>
|
|
23903
|
+
</nine-grid>
|
|
23904
|
+
|
|
23905
|
+
<div>
|
|
23906
|
+
<label><input type="checkbox" checked>Select All</label>
|
|
23907
|
+
<button id="btnOk">OK</button>
|
|
23908
|
+
<button id="btnCancel">Cancel</button>
|
|
23909
|
+
</div>
|
|
23910
|
+
`;
|
|
23888
23911
|
|
|
23889
|
-
|
|
23890
|
-
this
|
|
23891
|
-
|
|
23912
|
+
this.shadowRoot.querySelector("input[type=text]").addEventListener("input", this.#onInput);
|
|
23913
|
+
this.shadowRoot.querySelector("input[type=checkbox]").addEventListener("change", this.#onSelectAll);
|
|
23914
|
+
this.shadowRoot.querySelector("#btnOk").addEventListener("click", this.#onOk);
|
|
23915
|
+
this.shadowRoot.querySelector("#btnCancel").addEventListener("click", this.#onCancel);
|
|
23916
|
+
};
|
|
23917
|
+
|
|
23918
|
+
#onOk = (e) => {
|
|
23919
|
+
|
|
23920
|
+
const grd = this.shadowRoot.querySelector("nine-grid");
|
|
23921
|
+
|
|
23922
|
+
this.classList.add("loading");
|
|
23892
23923
|
|
|
23924
|
+
setTimeout(() => {
|
|
23925
|
+
const [LVL_IDX, CHK_IDX, COLNM_IDX, DATA_IDX] = ["LVL", "CHK", "COLNM", "DATA"].map(k => grd.fields.indexOf(k));
|
|
23926
|
+
const checked = grd.data.getValidDataNF().filter(m => m.v[LVL_IDX] === 2 && m.v[CHK_IDX] === "Y");
|
|
23927
|
+
const filterOptions = checked.length > 0 ? [...new Set(checked.map(m => m.v[COLNM_IDX]))].map(v => ({
|
|
23928
|
+
colnm: v,
|
|
23929
|
+
data: [...new Set(grd.data.getValidData().filter(m => m.v[CHK_IDX] === "Y" && m.v[COLNM_IDX] === v).map(m => m.v[DATA_IDX] || ''))].sort()
|
|
23930
|
+
})) : [];
|
|
23931
|
+
|
|
23932
|
+
|
|
23933
|
+
this.#button.filterOptions = filterOptions;
|
|
23893
23934
|
|
|
23894
|
-
|
|
23895
|
-
|
|
23935
|
+
const oParam = Object.fromEntries(
|
|
23936
|
+
[...this.#owner.body.querySelectorAll("ng-filter-button")]
|
|
23937
|
+
.flatMap(el => el.filterOptions)
|
|
23938
|
+
.filter(opt => opt.data.length > 0)
|
|
23939
|
+
.map(opt => [opt.colnm, opt.data])
|
|
23940
|
+
);
|
|
23941
|
+
|
|
23942
|
+
this.#owner.filtering.set(oParam);
|
|
23896
23943
|
|
|
23897
|
-
|
|
23898
|
-
|
|
23899
|
-
|
|
23900
|
-
getVisibleFirstRow = () => {
|
|
23901
|
-
var tr = this.#owner.body.querySelector(".ng-container-body tbody.bindable tr:first-child");
|
|
23902
|
-
return parseInt(tr.dataset.row);
|
|
23944
|
+
this.classList.remove("loading");
|
|
23945
|
+
this.style.display = 'none';
|
|
23946
|
+
});
|
|
23903
23947
|
};
|
|
23904
23948
|
|
|
23905
|
-
getVisibleLastRow = () => {
|
|
23906
|
-
var trs = this.#owner.body.querySelectorAll(".ng-container-body tbody.bindable tr:not(.nodata)");
|
|
23907
|
-
return (trs.length > 0) ? parseInt(trs[trs.length - 1].dataset.row) : -1;
|
|
23908
|
-
};
|
|
23909
23949
|
|
|
23910
|
-
getRowHeight = (rowIndex) => {
|
|
23911
|
-
let h = 0;
|
|
23912
|
-
|
|
23913
|
-
for (var i = 0; i < this.#owner.template.length; i++) {
|
|
23914
|
-
h += this.#owner.matrix.getHeight(parseInt(rowIndex * this.#owner.template.length + i));
|
|
23915
|
-
}
|
|
23916
|
-
|
|
23917
|
-
return h;
|
|
23918
|
-
};
|
|
23919
23950
|
|
|
23920
|
-
|
|
23921
|
-
|
|
23922
|
-
return (!tbody || !tbody.style || !tbody.style.transform) ? 0 : parseFloat(tbody.style.transform.replace("translateY(", "").replace(")", ""));
|
|
23951
|
+
#onCancel = (e) => {
|
|
23952
|
+
this.style.display = 'none';
|
|
23923
23953
|
};
|
|
23924
|
-
|
|
23925
|
-
|
|
23926
|
-
|
|
23927
|
-
|
|
23928
|
-
|
|
23929
|
-
|
|
23930
|
-
|
|
23931
|
-
|
|
23954
|
+
|
|
23955
|
+
#onSelectAll = (e) => {
|
|
23956
|
+
const grd = this.shadowRoot.querySelector("nine-grid");
|
|
23957
|
+
const idx = grd.fields.indexOf("CHK");
|
|
23958
|
+
const isChecked = e.target.checked; // ✅ jQuery 없이 `checked` 값 가져오기
|
|
23959
|
+
|
|
23960
|
+
grd.data.getValidData().forEach(m => {
|
|
23961
|
+
m.v[idx] = isChecked ? "Y" : "N"; // ✅ `Y` 또는 `N` 값 설정
|
|
23962
|
+
});
|
|
23963
|
+
|
|
23964
|
+
grd.refreshData();
|
|
23932
23965
|
};
|
|
23933
|
-
|
|
23934
|
-
fitPage = () => {
|
|
23935
|
-
const lastRow = this.getVisibleLastRow();
|
|
23936
|
-
const totalSpace = this.getTotalSpace();
|
|
23937
|
-
|
|
23938
|
-
/**
|
|
23939
|
-
* 마지막 페이지 정리
|
|
23940
|
-
*/
|
|
23941
|
-
if (lastRow == this.#owner.data.count() - 1) {
|
|
23942
|
-
var h = 0;
|
|
23943
|
-
for (var i = lastRow; i >= 0; i--) {
|
|
23944
|
-
h += this.getRowHeight(i);
|
|
23945
|
-
|
|
23946
|
-
if (h > totalSpace) {
|
|
23947
|
-
this.#owner.scrollTo(i + 1);
|
|
23948
|
-
break;
|
|
23949
|
-
}
|
|
23950
|
-
}
|
|
23951
|
-
}
|
|
23952
|
-
}
|
|
23953
|
-
/**
|
|
23954
|
-
#isLastPage = () => {
|
|
23955
|
-
const arr = this.#owner.body.querySelectorAll(".ng-container-body tbody.bindable tr:not(.nodata)");
|
|
23956
|
-
if (arr.length <= 0) return null;
|
|
23957
23966
|
|
|
23958
|
-
return arr[arr.length - 1].dataset.row == this.#owner.data.count() - 1 ? true : false;
|
|
23959
|
-
}*/
|
|
23960
|
-
|
|
23961
23967
|
|
|
23962
|
-
/**
|
|
23963
|
-
* grid.selectCell(row, colnm, subrow) => scrollTo
|
|
23964
|
-
* grid.selectCol(fromColNm, toColNm)
|
|
23965
|
-
* grid.selectRow(row) => scrollTo
|
|
23966
|
-
* grid.selectArea(row1, col1, row2, col2) => scrollTo
|
|
23967
|
-
*
|
|
23968
|
-
* grid.clearSelect()
|
|
23969
|
-
*
|
|
23970
|
-
* grid.selection.currentCell;
|
|
23971
|
-
* grid.selection.currentRow;
|
|
23972
|
-
* grid.selection.currentSubRow;
|
|
23973
|
-
* grid.selection.currentCol;
|
|
23974
|
-
* grid.selection.firstRow
|
|
23975
|
-
* grid.selection.firstCol
|
|
23976
|
-
* grid.selection.lastRow
|
|
23977
|
-
* grid.selection.lastCol
|
|
23978
|
-
*/
|
|
23979
23968
|
|
|
23980
|
-
|
|
23981
|
-
|
|
23982
|
-
const row1 = this.#getRowIndex(oRow1);
|
|
23983
|
-
const row2 = this.#getRowIndex(oRow2);
|
|
23984
|
-
const col1 = this.#getColIndex(oCol1);
|
|
23985
|
-
const col2 = this.#getColIndex(oCol2);
|
|
23986
|
-
const matrixRow1= parseInt(row1 * this.#owner.template.length);
|
|
23987
|
-
const matrixRow2= parseInt(row2 * this.#owner.template.length) + this.#owner.template.length - 1;
|
|
23988
|
-
|
|
23989
|
-
this.#owner.row.at = row1;
|
|
23969
|
+
#onInput = (e) => {
|
|
23970
|
+
const grd = this.shadowRoot.querySelector("nine-grid");
|
|
23990
23971
|
|
|
23991
|
-
|
|
23992
|
-
};
|
|
23993
|
-
|
|
23994
|
-
selectRow = (oRow1, oRow2) => {
|
|
23995
|
-
|
|
23996
|
-
const row1 = this.#getRowIndex(oRow1);
|
|
23997
|
-
const row2 = ninegrid.isNull(oRow2) ? row1 : this.#getRowIndex(oRow2);
|
|
23998
|
-
const matrixRow1= parseInt(row1 * this.#owner.template.length);
|
|
23999
|
-
const matrixRow2= parseInt(row2 * this.#owner.template.length) + this.#owner.template.length - 1;
|
|
23972
|
+
grd.classList.add("loading");
|
|
24000
23973
|
|
|
24001
|
-
|
|
23974
|
+
const data = grd.dataManager.rawRecords;
|
|
23975
|
+
data.forEach(m => { m.__ng.filtered = false; });
|
|
24002
23976
|
|
|
24003
|
-
|
|
24004
|
-
|
|
24005
|
-
|
|
24006
|
-
selectCol = (oCol1, oCol2) => {
|
|
24007
|
-
const col1 = this.#getColIndex(oCol1);
|
|
24008
|
-
const col2 = ninegrid.isNull(oCol2) ? col1 : this.#getColIndex(oCol2);
|
|
24009
|
-
const matrixRow1= 0;
|
|
24010
|
-
const matrixRow2= parseInt(this.#owner.data.count() * this.#owner.template.length - 1);
|
|
23977
|
+
const v = e.target.value.toLowerCase(); // ✅ jQuery 없이 값 가져오기
|
|
23978
|
+
const [LVL_IDX, DATA_IDX] = ["LVL", "DATA"].map(field => grd.fields.indexOf(field));
|
|
24011
23979
|
|
|
24012
|
-
|
|
24013
|
-
|
|
24014
|
-
|
|
24015
|
-
|
|
24016
|
-
|
|
24017
|
-
const row = this.#getRowIndex(oRow);
|
|
24018
|
-
const col = this.#getColIndex(oCol);
|
|
24019
|
-
const matrixRow = parseInt(row * this.#owner.template.length) + ninegrid.nvl(subrow, 0);
|
|
24020
|
-
|
|
24021
|
-
this.#owner.row.at = row;
|
|
23980
|
+
data.forEach(m => {
|
|
23981
|
+
m.__ng.filtered = m.v[LVL_IDX] === 2 && !String(m.v[DATA_IDX] || "").toLowerCase().includes(v);
|
|
23982
|
+
});
|
|
23983
|
+
|
|
23984
|
+
grd.data.resetRecords();
|
|
24022
23985
|
|
|
24023
|
-
(
|
|
23986
|
+
clearTimeout(this.#timer);
|
|
23987
|
+
this.#timer = setTimeout(() => {
|
|
23988
|
+
grd.dataManager.viewRecords.reset();
|
|
23989
|
+
grd.dataManager.viewRecords.touch();
|
|
23990
|
+
}, 200);
|
|
24024
23991
|
};
|
|
24025
23992
|
|
|
24026
|
-
|
|
24027
|
-
|
|
24028
|
-
|
|
24029
|
-
}
|
|
24030
|
-
else if (typeof oRow === "function") {
|
|
24031
|
-
return this.#owner.data.findIndex(oRow);
|
|
24032
|
-
}
|
|
24033
|
-
else {
|
|
24034
|
-
throw `invalid ${oRow}`;
|
|
24035
|
-
}
|
|
23993
|
+
close = () => {
|
|
23994
|
+
this.col = null;
|
|
23995
|
+
this.style.display = 'none';
|
|
24036
23996
|
};
|
|
24037
|
-
|
|
24038
|
-
|
|
24039
|
-
|
|
24040
|
-
|
|
24041
|
-
|
|
24042
|
-
|
|
24043
|
-
|
|
24044
|
-
}
|
|
24045
|
-
|
|
24046
|
-
|
|
24047
|
-
|
|
23997
|
+
|
|
23998
|
+
open = (filterButton) => {
|
|
23999
|
+
|
|
24000
|
+
/** 위치 */
|
|
24001
|
+
const cell = filterButton.closest("th,td");
|
|
24002
|
+
|
|
24003
|
+
const { left: btnLeft } = filterButton.getBoundingClientRect();
|
|
24004
|
+
const { left: ownerLeft, width: ownerWidth, top: ownerTop } = this.#owner.getBoundingClientRect();
|
|
24005
|
+
const { top: cellTop, height: cellHeight } = cell.getBoundingClientRect();
|
|
24006
|
+
const { width: targetWidth } = this.getBoundingClientRect();
|
|
24007
|
+
|
|
24008
|
+
let l = Math.max(0, btnLeft - ownerLeft);
|
|
24009
|
+
l = Math.min(l, ownerWidth - targetWidth - 5);
|
|
24010
|
+
|
|
24011
|
+
const t = cellTop + cellHeight - ownerTop;
|
|
24012
|
+
|
|
24013
|
+
Object.assign(this.style, { left: `${l}px`, top: `${t}px`, display: "flex" });
|
|
24014
|
+
this.classList.add("loading");
|
|
24015
|
+
|
|
24016
|
+
this.shadowRoot.querySelector("input[type=text]").value = "";
|
|
24017
|
+
|
|
24018
|
+
setTimeout(() => {
|
|
24019
|
+
const data = this.#owner.data.getValidDataNF();
|
|
24020
|
+
const col = cell.dataset.col;
|
|
24021
|
+
this.col = col;
|
|
24022
|
+
this.#button = filterButton;
|
|
24023
|
+
|
|
24024
|
+
const ds = filterButton.filterOptions.map((opt, i) => {
|
|
24025
|
+
const groupLabel = `<span class="group">${cell.textContent}${filterButton.filterOptions.length > 1 ? ` #${i + 1} (${opt.colnm})` : ""}</span>`;
|
|
24026
|
+
|
|
24027
|
+
const cellEl = this.#owner.activeTmpl.querySelector(`[data-col="${col}"][data-bind="${opt.colnm}"]`);
|
|
24028
|
+
const expr = cellEl?.getAttribute("data-expr");
|
|
24029
|
+
const exprFunc = expr ? this.#owner.exprFunction(expr) : null;
|
|
24030
|
+
|
|
24031
|
+
const data2 = data.map(rowData => {
|
|
24032
|
+
const idx = this.#owner.fields.indexOf(opt.colnm);
|
|
24033
|
+
return expr ? { v: rowData.v[idx], v2: exprFunc(this.#owner.data.conv(rowData), rowData.__ng.rowidx, this.#owner.data) } : { v: rowData.v[idx], v2: rowData.v[idx] };
|
|
24034
|
+
});
|
|
24035
|
+
|
|
24036
|
+
return [
|
|
24037
|
+
{ LVL: 1, CHK: "N", DATA2: groupLabel },
|
|
24038
|
+
...[...new Set(data2.map(JSON.stringify))]
|
|
24039
|
+
.map(JSON.parse)
|
|
24040
|
+
.sort((a, b) => (a.v2 || "") > (b.v2 || "") ? 1 : (a.v2 || "") < (b.v2 || "") ? -1 : 0)
|
|
24041
|
+
.map(o => ({
|
|
24042
|
+
LVL: 2,
|
|
24043
|
+
DATA: o.v,
|
|
24044
|
+
DATA2: o.v2 || ` <span class="empty">(empty)</span> ${o.v}`,
|
|
24045
|
+
COLNM: opt.colnm,
|
|
24046
|
+
CHK: opt.data.length === 0 || opt.data.nineBinarySearch(o.v || "") >= 0 ? "Y" : "N",
|
|
24047
|
+
}))
|
|
24048
|
+
];
|
|
24049
|
+
}).flat();
|
|
24050
|
+
|
|
24051
|
+
const grd = this.shadowRoot.querySelector("nine-grid");
|
|
24052
|
+
grd.fields.add(["DATA","DATA2","COLNM"]);
|
|
24053
|
+
grd.data.set(ds);
|
|
24054
|
+
|
|
24055
|
+
// ✅ 데이터 필터링 및 체크 상태 결정
|
|
24056
|
+
const checkbox = this.shadowRoot.querySelector("input[type=checkbox]");
|
|
24057
|
+
checkbox.checked = grd.data.getValidData().every(item => !(item.LVL === 2 && item.CHK !== "Y"));
|
|
24058
|
+
|
|
24059
|
+
this.shadowRoot.querySelector("input").focus();
|
|
24060
|
+
this.classList.remove("loading");
|
|
24061
|
+
});
|
|
24048
24062
|
};
|
|
24049
|
-
|
|
24050
|
-
|
|
24051
|
-
|
|
24052
|
-
moveTo = (at) => {
|
|
24053
|
-
this.#owner.scrollTo(at);
|
|
24054
|
-
}
|
|
24055
24063
|
}
|
|
24056
24064
|
|
|
24065
|
+
|
|
24066
|
+
customElements.define("ng-filter-button", ngFilterButton);
|
|
24067
|
+
customElements.define("ng-filter-panel", ngFilterPanel);
|
|
24068
|
+
|
|
24057
24069
|
class ninegridContainer extends HTMLElement
|
|
24058
24070
|
{
|
|
24059
24071
|
#colResizer;
|
|
@@ -27305,9 +27317,9 @@ class aiMessage extends HTMLElement
|
|
|
27305
27317
|
</style>
|
|
27306
27318
|
|
|
27307
27319
|
<div class="chat-message">
|
|
27308
|
-
<
|
|
27320
|
+
<span title="${this.#message}" class="message">
|
|
27309
27321
|
${this.#message}
|
|
27310
|
-
</
|
|
27322
|
+
</span>
|
|
27311
27323
|
<span class="more" style="position:relative;"><a href="#">more</a></span>
|
|
27312
27324
|
</div>
|
|
27313
27325
|
|
|
@@ -27330,6 +27342,8 @@ class aiMessage extends HTMLElement
|
|
|
27330
27342
|
set data(v) {
|
|
27331
27343
|
console.log(v); }
|
|
27332
27344
|
|
|
27345
|
+
|
|
27346
|
+
|
|
27333
27347
|
#init = () => {
|
|
27334
27348
|
|
|
27335
27349
|
const html = `
|
|
@@ -27366,21 +27380,7 @@ class aiMessage extends HTMLElement
|
|
|
27366
27380
|
alert(this.#message);
|
|
27367
27381
|
});
|
|
27368
27382
|
|
|
27369
|
-
|
|
27370
|
-
const elMessage = this.shadowRoot.querySelector(".message");
|
|
27371
|
-
const elMore = this.shadowRoot.querySelector(".more");
|
|
27372
|
-
|
|
27373
|
-
console.log(elMessage.scrollWidth, elMessage.clientWidth);
|
|
27374
|
-
|
|
27375
|
-
elMore.style.display = "flex";
|
|
27376
|
-
//elMore.style.position = "absolute";
|
|
27377
|
-
|
|
27378
|
-
console.log(elMessage.scrollWidth, elMessage.clientWidth);
|
|
27379
|
-
|
|
27380
|
-
//elMore.style.display = (elMessage.scrollWidth > elMessage.clientWidth) ? "flex" : "none";
|
|
27381
|
-
if (elMessage.scrollWidth > elMessage.clientWidth) ;
|
|
27382
|
-
}, 100);
|
|
27383
|
-
|
|
27383
|
+
this.shadowRoot.querySelector(".more").style.display = (ninegrid.isEllipsis(this.shadowRoot.querySelector(".message"))) ? "flex" : "none";
|
|
27384
27384
|
};
|
|
27385
27385
|
}
|
|
27386
27386
|
|