ninegrid2 6.245.0 → 6.247.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.
@@ -18053,26 +18053,6 @@ class ngFilterPanel extends HTMLElement
18053
18053
  this.classList.add("loading");
18054
18054
 
18055
18055
  setTimeout(() => {
18056
-
18057
- /**
18058
- const LVL_IDX = grd.fields.indexOf("LVL");
18059
- const CHK_IDX = grd.fields.indexOf("CHK");
18060
- const COLNM_IDX = grd.fields.indexOf("COLNM");
18061
- const DATA_IDX = grd.fields.indexOf("DATA");
18062
-
18063
- const checked = grd.data.getValidDataNF().filter(m => { return m.v[LVL_IDX] == 2 && m.v[CHK_IDX] == "Y"; });
18064
- //const unchecked = grd.data.getValidDataNF().filter(m => { return m.v[LVL_IDX] == 2 && m.v[CHK_IDX] != "Y"; });
18065
-
18066
- var filterOptions = [];
18067
- if (checked.length > 0) {
18068
-
18069
- [...new Set(checked.map(m => { return m.v[COLNM_IDX] }))].forEach(v => {
18070
- filterOptions.push({
18071
- colnm : v,
18072
- data : [...new Set(grd.data.getValidData().filter(m => { return m.v[CHK_IDX] == "Y" && m.v[COLNM_IDX] == v; }).map(m => { return m.v[DATA_IDX] || ''; }))].sort((a,b) => { return a > b ? 1 : -1; }),
18073
- });
18074
- });
18075
- } */
18076
18056
  const [LVL_IDX, CHK_IDX, COLNM_IDX, DATA_IDX] = ["LVL", "CHK", "COLNM", "DATA"].map(k => grd.fields.indexOf(k));
18077
18057
  const checked = grd.data.getValidDataNF().filter(m => m.v[LVL_IDX] === 2 && m.v[CHK_IDX] === "Y");
18078
18058
  const filterOptions = checked.length > 0 ? [...new Set(checked.map(m => m.v[COLNM_IDX]))].map(v => ({
@@ -18082,18 +18062,6 @@ class ngFilterPanel extends HTMLElement
18082
18062
 
18083
18063
 
18084
18064
  this.#button.filterOptions = filterOptions;
18085
-
18086
- /**
18087
- var oParam = {};
18088
-
18089
- this.#owner.body.querySelectorAll("ng-filter-button").forEach(el => {
18090
-
18091
- //if (!el.filterOptions) return true;
18092
-
18093
- el.filterOptions.forEach(filterOptions => {
18094
- if (filterOptions.data.length > 0) oParam[filterOptions.colnm] = filterOptions.data;
18095
- });
18096
- }); */
18097
18065
 
18098
18066
  const oParam = Object.fromEntries(
18099
18067
  [...this.#owner.body.querySelectorAll("ng-filter-button")]
@@ -18103,60 +18071,53 @@ class ngFilterPanel extends HTMLElement
18103
18071
  );
18104
18072
 
18105
18073
  this.#owner.filtering.set(oParam);
18074
+
18106
18075
  this.classList.remove("loading");
18076
+ this.style.display = 'none';
18107
18077
  });
18108
-
18109
- //$(this).hide();
18110
- this.style.display = 'none';
18111
18078
  };
18112
18079
 
18113
18080
 
18114
18081
 
18115
18082
  #onCancel = (e) => {
18116
- //$(this).hide();
18117
18083
  this.style.display = 'none';
18118
18084
  };
18119
18085
 
18120
18086
  #onSelectAll = (e) => {
18121
- var grd = this.shadowRoot.querySelector("nine-grid");
18122
- var idx = (grd.fields.indexOf("CHK"));
18087
+ const grd = this.shadowRoot.querySelector("nine-grid");
18088
+ const idx = grd.fields.indexOf("CHK");
18089
+ const isChecked = e.target.checked; // ✅ jQuery 없이 `checked` 값 가져오기
18090
+
18091
+ grd.data.getValidData().forEach(m => {
18092
+ m.v[idx] = isChecked ? "Y" : "N"; // ✅ `Y` 또는 `N` 값 설정
18093
+ });
18123
18094
 
18124
- grd.data.getValidData().map(m => { m.v[idx] = $(e.target).prop("checked") ? "Y" : "N"; });
18125
-
18126
18095
  grd.refreshData();
18127
18096
  };
18097
+
18128
18098
 
18129
18099
 
18130
18100
  #onInput = (e) => {
18131
- var grd = this.shadowRoot.querySelector("nine-grid");
18132
-
18101
+ const grd = this.shadowRoot.querySelector("nine-grid");
18133
18102
 
18134
- ninegrid.j.querySelectorAll(grd).addClass("loading");
18135
-
18103
+ grd.classList.add("loading");
18136
18104
 
18137
- var data = grd.dataManager.rawRecords;
18105
+ const data = grd.dataManager.rawRecords;
18106
+ data.forEach(m => { m.__ng.filtered = false; });
18138
18107
 
18139
- data.map(m => { m.__ng.filtered = false; });
18108
+ const v = e.target.value.toLowerCase(); // jQuery 없이 값 가져오기
18109
+ const [LVL_IDX, DATA_IDX] = ["LVL", "DATA"].map(field => grd.fields.indexOf(field));
18140
18110
 
18141
-
18142
- var v = $(e.target).val().toLowerCase();
18143
-
18111
+ data.forEach(m => {
18112
+ m.__ng.filtered = m.v[LVL_IDX] === 2 && !String(m.v[DATA_IDX] || "").toLowerCase().includes(v);
18113
+ });
18144
18114
 
18145
- const LVL_IDX = grd.fields.indexOf("LVL");
18146
- const DATA_IDX = grd.fields.indexOf("DATA");
18147
-
18148
- data.filter(m => { return m.v[LVL_IDX] == 2 && String(m.v[DATA_IDX] || '').toLowerCase().indexOf(v) < 0; }).map(m => { m.__ng.filtered = true; });
18149
-
18150
18115
  grd.data.resetRecords();
18151
18116
 
18152
- if (this.#timer) {
18153
- clearTimeout(this.#timer);
18154
- this.#timer = null;
18155
- }
18117
+ clearTimeout(this.#timer);
18156
18118
  this.#timer = setTimeout(() => {
18157
18119
  grd.dataManager.viewRecords.reset();
18158
18120
  grd.dataManager.viewRecords.touch();
18159
- //ninegrid.j.querySelectorAll(grd).removeClass("loading");
18160
18121
  }, 200);
18161
18122
  };
18162
18123
 
@@ -18167,108 +18128,68 @@ class ngFilterPanel extends HTMLElement
18167
18128
 
18168
18129
  open = (filterButton) => {
18169
18130
 
18170
- //const owner = this.shadow.closest("nine-grid");
18171
-
18172
18131
  /** 위치 */
18173
18132
  const cell = filterButton.closest("th,td");
18174
18133
 
18175
- const filterButtonRect = filterButton.getBoundingClientRect();
18176
- const ownerRect = this.#owner.getBoundingClientRect();
18177
- const cellRect = cell.getBoundingClientRect();
18178
- const targetRect = this.getBoundingClientRect();
18179
-
18180
- let l = filterButtonRect.left - ownerRect.left;
18181
- if (l < 0) l = 0;
18182
- if (l + targetRect.width > ownerRect.width) l = ownerRect.width - targetRect.width - 5;
18183
-
18184
- const t = cellRect.top + cellRect.height - ownerRect.top;
18134
+ const { left: btnLeft } = filterButton.getBoundingClientRect();
18135
+ const { left: ownerLeft, width: ownerWidth, top: ownerTop } = this.#owner.getBoundingClientRect();
18136
+ const { top: cellTop, height: cellHeight } = cell.getBoundingClientRect();
18137
+ const { width: targetWidth } = this.getBoundingClientRect();
18185
18138
 
18186
- this.style.left = `${l}px`; // 위치 설정
18187
- this.style.top = `${t}px`;
18139
+ let l = Math.max(0, btnLeft - ownerLeft);
18140
+ l = Math.min(l, ownerWidth - targetWidth - 5);
18188
18141
 
18189
-
18190
-
18191
- //console.log(this, owner, filterButton.filterOptions, colnms);
18192
-
18193
- var col = filterButton.closest('th,td').dataset.col;
18194
- this.col = col;
18142
+ const t = cellTop + cellHeight - ownerTop;
18195
18143
 
18196
- this.#button = filterButton;
18197
-
18198
- this.style.display = 'flex';
18144
+ Object.assign(this.style, { left: `${l}px`, top: `${t}px`, display: "flex" });
18199
18145
  this.classList.add("loading");
18200
18146
 
18201
-
18202
18147
  this.shadowRoot.querySelector("input[type=text]").value = "";
18203
18148
 
18204
-
18205
- //$(this.shadowRoot).find("input[type=text]").val("");
18206
-
18207
18149
  setTimeout(() => {
18208
-
18150
+ const data = this.#owner.data.getValidDataNF();
18151
+ const col = cell.dataset.col;
18152
+ this.col = col;
18153
+ this.#button = filterButton;
18209
18154
 
18210
- let data = this.#owner.data.getValidDataNF();
18211
-
18212
- var ds = [];
18213
- filterButton.filterOptions.forEach((filterOption,i) => {
18214
-
18215
- ds.push({
18216
- LVL: 1,
18217
- CHK: 'N',
18218
- DATA2: '<span class="group">' + $(filterButton).closest('th,td').text() + (filterButton.filterOptions.length > 1 ? ` #${i+1} (${filterOption.colnm})` : '') + '</span>',
18219
- });
18155
+ const ds = filterButton.filterOptions.map((filterOption, i) => {
18156
+ const groupLabel = `<span class="group">${cell.textContent}${filterButton.filterOptions.length > 1 ? ` #${i + 1} (${filterOption.colnm})` : ""}</span>`;
18220
18157
 
18221
- /**
18222
- var cell = $(`[data-col=${col}][data-bind=${filterOption.colnm}]`, this.#owner.template);
18223
- var expr = cell.attr("data-expr");
18224
- var exprFunc = (expr) ? this.#owner.exprFunction(expr) : null;
18225
- */
18226
-
18227
- const cell = ninegrid.j.querySelectorAll(`[data-col="${col}"][data-bind="${filterOption.colnm}"]`, this.#owner.tmpl).elem();
18228
- const expr = cell.getAttribute("data-expr");
18229
- const exprFunc = (expr) ? this.#owner.exprFunction(expr) : null;
18158
+ const cellEl = this.#owner.tmpl.querySelector(`[data-col="${col}"][data-bind="${filterOption.colnm}"]`);
18159
+ const expr = cellEl?.getAttribute("data-expr");
18160
+ const exprFunc = expr ? this.#owner.exprFunction(expr) : null;
18230
18161
 
18231
- var data2 = [];
18232
- for (var rowData of data) {
18233
- var idx = this.#owner.fields.indexOf(filterOption.colnm);
18234
-
18235
- if (expr) {
18236
- var o = this.#owner.data.conv(rowData);
18237
- data2.push({v:o[filterOption.colnm],v2:exprFunc(o, rowData.__ng.rowidx, this.#owner.data)});
18238
- }
18239
- else {
18240
- data2.push({v:rowData.v[idx],v2:rowData.v[idx]});
18241
- }
18242
- }
18243
-
18244
- console.log(data, data2);
18245
-
18246
- [...new Set(data2.sort( (a,b) => { return (a.v2||'') > (b.v2||'') ? 1 : ((a.v2||'') < (b.v2||'') ? -1 : 0); } ).map((m) => JSON.stringify(m)))].map((m) => JSON.parse(m)).forEach(o => {
18247
- console.log(filterOption, o);
18248
- ds.push({
18249
- LVL : 2,
18250
- DATA : o.v,
18251
- DATA2 : o.v2 || ` <span class="empty">(empty)</span> ${o.v}`,
18252
- COLNM : filterOption.colnm,
18253
- CHK : filterOption.data.length == 0 || filterOption.data.nineBinarySearch(o.v || '') >= 0 ? "Y" : "N",
18254
- });
18162
+ const data2 = data.map(rowData => {
18163
+ const idx = this.#owner.fields.indexOf(filterOption.colnm);
18164
+ 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] };
18255
18165
  });
18256
- });
18166
+
18167
+ return [
18168
+ { LVL: 1, CHK: "N", DATA2: groupLabel },
18169
+ ...[...new Set(data2.map(JSON.stringify))]
18170
+ .map(JSON.parse)
18171
+ .sort((a, b) => (a.v2 || "") > (b.v2 || "") ? 1 : (a.v2 || "") < (b.v2 || "") ? -1 : 0)
18172
+ .map(o => ({
18173
+ LVL: 2,
18174
+ DATA: o.v,
18175
+ DATA2: o.v2 || ` <span class="empty">(empty)</span> ${o.v}`,
18176
+ COLNM: filterOption.colnm,
18177
+ CHK: filterOption.data.length === 0 || filterOption.data.nineBinarySearch(o.v || "") >= 0 ? "Y" : "N",
18178
+ }))
18179
+ ];
18180
+ }).flat();
18257
18181
 
18258
18182
  const grd = this.shadowRoot.querySelector("nine-grid");
18259
18183
  //grd.dataSource = ds;
18260
18184
  grd.fields.add(["DATA","DATA2","COLNM"]);
18261
-
18262
18185
  grd.data.set(ds);
18263
18186
 
18264
18187
  // ✅ 데이터 필터링 및 체크 상태 결정
18265
18188
  const checkbox = this.shadowRoot.querySelector("input[type=checkbox]");
18266
- checkbox.checked = grd.data.getValidData().filter(item => item.LVL == 2 && item.CHK != "Y").length === 0; // ✅ 체크 상태 설정
18189
+ checkbox.checked = grd.data.getValidData().every(item => !(item.LVL === 2 && item.CHK !== "Y"));
18267
18190
 
18268
18191
  this.shadowRoot.querySelector("input").focus();
18269
-
18270
18192
  this.classList.remove("loading");
18271
- //ninegrid.j.querySelectorAll(this).removeClass("loading");
18272
18193
  });
18273
18194
  };
18274
18195
  }
@@ -18051,26 +18051,6 @@ class ngFilterPanel extends HTMLElement
18051
18051
  this.classList.add("loading");
18052
18052
 
18053
18053
  setTimeout(() => {
18054
-
18055
- /**
18056
- const LVL_IDX = grd.fields.indexOf("LVL");
18057
- const CHK_IDX = grd.fields.indexOf("CHK");
18058
- const COLNM_IDX = grd.fields.indexOf("COLNM");
18059
- const DATA_IDX = grd.fields.indexOf("DATA");
18060
-
18061
- const checked = grd.data.getValidDataNF().filter(m => { return m.v[LVL_IDX] == 2 && m.v[CHK_IDX] == "Y"; });
18062
- //const unchecked = grd.data.getValidDataNF().filter(m => { return m.v[LVL_IDX] == 2 && m.v[CHK_IDX] != "Y"; });
18063
-
18064
- var filterOptions = [];
18065
- if (checked.length > 0) {
18066
-
18067
- [...new Set(checked.map(m => { return m.v[COLNM_IDX] }))].forEach(v => {
18068
- filterOptions.push({
18069
- colnm : v,
18070
- data : [...new Set(grd.data.getValidData().filter(m => { return m.v[CHK_IDX] == "Y" && m.v[COLNM_IDX] == v; }).map(m => { return m.v[DATA_IDX] || ''; }))].sort((a,b) => { return a > b ? 1 : -1; }),
18071
- });
18072
- });
18073
- } */
18074
18054
  const [LVL_IDX, CHK_IDX, COLNM_IDX, DATA_IDX] = ["LVL", "CHK", "COLNM", "DATA"].map(k => grd.fields.indexOf(k));
18075
18055
  const checked = grd.data.getValidDataNF().filter(m => m.v[LVL_IDX] === 2 && m.v[CHK_IDX] === "Y");
18076
18056
  const filterOptions = checked.length > 0 ? [...new Set(checked.map(m => m.v[COLNM_IDX]))].map(v => ({
@@ -18080,18 +18060,6 @@ class ngFilterPanel extends HTMLElement
18080
18060
 
18081
18061
 
18082
18062
  this.#button.filterOptions = filterOptions;
18083
-
18084
- /**
18085
- var oParam = {};
18086
-
18087
- this.#owner.body.querySelectorAll("ng-filter-button").forEach(el => {
18088
-
18089
- //if (!el.filterOptions) return true;
18090
-
18091
- el.filterOptions.forEach(filterOptions => {
18092
- if (filterOptions.data.length > 0) oParam[filterOptions.colnm] = filterOptions.data;
18093
- });
18094
- }); */
18095
18063
 
18096
18064
  const oParam = Object.fromEntries(
18097
18065
  [...this.#owner.body.querySelectorAll("ng-filter-button")]
@@ -18101,60 +18069,53 @@ class ngFilterPanel extends HTMLElement
18101
18069
  );
18102
18070
 
18103
18071
  this.#owner.filtering.set(oParam);
18072
+
18104
18073
  this.classList.remove("loading");
18074
+ this.style.display = 'none';
18105
18075
  });
18106
-
18107
- //$(this).hide();
18108
- this.style.display = 'none';
18109
18076
  };
18110
18077
 
18111
18078
 
18112
18079
 
18113
18080
  #onCancel = (e) => {
18114
- //$(this).hide();
18115
18081
  this.style.display = 'none';
18116
18082
  };
18117
18083
 
18118
18084
  #onSelectAll = (e) => {
18119
- var grd = this.shadowRoot.querySelector("nine-grid");
18120
- var idx = (grd.fields.indexOf("CHK"));
18085
+ const grd = this.shadowRoot.querySelector("nine-grid");
18086
+ const idx = grd.fields.indexOf("CHK");
18087
+ const isChecked = e.target.checked; // ✅ jQuery 없이 `checked` 값 가져오기
18088
+
18089
+ grd.data.getValidData().forEach(m => {
18090
+ m.v[idx] = isChecked ? "Y" : "N"; // ✅ `Y` 또는 `N` 값 설정
18091
+ });
18121
18092
 
18122
- grd.data.getValidData().map(m => { m.v[idx] = $(e.target).prop("checked") ? "Y" : "N"; });
18123
-
18124
18093
  grd.refreshData();
18125
18094
  };
18095
+
18126
18096
 
18127
18097
 
18128
18098
  #onInput = (e) => {
18129
- var grd = this.shadowRoot.querySelector("nine-grid");
18130
-
18099
+ const grd = this.shadowRoot.querySelector("nine-grid");
18131
18100
 
18132
- ninegrid.j.querySelectorAll(grd).addClass("loading");
18133
-
18101
+ grd.classList.add("loading");
18134
18102
 
18135
- var data = grd.dataManager.rawRecords;
18103
+ const data = grd.dataManager.rawRecords;
18104
+ data.forEach(m => { m.__ng.filtered = false; });
18136
18105
 
18137
- data.map(m => { m.__ng.filtered = false; });
18106
+ const v = e.target.value.toLowerCase(); // jQuery 없이 값 가져오기
18107
+ const [LVL_IDX, DATA_IDX] = ["LVL", "DATA"].map(field => grd.fields.indexOf(field));
18138
18108
 
18139
-
18140
- var v = $(e.target).val().toLowerCase();
18141
-
18109
+ data.forEach(m => {
18110
+ m.__ng.filtered = m.v[LVL_IDX] === 2 && !String(m.v[DATA_IDX] || "").toLowerCase().includes(v);
18111
+ });
18142
18112
 
18143
- const LVL_IDX = grd.fields.indexOf("LVL");
18144
- const DATA_IDX = grd.fields.indexOf("DATA");
18145
-
18146
- data.filter(m => { return m.v[LVL_IDX] == 2 && String(m.v[DATA_IDX] || '').toLowerCase().indexOf(v) < 0; }).map(m => { m.__ng.filtered = true; });
18147
-
18148
18113
  grd.data.resetRecords();
18149
18114
 
18150
- if (this.#timer) {
18151
- clearTimeout(this.#timer);
18152
- this.#timer = null;
18153
- }
18115
+ clearTimeout(this.#timer);
18154
18116
  this.#timer = setTimeout(() => {
18155
18117
  grd.dataManager.viewRecords.reset();
18156
18118
  grd.dataManager.viewRecords.touch();
18157
- //ninegrid.j.querySelectorAll(grd).removeClass("loading");
18158
18119
  }, 200);
18159
18120
  };
18160
18121
 
@@ -18165,108 +18126,68 @@ class ngFilterPanel extends HTMLElement
18165
18126
 
18166
18127
  open = (filterButton) => {
18167
18128
 
18168
- //const owner = this.shadow.closest("nine-grid");
18169
-
18170
18129
  /** 위치 */
18171
18130
  const cell = filterButton.closest("th,td");
18172
18131
 
18173
- const filterButtonRect = filterButton.getBoundingClientRect();
18174
- const ownerRect = this.#owner.getBoundingClientRect();
18175
- const cellRect = cell.getBoundingClientRect();
18176
- const targetRect = this.getBoundingClientRect();
18177
-
18178
- let l = filterButtonRect.left - ownerRect.left;
18179
- if (l < 0) l = 0;
18180
- if (l + targetRect.width > ownerRect.width) l = ownerRect.width - targetRect.width - 5;
18181
-
18182
- const t = cellRect.top + cellRect.height - ownerRect.top;
18132
+ const { left: btnLeft } = filterButton.getBoundingClientRect();
18133
+ const { left: ownerLeft, width: ownerWidth, top: ownerTop } = this.#owner.getBoundingClientRect();
18134
+ const { top: cellTop, height: cellHeight } = cell.getBoundingClientRect();
18135
+ const { width: targetWidth } = this.getBoundingClientRect();
18183
18136
 
18184
- this.style.left = `${l}px`; // 위치 설정
18185
- this.style.top = `${t}px`;
18137
+ let l = Math.max(0, btnLeft - ownerLeft);
18138
+ l = Math.min(l, ownerWidth - targetWidth - 5);
18186
18139
 
18187
-
18188
-
18189
- //console.log(this, owner, filterButton.filterOptions, colnms);
18190
-
18191
- var col = filterButton.closest('th,td').dataset.col;
18192
- this.col = col;
18140
+ const t = cellTop + cellHeight - ownerTop;
18193
18141
 
18194
- this.#button = filterButton;
18195
-
18196
- this.style.display = 'flex';
18142
+ Object.assign(this.style, { left: `${l}px`, top: `${t}px`, display: "flex" });
18197
18143
  this.classList.add("loading");
18198
18144
 
18199
-
18200
18145
  this.shadowRoot.querySelector("input[type=text]").value = "";
18201
18146
 
18202
-
18203
- //$(this.shadowRoot).find("input[type=text]").val("");
18204
-
18205
18147
  setTimeout(() => {
18206
-
18148
+ const data = this.#owner.data.getValidDataNF();
18149
+ const col = cell.dataset.col;
18150
+ this.col = col;
18151
+ this.#button = filterButton;
18207
18152
 
18208
- let data = this.#owner.data.getValidDataNF();
18209
-
18210
- var ds = [];
18211
- filterButton.filterOptions.forEach((filterOption,i) => {
18212
-
18213
- ds.push({
18214
- LVL: 1,
18215
- CHK: 'N',
18216
- DATA2: '<span class="group">' + $(filterButton).closest('th,td').text() + (filterButton.filterOptions.length > 1 ? ` #${i+1} (${filterOption.colnm})` : '') + '</span>',
18217
- });
18153
+ const ds = filterButton.filterOptions.map((filterOption, i) => {
18154
+ const groupLabel = `<span class="group">${cell.textContent}${filterButton.filterOptions.length > 1 ? ` #${i + 1} (${filterOption.colnm})` : ""}</span>`;
18218
18155
 
18219
- /**
18220
- var cell = $(`[data-col=${col}][data-bind=${filterOption.colnm}]`, this.#owner.template);
18221
- var expr = cell.attr("data-expr");
18222
- var exprFunc = (expr) ? this.#owner.exprFunction(expr) : null;
18223
- */
18224
-
18225
- const cell = ninegrid.j.querySelectorAll(`[data-col="${col}"][data-bind="${filterOption.colnm}"]`, this.#owner.tmpl).elem();
18226
- const expr = cell.getAttribute("data-expr");
18227
- const exprFunc = (expr) ? this.#owner.exprFunction(expr) : null;
18156
+ const cellEl = this.#owner.tmpl.querySelector(`[data-col="${col}"][data-bind="${filterOption.colnm}"]`);
18157
+ const expr = cellEl?.getAttribute("data-expr");
18158
+ const exprFunc = expr ? this.#owner.exprFunction(expr) : null;
18228
18159
 
18229
- var data2 = [];
18230
- for (var rowData of data) {
18231
- var idx = this.#owner.fields.indexOf(filterOption.colnm);
18232
-
18233
- if (expr) {
18234
- var o = this.#owner.data.conv(rowData);
18235
- data2.push({v:o[filterOption.colnm],v2:exprFunc(o, rowData.__ng.rowidx, this.#owner.data)});
18236
- }
18237
- else {
18238
- data2.push({v:rowData.v[idx],v2:rowData.v[idx]});
18239
- }
18240
- }
18241
-
18242
- console.log(data, data2);
18243
-
18244
- [...new Set(data2.sort( (a,b) => { return (a.v2||'') > (b.v2||'') ? 1 : ((a.v2||'') < (b.v2||'') ? -1 : 0); } ).map((m) => JSON.stringify(m)))].map((m) => JSON.parse(m)).forEach(o => {
18245
- console.log(filterOption, o);
18246
- ds.push({
18247
- LVL : 2,
18248
- DATA : o.v,
18249
- DATA2 : o.v2 || ` <span class="empty">(empty)</span> ${o.v}`,
18250
- COLNM : filterOption.colnm,
18251
- CHK : filterOption.data.length == 0 || filterOption.data.nineBinarySearch(o.v || '') >= 0 ? "Y" : "N",
18252
- });
18160
+ const data2 = data.map(rowData => {
18161
+ const idx = this.#owner.fields.indexOf(filterOption.colnm);
18162
+ 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] };
18253
18163
  });
18254
- });
18164
+
18165
+ return [
18166
+ { LVL: 1, CHK: "N", DATA2: groupLabel },
18167
+ ...[...new Set(data2.map(JSON.stringify))]
18168
+ .map(JSON.parse)
18169
+ .sort((a, b) => (a.v2 || "") > (b.v2 || "") ? 1 : (a.v2 || "") < (b.v2 || "") ? -1 : 0)
18170
+ .map(o => ({
18171
+ LVL: 2,
18172
+ DATA: o.v,
18173
+ DATA2: o.v2 || ` <span class="empty">(empty)</span> ${o.v}`,
18174
+ COLNM: filterOption.colnm,
18175
+ CHK: filterOption.data.length === 0 || filterOption.data.nineBinarySearch(o.v || "") >= 0 ? "Y" : "N",
18176
+ }))
18177
+ ];
18178
+ }).flat();
18255
18179
 
18256
18180
  const grd = this.shadowRoot.querySelector("nine-grid");
18257
18181
  //grd.dataSource = ds;
18258
18182
  grd.fields.add(["DATA","DATA2","COLNM"]);
18259
-
18260
18183
  grd.data.set(ds);
18261
18184
 
18262
18185
  // ✅ 데이터 필터링 및 체크 상태 결정
18263
18186
  const checkbox = this.shadowRoot.querySelector("input[type=checkbox]");
18264
- checkbox.checked = grd.data.getValidData().filter(item => item.LVL == 2 && item.CHK != "Y").length === 0; // ✅ 체크 상태 설정
18187
+ checkbox.checked = grd.data.getValidData().every(item => !(item.LVL === 2 && item.CHK !== "Y"));
18265
18188
 
18266
18189
  this.shadowRoot.querySelector("input").focus();
18267
-
18268
18190
  this.classList.remove("loading");
18269
- //ninegrid.j.querySelectorAll(this).removeClass("loading");
18270
18191
  });
18271
18192
  };
18272
18193
  }
@@ -230,26 +230,6 @@ class ngFilterPanel extends HTMLElement
230
230
  this.classList.add("loading");
231
231
 
232
232
  setTimeout(() => {
233
-
234
- /**
235
- const LVL_IDX = grd.fields.indexOf("LVL");
236
- const CHK_IDX = grd.fields.indexOf("CHK");
237
- const COLNM_IDX = grd.fields.indexOf("COLNM");
238
- const DATA_IDX = grd.fields.indexOf("DATA");
239
-
240
- const checked = grd.data.getValidDataNF().filter(m => { return m.v[LVL_IDX] == 2 && m.v[CHK_IDX] == "Y"; });
241
- //const unchecked = grd.data.getValidDataNF().filter(m => { return m.v[LVL_IDX] == 2 && m.v[CHK_IDX] != "Y"; });
242
-
243
- var filterOptions = [];
244
- if (checked.length > 0) {
245
-
246
- [...new Set(checked.map(m => { return m.v[COLNM_IDX] }))].forEach(v => {
247
- filterOptions.push({
248
- colnm : v,
249
- data : [...new Set(grd.data.getValidData().filter(m => { return m.v[CHK_IDX] == "Y" && m.v[COLNM_IDX] == v; }).map(m => { return m.v[DATA_IDX] || ''; }))].sort((a,b) => { return a > b ? 1 : -1; }),
250
- });
251
- });
252
- } */
253
233
  const [LVL_IDX, CHK_IDX, COLNM_IDX, DATA_IDX] = ["LVL", "CHK", "COLNM", "DATA"].map(k => grd.fields.indexOf(k));
254
234
  const checked = grd.data.getValidDataNF().filter(m => m.v[LVL_IDX] === 2 && m.v[CHK_IDX] === "Y");
255
235
  const filterOptions = checked.length > 0 ? [...new Set(checked.map(m => m.v[COLNM_IDX]))].map(v => ({
@@ -259,18 +239,6 @@ class ngFilterPanel extends HTMLElement
259
239
 
260
240
 
261
241
  this.#button.filterOptions = filterOptions;
262
-
263
- /**
264
- var oParam = {};
265
-
266
- this.#owner.body.querySelectorAll("ng-filter-button").forEach(el => {
267
-
268
- //if (!el.filterOptions) return true;
269
-
270
- el.filterOptions.forEach(filterOptions => {
271
- if (filterOptions.data.length > 0) oParam[filterOptions.colnm] = filterOptions.data;
272
- });
273
- }); */
274
242
 
275
243
  const oParam = Object.fromEntries(
276
244
  [...this.#owner.body.querySelectorAll("ng-filter-button")]
@@ -280,60 +248,53 @@ class ngFilterPanel extends HTMLElement
280
248
  );
281
249
 
282
250
  this.#owner.filtering.set(oParam);
251
+
283
252
  this.classList.remove("loading");
253
+ this.style.display = 'none';
284
254
  });
285
-
286
- //$(this).hide();
287
- this.style.display = 'none';
288
255
  };
289
256
 
290
257
 
291
258
 
292
259
  #onCancel = (e) => {
293
- //$(this).hide();
294
260
  this.style.display = 'none';
295
261
  };
296
262
 
297
263
  #onSelectAll = (e) => {
298
- var grd = this.shadowRoot.querySelector("nine-grid");
299
- var idx = (grd.fields.indexOf("CHK"));
264
+ const grd = this.shadowRoot.querySelector("nine-grid");
265
+ const idx = grd.fields.indexOf("CHK");
266
+ const isChecked = e.target.checked; // ✅ jQuery 없이 `checked` 값 가져오기
267
+
268
+ grd.data.getValidData().forEach(m => {
269
+ m.v[idx] = isChecked ? "Y" : "N"; // ✅ `Y` 또는 `N` 값 설정
270
+ });
300
271
 
301
- grd.data.getValidData().map(m => { m.v[idx] = $(e.target).prop("checked") ? "Y" : "N"; });
302
-
303
272
  grd.refreshData();
304
273
  };
274
+
305
275
 
306
276
 
307
277
  #onInput = (e) => {
308
- var grd = this.shadowRoot.querySelector("nine-grid");
309
-
278
+ const grd = this.shadowRoot.querySelector("nine-grid");
310
279
 
311
- ninegrid.j.querySelectorAll(grd).addClass("loading");
312
-
280
+ grd.classList.add("loading");
313
281
 
314
- var data = grd.dataManager.rawRecords;
282
+ const data = grd.dataManager.rawRecords;
283
+ data.forEach(m => { m.__ng.filtered = false; });
315
284
 
316
- data.map(m => { m.__ng.filtered = false; });
285
+ const v = e.target.value.toLowerCase(); // jQuery 없이 값 가져오기
286
+ const [LVL_IDX, DATA_IDX] = ["LVL", "DATA"].map(field => grd.fields.indexOf(field));
317
287
 
318
-
319
- var v = $(e.target).val().toLowerCase();
320
-
288
+ data.forEach(m => {
289
+ m.__ng.filtered = m.v[LVL_IDX] === 2 && !String(m.v[DATA_IDX] || "").toLowerCase().includes(v);
290
+ });
321
291
 
322
- const LVL_IDX = grd.fields.indexOf("LVL");
323
- const DATA_IDX = grd.fields.indexOf("DATA");
324
-
325
- data.filter(m => { return m.v[LVL_IDX] == 2 && String(m.v[DATA_IDX] || '').toLowerCase().indexOf(v) < 0; }).map(m => { m.__ng.filtered = true; });
326
-
327
292
  grd.data.resetRecords();
328
293
 
329
- if (this.#timer) {
330
- clearTimeout(this.#timer);
331
- this.#timer = null;
332
- }
294
+ clearTimeout(this.#timer);
333
295
  this.#timer = setTimeout(() => {
334
296
  grd.dataManager.viewRecords.reset();
335
297
  grd.dataManager.viewRecords.touch();
336
- //ninegrid.j.querySelectorAll(grd).removeClass("loading");
337
298
  }, 200)
338
299
  };
339
300
 
@@ -344,108 +305,68 @@ class ngFilterPanel extends HTMLElement
344
305
 
345
306
  open = (filterButton) => {
346
307
 
347
- //const owner = this.shadow.closest("nine-grid");
348
-
349
308
  /** 위치 */
350
309
  const cell = filterButton.closest("th,td");
351
310
 
352
- const filterButtonRect = filterButton.getBoundingClientRect();
353
- const ownerRect = this.#owner.getBoundingClientRect();
354
- const cellRect = cell.getBoundingClientRect();
355
- const targetRect = this.getBoundingClientRect();
311
+ const { left: btnLeft } = filterButton.getBoundingClientRect();
312
+ const { left: ownerLeft, width: ownerWidth, top: ownerTop } = this.#owner.getBoundingClientRect();
313
+ const { top: cellTop, height: cellHeight } = cell.getBoundingClientRect();
314
+ const { width: targetWidth } = this.getBoundingClientRect();
356
315
 
357
- let l = filterButtonRect.left - ownerRect.left;
358
- if (l < 0) l = 0;
359
- if (l + targetRect.width > ownerRect.width) l = ownerRect.width - targetRect.width - 5;
316
+ let l = Math.max(0, btnLeft - ownerLeft);
317
+ l = Math.min(l, ownerWidth - targetWidth - 5);
360
318
 
361
- const t = cellRect.top + cellRect.height - ownerRect.top;
362
-
363
- this.style.left = `${l}px`; // ✅ 위치 설정
364
- this.style.top = `${t}px`;
365
-
366
-
319
+ const t = cellTop + cellHeight - ownerTop;
367
320
 
368
- //console.log(this, owner, filterButton.filterOptions, colnms);
369
-
370
- var col = filterButton.closest('th,td').dataset.col;
371
- this.col = col;
372
-
373
- this.#button = filterButton;
374
-
375
- this.style.display = 'flex';
321
+ Object.assign(this.style, { left: `${l}px`, top: `${t}px`, display: "flex" });
376
322
  this.classList.add("loading");
377
323
 
378
-
379
324
  this.shadowRoot.querySelector("input[type=text]").value = "";
380
325
 
381
-
382
- //$(this.shadowRoot).find("input[type=text]").val("");
383
-
384
326
  setTimeout(() => {
385
-
386
-
387
- let data = this.#owner.data.getValidDataNF();
327
+ const data = this.#owner.data.getValidDataNF();
328
+ const col = cell.dataset.col;
329
+ this.col = col;
330
+ this.#button = filterButton;
388
331
 
389
- var ds = [];
390
- filterButton.filterOptions.forEach((filterOption,i) => {
391
-
392
- ds.push({
393
- LVL: 1,
394
- CHK: 'N',
395
- DATA2: '<span class="group">' + $(filterButton).closest('th,td').text() + (filterButton.filterOptions.length > 1 ? ` #${i+1} (${filterOption.colnm})` : '') + '</span>',
396
- });
332
+ const ds = filterButton.filterOptions.map((filterOption, i) => {
333
+ const groupLabel = `<span class="group">${cell.textContent}${filterButton.filterOptions.length > 1 ? ` #${i + 1} (${filterOption.colnm})` : ""}</span>`;
397
334
 
398
- /**
399
- var cell = $(`[data-col=${col}][data-bind=${filterOption.colnm}]`, this.#owner.template);
400
- var expr = cell.attr("data-expr");
401
- var exprFunc = (expr) ? this.#owner.exprFunction(expr) : null;
402
- */
403
-
404
- const cell = ninegrid.j.querySelectorAll(`[data-col="${col}"][data-bind="${filterOption.colnm}"]`, this.#owner.tmpl).elem();
405
- const expr = cell.getAttribute("data-expr");
406
- const exprFunc = (expr) ? this.#owner.exprFunction(expr) : null;
407
-
408
- var data2 = [];
409
- for (var rowData of data) {
410
- var idx = this.#owner.fields.indexOf(filterOption.colnm);
411
-
412
- if (expr) {
413
- var o = this.#owner.data.conv(rowData);
414
- data2.push({v:o[filterOption.colnm],v2:exprFunc(o, rowData.__ng.rowidx, this.#owner.data)});
415
- }
416
- else {
417
- data2.push({v:rowData.v[idx],v2:rowData.v[idx]});
418
- }
419
- }
335
+ const cellEl = this.#owner.tmpl.querySelector(`[data-col="${col}"][data-bind="${filterOption.colnm}"]`);
336
+ const expr = cellEl?.getAttribute("data-expr");
337
+ const exprFunc = expr ? this.#owner.exprFunction(expr) : null;
420
338
 
421
- console.log(data, data2);
422
-
423
- [...new Set(data2.sort( (a,b) => { return (a.v2||'') > (b.v2||'') ? 1 : ((a.v2||'') < (b.v2||'') ? -1 : 0); } ).map((m) => JSON.stringify(m)))].map((m) => JSON.parse(m)).forEach(o => {
424
- console.log(filterOption, o);
425
- ds.push({
426
- LVL : 2,
427
- DATA : o.v,
428
- DATA2 : o.v2 || ` <span class="empty">(empty)</span> ${o.v}`,
429
- COLNM : filterOption.colnm,
430
- CHK : filterOption.data.length == 0 || filterOption.data.nineBinarySearch(o.v || '') >= 0 ? "Y" : "N",
431
- });
339
+ const data2 = data.map(rowData => {
340
+ const idx = this.#owner.fields.indexOf(filterOption.colnm);
341
+ 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] };
432
342
  });
433
- });
343
+
344
+ return [
345
+ { LVL: 1, CHK: "N", DATA2: groupLabel },
346
+ ...[...new Set(data2.map(JSON.stringify))]
347
+ .map(JSON.parse)
348
+ .sort((a, b) => (a.v2 || "") > (b.v2 || "") ? 1 : (a.v2 || "") < (b.v2 || "") ? -1 : 0)
349
+ .map(o => ({
350
+ LVL: 2,
351
+ DATA: o.v,
352
+ DATA2: o.v2 || ` <span class="empty">(empty)</span> ${o.v}`,
353
+ COLNM: filterOption.colnm,
354
+ CHK: filterOption.data.length === 0 || filterOption.data.nineBinarySearch(o.v || "") >= 0 ? "Y" : "N",
355
+ }))
356
+ ];
357
+ }).flat();
434
358
 
435
359
  const grd = this.shadowRoot.querySelector("nine-grid");
436
360
  //grd.dataSource = ds;
437
361
  grd.fields.add(["DATA","DATA2","COLNM"]);
438
-
439
362
  grd.data.set(ds);
440
363
 
441
364
  // ✅ 데이터 필터링 및 체크 상태 결정
442
365
  const checkbox = this.shadowRoot.querySelector("input[type=checkbox]");
443
- checkbox.checked = grd.data.getValidData().filter(item => item.LVL == 2 && item.CHK != "Y").length === 0; // ✅ 체크 상태 설정
366
+ checkbox.checked = grd.data.getValidData().every(item => !(item.LVL === 2 && item.CHK !== "Y"));
444
367
 
445
368
  this.shadowRoot.querySelector("input").focus();
446
-
447
369
  this.classList.remove("loading");
448
- //ninegrid.j.querySelectorAll(this).removeClass("loading");
449
370
  });
450
371
  };
451
372
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ninegrid2",
3
3
  "type": "module",
4
- "version": "6.245.0",
4
+ "version": "6.247.0",
5
5
  "main": "dist/index.js",
6
6
  "exports": {
7
7
  "import": "./dist/index.js",
@@ -230,26 +230,6 @@ class ngFilterPanel extends HTMLElement
230
230
  this.classList.add("loading");
231
231
 
232
232
  setTimeout(() => {
233
-
234
- /**
235
- const LVL_IDX = grd.fields.indexOf("LVL");
236
- const CHK_IDX = grd.fields.indexOf("CHK");
237
- const COLNM_IDX = grd.fields.indexOf("COLNM");
238
- const DATA_IDX = grd.fields.indexOf("DATA");
239
-
240
- const checked = grd.data.getValidDataNF().filter(m => { return m.v[LVL_IDX] == 2 && m.v[CHK_IDX] == "Y"; });
241
- //const unchecked = grd.data.getValidDataNF().filter(m => { return m.v[LVL_IDX] == 2 && m.v[CHK_IDX] != "Y"; });
242
-
243
- var filterOptions = [];
244
- if (checked.length > 0) {
245
-
246
- [...new Set(checked.map(m => { return m.v[COLNM_IDX] }))].forEach(v => {
247
- filterOptions.push({
248
- colnm : v,
249
- data : [...new Set(grd.data.getValidData().filter(m => { return m.v[CHK_IDX] == "Y" && m.v[COLNM_IDX] == v; }).map(m => { return m.v[DATA_IDX] || ''; }))].sort((a,b) => { return a > b ? 1 : -1; }),
250
- });
251
- });
252
- } */
253
233
  const [LVL_IDX, CHK_IDX, COLNM_IDX, DATA_IDX] = ["LVL", "CHK", "COLNM", "DATA"].map(k => grd.fields.indexOf(k));
254
234
  const checked = grd.data.getValidDataNF().filter(m => m.v[LVL_IDX] === 2 && m.v[CHK_IDX] === "Y");
255
235
  const filterOptions = checked.length > 0 ? [...new Set(checked.map(m => m.v[COLNM_IDX]))].map(v => ({
@@ -259,18 +239,6 @@ class ngFilterPanel extends HTMLElement
259
239
 
260
240
 
261
241
  this.#button.filterOptions = filterOptions;
262
-
263
- /**
264
- var oParam = {};
265
-
266
- this.#owner.body.querySelectorAll("ng-filter-button").forEach(el => {
267
-
268
- //if (!el.filterOptions) return true;
269
-
270
- el.filterOptions.forEach(filterOptions => {
271
- if (filterOptions.data.length > 0) oParam[filterOptions.colnm] = filterOptions.data;
272
- });
273
- }); */
274
242
 
275
243
  const oParam = Object.fromEntries(
276
244
  [...this.#owner.body.querySelectorAll("ng-filter-button")]
@@ -280,60 +248,53 @@ class ngFilterPanel extends HTMLElement
280
248
  );
281
249
 
282
250
  this.#owner.filtering.set(oParam);
251
+
283
252
  this.classList.remove("loading");
253
+ this.style.display = 'none';
284
254
  });
285
-
286
- //$(this).hide();
287
- this.style.display = 'none';
288
255
  };
289
256
 
290
257
 
291
258
 
292
259
  #onCancel = (e) => {
293
- //$(this).hide();
294
260
  this.style.display = 'none';
295
261
  };
296
262
 
297
263
  #onSelectAll = (e) => {
298
- var grd = this.shadowRoot.querySelector("nine-grid");
299
- var idx = (grd.fields.indexOf("CHK"));
264
+ const grd = this.shadowRoot.querySelector("nine-grid");
265
+ const idx = grd.fields.indexOf("CHK");
266
+ const isChecked = e.target.checked; // ✅ jQuery 없이 `checked` 값 가져오기
267
+
268
+ grd.data.getValidData().forEach(m => {
269
+ m.v[idx] = isChecked ? "Y" : "N"; // ✅ `Y` 또는 `N` 값 설정
270
+ });
300
271
 
301
- grd.data.getValidData().map(m => { m.v[idx] = $(e.target).prop("checked") ? "Y" : "N"; });
302
-
303
272
  grd.refreshData();
304
273
  };
274
+
305
275
 
306
276
 
307
277
  #onInput = (e) => {
308
- var grd = this.shadowRoot.querySelector("nine-grid");
309
-
278
+ const grd = this.shadowRoot.querySelector("nine-grid");
310
279
 
311
- ninegrid.j.querySelectorAll(grd).addClass("loading");
312
-
280
+ grd.classList.add("loading");
313
281
 
314
- var data = grd.dataManager.rawRecords;
282
+ const data = grd.dataManager.rawRecords;
283
+ data.forEach(m => { m.__ng.filtered = false; });
315
284
 
316
- data.map(m => { m.__ng.filtered = false; });
285
+ const v = e.target.value.toLowerCase(); // jQuery 없이 값 가져오기
286
+ const [LVL_IDX, DATA_IDX] = ["LVL", "DATA"].map(field => grd.fields.indexOf(field));
317
287
 
318
-
319
- var v = $(e.target).val().toLowerCase();
320
-
288
+ data.forEach(m => {
289
+ m.__ng.filtered = m.v[LVL_IDX] === 2 && !String(m.v[DATA_IDX] || "").toLowerCase().includes(v);
290
+ });
321
291
 
322
- const LVL_IDX = grd.fields.indexOf("LVL");
323
- const DATA_IDX = grd.fields.indexOf("DATA");
324
-
325
- data.filter(m => { return m.v[LVL_IDX] == 2 && String(m.v[DATA_IDX] || '').toLowerCase().indexOf(v) < 0; }).map(m => { m.__ng.filtered = true; });
326
-
327
292
  grd.data.resetRecords();
328
293
 
329
- if (this.#timer) {
330
- clearTimeout(this.#timer);
331
- this.#timer = null;
332
- }
294
+ clearTimeout(this.#timer);
333
295
  this.#timer = setTimeout(() => {
334
296
  grd.dataManager.viewRecords.reset();
335
297
  grd.dataManager.viewRecords.touch();
336
- //ninegrid.j.querySelectorAll(grd).removeClass("loading");
337
298
  }, 200)
338
299
  };
339
300
 
@@ -344,108 +305,68 @@ class ngFilterPanel extends HTMLElement
344
305
 
345
306
  open = (filterButton) => {
346
307
 
347
- //const owner = this.shadow.closest("nine-grid");
348
-
349
308
  /** 위치 */
350
309
  const cell = filterButton.closest("th,td");
351
310
 
352
- const filterButtonRect = filterButton.getBoundingClientRect();
353
- const ownerRect = this.#owner.getBoundingClientRect();
354
- const cellRect = cell.getBoundingClientRect();
355
- const targetRect = this.getBoundingClientRect();
311
+ const { left: btnLeft } = filterButton.getBoundingClientRect();
312
+ const { left: ownerLeft, width: ownerWidth, top: ownerTop } = this.#owner.getBoundingClientRect();
313
+ const { top: cellTop, height: cellHeight } = cell.getBoundingClientRect();
314
+ const { width: targetWidth } = this.getBoundingClientRect();
356
315
 
357
- let l = filterButtonRect.left - ownerRect.left;
358
- if (l < 0) l = 0;
359
- if (l + targetRect.width > ownerRect.width) l = ownerRect.width - targetRect.width - 5;
316
+ let l = Math.max(0, btnLeft - ownerLeft);
317
+ l = Math.min(l, ownerWidth - targetWidth - 5);
360
318
 
361
- const t = cellRect.top + cellRect.height - ownerRect.top;
362
-
363
- this.style.left = `${l}px`; // ✅ 위치 설정
364
- this.style.top = `${t}px`;
365
-
366
-
319
+ const t = cellTop + cellHeight - ownerTop;
367
320
 
368
- //console.log(this, owner, filterButton.filterOptions, colnms);
369
-
370
- var col = filterButton.closest('th,td').dataset.col;
371
- this.col = col;
372
-
373
- this.#button = filterButton;
374
-
375
- this.style.display = 'flex';
321
+ Object.assign(this.style, { left: `${l}px`, top: `${t}px`, display: "flex" });
376
322
  this.classList.add("loading");
377
323
 
378
-
379
324
  this.shadowRoot.querySelector("input[type=text]").value = "";
380
325
 
381
-
382
- //$(this.shadowRoot).find("input[type=text]").val("");
383
-
384
326
  setTimeout(() => {
385
-
386
-
387
- let data = this.#owner.data.getValidDataNF();
327
+ const data = this.#owner.data.getValidDataNF();
328
+ const col = cell.dataset.col;
329
+ this.col = col;
330
+ this.#button = filterButton;
388
331
 
389
- var ds = [];
390
- filterButton.filterOptions.forEach((filterOption,i) => {
391
-
392
- ds.push({
393
- LVL: 1,
394
- CHK: 'N',
395
- DATA2: '<span class="group">' + $(filterButton).closest('th,td').text() + (filterButton.filterOptions.length > 1 ? ` #${i+1} (${filterOption.colnm})` : '') + '</span>',
396
- });
332
+ const ds = filterButton.filterOptions.map((filterOption, i) => {
333
+ const groupLabel = `<span class="group">${cell.textContent}${filterButton.filterOptions.length > 1 ? ` #${i + 1} (${filterOption.colnm})` : ""}</span>`;
397
334
 
398
- /**
399
- var cell = $(`[data-col=${col}][data-bind=${filterOption.colnm}]`, this.#owner.template);
400
- var expr = cell.attr("data-expr");
401
- var exprFunc = (expr) ? this.#owner.exprFunction(expr) : null;
402
- */
403
-
404
- const cell = ninegrid.j.querySelectorAll(`[data-col="${col}"][data-bind="${filterOption.colnm}"]`, this.#owner.tmpl).elem();
405
- const expr = cell.getAttribute("data-expr");
406
- const exprFunc = (expr) ? this.#owner.exprFunction(expr) : null;
407
-
408
- var data2 = [];
409
- for (var rowData of data) {
410
- var idx = this.#owner.fields.indexOf(filterOption.colnm);
411
-
412
- if (expr) {
413
- var o = this.#owner.data.conv(rowData);
414
- data2.push({v:o[filterOption.colnm],v2:exprFunc(o, rowData.__ng.rowidx, this.#owner.data)});
415
- }
416
- else {
417
- data2.push({v:rowData.v[idx],v2:rowData.v[idx]});
418
- }
419
- }
335
+ const cellEl = this.#owner.tmpl.querySelector(`[data-col="${col}"][data-bind="${filterOption.colnm}"]`);
336
+ const expr = cellEl?.getAttribute("data-expr");
337
+ const exprFunc = expr ? this.#owner.exprFunction(expr) : null;
420
338
 
421
- console.log(data, data2);
422
-
423
- [...new Set(data2.sort( (a,b) => { return (a.v2||'') > (b.v2||'') ? 1 : ((a.v2||'') < (b.v2||'') ? -1 : 0); } ).map((m) => JSON.stringify(m)))].map((m) => JSON.parse(m)).forEach(o => {
424
- console.log(filterOption, o);
425
- ds.push({
426
- LVL : 2,
427
- DATA : o.v,
428
- DATA2 : o.v2 || ` <span class="empty">(empty)</span> ${o.v}`,
429
- COLNM : filterOption.colnm,
430
- CHK : filterOption.data.length == 0 || filterOption.data.nineBinarySearch(o.v || '') >= 0 ? "Y" : "N",
431
- });
339
+ const data2 = data.map(rowData => {
340
+ const idx = this.#owner.fields.indexOf(filterOption.colnm);
341
+ 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] };
432
342
  });
433
- });
343
+
344
+ return [
345
+ { LVL: 1, CHK: "N", DATA2: groupLabel },
346
+ ...[...new Set(data2.map(JSON.stringify))]
347
+ .map(JSON.parse)
348
+ .sort((a, b) => (a.v2 || "") > (b.v2 || "") ? 1 : (a.v2 || "") < (b.v2 || "") ? -1 : 0)
349
+ .map(o => ({
350
+ LVL: 2,
351
+ DATA: o.v,
352
+ DATA2: o.v2 || ` <span class="empty">(empty)</span> ${o.v}`,
353
+ COLNM: filterOption.colnm,
354
+ CHK: filterOption.data.length === 0 || filterOption.data.nineBinarySearch(o.v || "") >= 0 ? "Y" : "N",
355
+ }))
356
+ ];
357
+ }).flat();
434
358
 
435
359
  const grd = this.shadowRoot.querySelector("nine-grid");
436
360
  //grd.dataSource = ds;
437
361
  grd.fields.add(["DATA","DATA2","COLNM"]);
438
-
439
362
  grd.data.set(ds);
440
363
 
441
364
  // ✅ 데이터 필터링 및 체크 상태 결정
442
365
  const checkbox = this.shadowRoot.querySelector("input[type=checkbox]");
443
- checkbox.checked = grd.data.getValidData().filter(item => item.LVL == 2 && item.CHK != "Y").length === 0; // ✅ 체크 상태 설정
366
+ checkbox.checked = grd.data.getValidData().every(item => !(item.LVL === 2 && item.CHK !== "Y"));
444
367
 
445
368
  this.shadowRoot.querySelector("input").focus();
446
-
447
369
  this.classList.remove("loading");
448
- //ninegrid.j.querySelectorAll(this).removeClass("loading");
449
370
  });
450
371
  };
451
372
  }