ninegrid2 6.1378.0 → 6.1379.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.
@@ -28436,19 +28436,15 @@ customElements.define("nx-title", nxTitle);
28436
28436
  class nxDiv extends HTMLElement {
28437
28437
  originContents;
28438
28438
  #isInitialized = false;
28439
- #root; // Shadow DOM 사용 여부에 따라 shadowRoot 또는 this를 가리킴
28439
+ #root;
28440
28440
 
28441
28441
  constructor() {
28442
28442
  super();
28443
- // constructor에서는 속성을 읽을 수 없으므로 초기화만 준비합니다.
28444
28443
  }
28445
28444
 
28446
28445
  connectedCallback() {
28447
28446
  if (!this.#isInitialized) {
28448
- // 1. 여기서 속성을 읽어 Shadow DOM 사용 여부를 결정합니다.
28449
- // use-shadow 속성이 "false"가 아닐 때만 Shadow DOM을 생성 (기본값 true)
28450
28447
  const useShadow = this.getAttribute("use-shadow") !== "false";
28451
-
28452
28448
  if (useShadow && !this.shadowRoot) {
28453
28449
  this.attachShadow({ mode: 'open' });
28454
28450
  this.#root = this.shadowRoot;
@@ -28458,22 +28454,50 @@ class nxDiv extends HTMLElement {
28458
28454
 
28459
28455
  this.#init();
28460
28456
  this.#isInitialized = true;
28461
- return true;
28462
28457
  }
28463
- return false;
28464
28458
  }
28465
28459
 
28466
- // 자식 클래스에서 접근 가능하도록 getter 제공
28467
- get root() {
28468
- return this.#root || this;
28469
- }
28460
+ get root() { return this.#root || this; }
28470
28461
 
28471
- // 공통 쿼리 함수: 현재 root(Shadow 또는 Light DOM)에서 요소를 찾음
28472
28462
  #getElements() {
28473
- // ShadowRoot가 있으면 shadowRoot에서, 없으면 본체(this)에서 찾음
28474
28463
  return ninegrid.querySelectorAll("input[name], textarea[name], select[name], nx-editor[name]", this.#root);
28475
28464
  }
28476
28465
 
28466
+ // [공통 로직 1] 특정 요소에 값을 쓰거나 초기화하는 핵심 함수
28467
+ #updateElement(el, value) {
28468
+ const tagName = el.tagName.toUpperCase();
28469
+ const type = el.type;
28470
+ let isChanged = false;
28471
+
28472
+ if (["INPUT", "TEXTAREA", "SELECT", "NX-EDITOR"].includes(tagName)) {
28473
+ if (type === "checkbox") {
28474
+ const t = el.getAttribute("true-value") || "Y";
28475
+ const isChecked = (String(t) === String(value));
28476
+ if (el.checked !== isChecked) isChanged = true;
28477
+ el.checked = isChecked;
28478
+ } else if (type === "radio") {
28479
+ const isChecked = (String(el.value) === String(value));
28480
+ if (el.checked !== isChecked) isChanged = true;
28481
+ el.checked = isChecked;
28482
+ } else {
28483
+ if (el.value !== value) isChanged = true;
28484
+ el.value = value;
28485
+ }
28486
+ } else {
28487
+ if (el.textContent !== value) isChanged = true;
28488
+ el.textContent = value;
28489
+ }
28490
+ return isChanged;
28491
+ }
28492
+
28493
+ // [공통 로직 2] 이벤트 리스너 일괄 등록
28494
+ #refreshListeners() {
28495
+ this.#getElements().forEach(el => {
28496
+ el.removeEventListener("input", this.#changeHandler);
28497
+ el.addEventListener("input", this.#changeHandler);
28498
+ });
28499
+ }
28500
+
28477
28501
  getData = () => {
28478
28502
  const jsonData = {};
28479
28503
  this.#getElements().forEach(el => {
@@ -28482,15 +28506,14 @@ class nxDiv extends HTMLElement {
28482
28506
 
28483
28507
  let value;
28484
28508
  if (el.tagName === "INPUT" && el.type === "checkbox") {
28485
- let t = el.getAttribute("true-value") || "Y";
28486
- let f = el.getAttribute("false-value") || "N";
28509
+ const t = el.getAttribute("true-value") || "Y";
28510
+ const f = el.getAttribute("false-value") || "N";
28487
28511
  value = el.checked ? t : f;
28488
- } else if (el.tagName === "INPUT" && el.type === "radio") {
28489
- value = el.value;
28490
28512
  } else {
28491
28513
  value = el.value;
28492
28514
  }
28493
28515
 
28516
+ // 중복 name 처리 (배열화)
28494
28517
  if (jsonData[key]) {
28495
28518
  if (!Array.isArray(jsonData[key])) jsonData[key] = [jsonData[key]];
28496
28519
  jsonData[key].push(value);
@@ -28501,55 +28524,36 @@ class nxDiv extends HTMLElement {
28501
28524
  return jsonData;
28502
28525
  };
28503
28526
 
28504
- setData = (jsonData) => {
28527
+ // 파라미터가 있으면 해당 값으로, 없으면 전체 공백 초기화
28528
+ clearData = (jsonData = {}) => {
28529
+ this.#refreshListeners();
28505
28530
  this.#getElements().forEach(el => {
28506
- el.removeEventListener("input", this.#changeHandler);
28507
- el.addEventListener("input", this.#changeHandler);
28531
+ const key = el.name;
28532
+ if (!key) return;
28533
+ const val = (jsonData && jsonData[key] !== undefined) ? jsonData[key] : "";
28534
+ this.#updateElement(el, val);
28508
28535
  });
28536
+ this.#changed(false);
28537
+ };
28509
28538
 
28539
+ setData = (jsonData) => {
28510
28540
  if (!jsonData || typeof jsonData !== 'object') return;
28541
+ this.#refreshListeners();
28511
28542
 
28512
28543
  let bChanged = false;
28513
28544
  this.#getElements().forEach(el => {
28514
28545
  const key = el.name;
28515
- //console.log(el.tagName, key, el.name);
28516
-
28517
28546
  if (!key || !jsonData.hasOwnProperty(key)) return;
28518
28547
 
28519
- const value = jsonData[key];
28520
- const inputTags = ["INPUT", "TEXTAREA", "SELECT", "NX-EDITOR"];
28521
-
28522
- if (inputTags.includes(el.tagName)) {
28523
- if (el.type === "checkbox") {
28524
- let t = el.getAttribute("true-value") || "Y";
28525
- el.getAttribute("false-value") || "N";
28526
- const isChecked = (t === String(value));
28527
- if (el.checked !== isChecked) bChanged = true;
28528
- el.checked = isChecked;
28529
- } else if (el.type === "radio") {
28530
- const isChecked = (String(el.value) === String(value));
28531
- if (el.checked !== isChecked) bChanged = true;
28532
- el.checked = isChecked;
28533
- } else {
28534
- if (el.value !== value) bChanged = true;
28535
- el.value = value;
28536
- }
28537
- } else {
28538
- if (el.textContent !== value) bChanged = true;
28539
- el.textContent = value;
28548
+ if (this.#updateElement(el, jsonData[key])) {
28549
+ bChanged = true;
28540
28550
  }
28541
28551
  });
28542
- if (bChanged) this.#changed(bChanged);
28543
- };
28544
-
28545
- clearData = (bChanged) => {
28546
-
28547
-
28548
- this.#changed(false);
28552
+ if (bChanged) this.#changed(true);
28549
28553
  };
28550
28554
 
28551
28555
  initData = (jsonData) => {
28552
- this.setData(jsonData);
28556
+ this.clearData(jsonData); // clearData가 이미 초기화 로직을 포함함
28553
28557
  this.#changed(false);
28554
28558
  };
28555
28559
 
@@ -28561,30 +28565,15 @@ class nxDiv extends HTMLElement {
28561
28565
  }
28562
28566
  }
28563
28567
 
28564
- #changeHandler = (e) => {
28565
- this.#changed(true);
28566
- }
28568
+ #changeHandler = (e) => this.#changed(true);
28567
28569
 
28568
28570
  #init = () => {
28569
- /** CSS style 적용 */
28570
28571
  for (const attr of this.attributes) {
28571
28572
  if (attr.name.startsWith("css-")) {
28572
28573
  this.style.setProperty(attr.name.substring(4), attr.value);
28573
28574
  }
28574
28575
  }
28575
-
28576
- //console.log("=========");
28577
- //console.log(this.innerHTML.trim());
28578
- this.originContents = this.innerHTML.trim();
28579
-
28580
- /**
28581
28576
  this.originContents = this.innerHTML.trim();
28582
- this.innerHTML = ""; // 기존 내부 HTML 제거
28583
-
28584
- // 만약 순수 nx-div로만 쓰일 경우(상속 x), 내용을 shadow에 채워줌
28585
- if (this.shadowRoot && this.tagName.toLowerCase() === 'nx-div') {
28586
- this.shadowRoot.innerHTML = this.originContents;
28587
- } */
28588
28577
  };
28589
28578
  }
28590
28579
 
@@ -28432,19 +28432,15 @@ customElements.define("nx-title", nxTitle);
28432
28432
  class nxDiv extends HTMLElement {
28433
28433
  originContents;
28434
28434
  #isInitialized = false;
28435
- #root; // Shadow DOM 사용 여부에 따라 shadowRoot 또는 this를 가리킴
28435
+ #root;
28436
28436
 
28437
28437
  constructor() {
28438
28438
  super();
28439
- // constructor에서는 속성을 읽을 수 없으므로 초기화만 준비합니다.
28440
28439
  }
28441
28440
 
28442
28441
  connectedCallback() {
28443
28442
  if (!this.#isInitialized) {
28444
- // 1. 여기서 속성을 읽어 Shadow DOM 사용 여부를 결정합니다.
28445
- // use-shadow 속성이 "false"가 아닐 때만 Shadow DOM을 생성 (기본값 true)
28446
28443
  const useShadow = this.getAttribute("use-shadow") !== "false";
28447
-
28448
28444
  if (useShadow && !this.shadowRoot) {
28449
28445
  this.attachShadow({ mode: 'open' });
28450
28446
  this.#root = this.shadowRoot;
@@ -28454,22 +28450,50 @@ class nxDiv extends HTMLElement {
28454
28450
 
28455
28451
  this.#init();
28456
28452
  this.#isInitialized = true;
28457
- return true;
28458
28453
  }
28459
- return false;
28460
28454
  }
28461
28455
 
28462
- // 자식 클래스에서 접근 가능하도록 getter 제공
28463
- get root() {
28464
- return this.#root || this;
28465
- }
28456
+ get root() { return this.#root || this; }
28466
28457
 
28467
- // 공통 쿼리 함수: 현재 root(Shadow 또는 Light DOM)에서 요소를 찾음
28468
28458
  #getElements() {
28469
- // ShadowRoot가 있으면 shadowRoot에서, 없으면 본체(this)에서 찾음
28470
28459
  return ninegrid.querySelectorAll("input[name], textarea[name], select[name], nx-editor[name]", this.#root);
28471
28460
  }
28472
28461
 
28462
+ // [공통 로직 1] 특정 요소에 값을 쓰거나 초기화하는 핵심 함수
28463
+ #updateElement(el, value) {
28464
+ const tagName = el.tagName.toUpperCase();
28465
+ const type = el.type;
28466
+ let isChanged = false;
28467
+
28468
+ if (["INPUT", "TEXTAREA", "SELECT", "NX-EDITOR"].includes(tagName)) {
28469
+ if (type === "checkbox") {
28470
+ const t = el.getAttribute("true-value") || "Y";
28471
+ const isChecked = (String(t) === String(value));
28472
+ if (el.checked !== isChecked) isChanged = true;
28473
+ el.checked = isChecked;
28474
+ } else if (type === "radio") {
28475
+ const isChecked = (String(el.value) === String(value));
28476
+ if (el.checked !== isChecked) isChanged = true;
28477
+ el.checked = isChecked;
28478
+ } else {
28479
+ if (el.value !== value) isChanged = true;
28480
+ el.value = value;
28481
+ }
28482
+ } else {
28483
+ if (el.textContent !== value) isChanged = true;
28484
+ el.textContent = value;
28485
+ }
28486
+ return isChanged;
28487
+ }
28488
+
28489
+ // [공통 로직 2] 이벤트 리스너 일괄 등록
28490
+ #refreshListeners() {
28491
+ this.#getElements().forEach(el => {
28492
+ el.removeEventListener("input", this.#changeHandler);
28493
+ el.addEventListener("input", this.#changeHandler);
28494
+ });
28495
+ }
28496
+
28473
28497
  getData = () => {
28474
28498
  const jsonData = {};
28475
28499
  this.#getElements().forEach(el => {
@@ -28478,15 +28502,14 @@ class nxDiv extends HTMLElement {
28478
28502
 
28479
28503
  let value;
28480
28504
  if (el.tagName === "INPUT" && el.type === "checkbox") {
28481
- let t = el.getAttribute("true-value") || "Y";
28482
- let f = el.getAttribute("false-value") || "N";
28505
+ const t = el.getAttribute("true-value") || "Y";
28506
+ const f = el.getAttribute("false-value") || "N";
28483
28507
  value = el.checked ? t : f;
28484
- } else if (el.tagName === "INPUT" && el.type === "radio") {
28485
- value = el.value;
28486
28508
  } else {
28487
28509
  value = el.value;
28488
28510
  }
28489
28511
 
28512
+ // 중복 name 처리 (배열화)
28490
28513
  if (jsonData[key]) {
28491
28514
  if (!Array.isArray(jsonData[key])) jsonData[key] = [jsonData[key]];
28492
28515
  jsonData[key].push(value);
@@ -28497,55 +28520,36 @@ class nxDiv extends HTMLElement {
28497
28520
  return jsonData;
28498
28521
  };
28499
28522
 
28500
- setData = (jsonData) => {
28523
+ // 파라미터가 있으면 해당 값으로, 없으면 전체 공백 초기화
28524
+ clearData = (jsonData = {}) => {
28525
+ this.#refreshListeners();
28501
28526
  this.#getElements().forEach(el => {
28502
- el.removeEventListener("input", this.#changeHandler);
28503
- el.addEventListener("input", this.#changeHandler);
28527
+ const key = el.name;
28528
+ if (!key) return;
28529
+ const val = (jsonData && jsonData[key] !== undefined) ? jsonData[key] : "";
28530
+ this.#updateElement(el, val);
28504
28531
  });
28532
+ this.#changed(false);
28533
+ };
28505
28534
 
28535
+ setData = (jsonData) => {
28506
28536
  if (!jsonData || typeof jsonData !== 'object') return;
28537
+ this.#refreshListeners();
28507
28538
 
28508
28539
  let bChanged = false;
28509
28540
  this.#getElements().forEach(el => {
28510
28541
  const key = el.name;
28511
- //console.log(el.tagName, key, el.name);
28512
-
28513
28542
  if (!key || !jsonData.hasOwnProperty(key)) return;
28514
28543
 
28515
- const value = jsonData[key];
28516
- const inputTags = ["INPUT", "TEXTAREA", "SELECT", "NX-EDITOR"];
28517
-
28518
- if (inputTags.includes(el.tagName)) {
28519
- if (el.type === "checkbox") {
28520
- let t = el.getAttribute("true-value") || "Y";
28521
- el.getAttribute("false-value") || "N";
28522
- const isChecked = (t === String(value));
28523
- if (el.checked !== isChecked) bChanged = true;
28524
- el.checked = isChecked;
28525
- } else if (el.type === "radio") {
28526
- const isChecked = (String(el.value) === String(value));
28527
- if (el.checked !== isChecked) bChanged = true;
28528
- el.checked = isChecked;
28529
- } else {
28530
- if (el.value !== value) bChanged = true;
28531
- el.value = value;
28532
- }
28533
- } else {
28534
- if (el.textContent !== value) bChanged = true;
28535
- el.textContent = value;
28544
+ if (this.#updateElement(el, jsonData[key])) {
28545
+ bChanged = true;
28536
28546
  }
28537
28547
  });
28538
- if (bChanged) this.#changed(bChanged);
28539
- };
28540
-
28541
- clearData = (bChanged) => {
28542
-
28543
-
28544
- this.#changed(false);
28548
+ if (bChanged) this.#changed(true);
28545
28549
  };
28546
28550
 
28547
28551
  initData = (jsonData) => {
28548
- this.setData(jsonData);
28552
+ this.clearData(jsonData); // clearData가 이미 초기화 로직을 포함함
28549
28553
  this.#changed(false);
28550
28554
  };
28551
28555
 
@@ -28557,30 +28561,15 @@ class nxDiv extends HTMLElement {
28557
28561
  }
28558
28562
  }
28559
28563
 
28560
- #changeHandler = (e) => {
28561
- this.#changed(true);
28562
- }
28564
+ #changeHandler = (e) => this.#changed(true);
28563
28565
 
28564
28566
  #init = () => {
28565
- /** CSS style 적용 */
28566
28567
  for (const attr of this.attributes) {
28567
28568
  if (attr.name.startsWith("css-")) {
28568
28569
  this.style.setProperty(attr.name.substring(4), attr.value);
28569
28570
  }
28570
28571
  }
28571
-
28572
- //console.log("=========");
28573
- //console.log(this.innerHTML.trim());
28574
- this.originContents = this.innerHTML.trim();
28575
-
28576
- /**
28577
28572
  this.originContents = this.innerHTML.trim();
28578
- this.innerHTML = ""; // 기존 내부 HTML 제거
28579
-
28580
- // 만약 순수 nx-div로만 쓰일 경우(상속 x), 내용을 shadow에 채워줌
28581
- if (this.shadowRoot && this.tagName.toLowerCase() === 'nx-div') {
28582
- this.shadowRoot.innerHTML = this.originContents;
28583
- } */
28584
28573
  };
28585
28574
  }
28586
28575
 
package/dist/nx/_nxDiv.js CHANGED
@@ -3,19 +3,15 @@ import ninegrid from "../index.js";
3
3
  export class nxDiv extends HTMLElement {
4
4
  originContents;
5
5
  #isInitialized = false;
6
- #root; // Shadow DOM 사용 여부에 따라 shadowRoot 또는 this를 가리킴
6
+ #root;
7
7
 
8
8
  constructor() {
9
9
  super();
10
- // constructor에서는 속성을 읽을 수 없으므로 초기화만 준비합니다.
11
10
  }
12
11
 
13
12
  connectedCallback() {
14
13
  if (!this.#isInitialized) {
15
- // 1. 여기서 속성을 읽어 Shadow DOM 사용 여부를 결정합니다.
16
- // use-shadow 속성이 "false"가 아닐 때만 Shadow DOM을 생성 (기본값 true)
17
14
  const useShadow = this.getAttribute("use-shadow") !== "false";
18
-
19
15
  if (useShadow && !this.shadowRoot) {
20
16
  this.attachShadow({ mode: 'open' });
21
17
  this.#root = this.shadowRoot;
@@ -25,22 +21,50 @@ export class nxDiv extends HTMLElement {
25
21
 
26
22
  this.#init();
27
23
  this.#isInitialized = true;
28
- return true;
29
24
  }
30
- return false;
31
25
  }
32
26
 
33
- // 자식 클래스에서 접근 가능하도록 getter 제공
34
- get root() {
35
- return this.#root || this;
36
- }
27
+ get root() { return this.#root || this; }
37
28
 
38
- // 공통 쿼리 함수: 현재 root(Shadow 또는 Light DOM)에서 요소를 찾음
39
29
  #getElements() {
40
- // ShadowRoot가 있으면 shadowRoot에서, 없으면 본체(this)에서 찾음
41
30
  return ninegrid.querySelectorAll("input[name], textarea[name], select[name], nx-editor[name]", this.#root);
42
31
  }
43
32
 
33
+ // [공통 로직 1] 특정 요소에 값을 쓰거나 초기화하는 핵심 함수
34
+ #updateElement(el, value) {
35
+ const tagName = el.tagName.toUpperCase();
36
+ const type = el.type;
37
+ let isChanged = false;
38
+
39
+ if (["INPUT", "TEXTAREA", "SELECT", "NX-EDITOR"].includes(tagName)) {
40
+ if (type === "checkbox") {
41
+ const t = el.getAttribute("true-value") || "Y";
42
+ const isChecked = (String(t) === String(value));
43
+ if (el.checked !== isChecked) isChanged = true;
44
+ el.checked = isChecked;
45
+ } else if (type === "radio") {
46
+ const isChecked = (String(el.value) === String(value));
47
+ if (el.checked !== isChecked) isChanged = true;
48
+ el.checked = isChecked;
49
+ } else {
50
+ if (el.value !== value) isChanged = true;
51
+ el.value = value;
52
+ }
53
+ } else {
54
+ if (el.textContent !== value) isChanged = true;
55
+ el.textContent = value;
56
+ }
57
+ return isChanged;
58
+ }
59
+
60
+ // [공통 로직 2] 이벤트 리스너 일괄 등록
61
+ #refreshListeners() {
62
+ this.#getElements().forEach(el => {
63
+ el.removeEventListener("input", this.#changeHandler);
64
+ el.addEventListener("input", this.#changeHandler);
65
+ });
66
+ }
67
+
44
68
  getData = () => {
45
69
  const jsonData = {};
46
70
  this.#getElements().forEach(el => {
@@ -49,15 +73,14 @@ export class nxDiv extends HTMLElement {
49
73
 
50
74
  let value;
51
75
  if (el.tagName === "INPUT" && el.type === "checkbox") {
52
- let t = el.getAttribute("true-value") || "Y";
53
- let f = el.getAttribute("false-value") || "N";
76
+ const t = el.getAttribute("true-value") || "Y";
77
+ const f = el.getAttribute("false-value") || "N";
54
78
  value = el.checked ? t : f;
55
- } else if (el.tagName === "INPUT" && el.type === "radio") {
56
- value = el.value;
57
79
  } else {
58
80
  value = el.value;
59
81
  }
60
82
 
83
+ // 중복 name 처리 (배열화)
61
84
  if (jsonData[key]) {
62
85
  if (!Array.isArray(jsonData[key])) jsonData[key] = [jsonData[key]];
63
86
  jsonData[key].push(value);
@@ -68,55 +91,36 @@ export class nxDiv extends HTMLElement {
68
91
  return jsonData;
69
92
  };
70
93
 
71
- setData = (jsonData) => {
94
+ // 파라미터가 있으면 해당 값으로, 없으면 전체 공백 초기화
95
+ clearData = (jsonData = {}) => {
96
+ this.#refreshListeners();
72
97
  this.#getElements().forEach(el => {
73
- el.removeEventListener("input", this.#changeHandler);
74
- el.addEventListener("input", this.#changeHandler);
98
+ const key = el.name;
99
+ if (!key) return;
100
+ const val = (jsonData && jsonData[key] !== undefined) ? jsonData[key] : "";
101
+ this.#updateElement(el, val);
75
102
  });
103
+ this.#changed(false);
104
+ };
76
105
 
106
+ setData = (jsonData) => {
77
107
  if (!jsonData || typeof jsonData !== 'object') return;
108
+ this.#refreshListeners();
78
109
 
79
110
  let bChanged = false;
80
111
  this.#getElements().forEach(el => {
81
112
  const key = el.name;
82
- //console.log(el.tagName, key, el.name);
83
-
84
113
  if (!key || !jsonData.hasOwnProperty(key)) return;
85
114
 
86
- const value = jsonData[key];
87
- const inputTags = ["INPUT", "TEXTAREA", "SELECT", "NX-EDITOR"];
88
-
89
- if (inputTags.includes(el.tagName)) {
90
- if (el.type === "checkbox") {
91
- let t = el.getAttribute("true-value") || "Y";
92
- let f = el.getAttribute("false-value") || "N";
93
- const isChecked = (t === String(value));
94
- if (el.checked !== isChecked) bChanged = true;
95
- el.checked = isChecked;
96
- } else if (el.type === "radio") {
97
- const isChecked = (String(el.value) === String(value));
98
- if (el.checked !== isChecked) bChanged = true;
99
- el.checked = isChecked;
100
- } else {
101
- if (el.value !== value) bChanged = true;
102
- el.value = value;
103
- }
104
- } else {
105
- if (el.textContent !== value) bChanged = true;
106
- el.textContent = value;
115
+ if (this.#updateElement(el, jsonData[key])) {
116
+ bChanged = true;
107
117
  }
108
118
  });
109
- if (bChanged) this.#changed(bChanged);
110
- };
111
-
112
- clearData = (bChanged) => {
113
-
114
-
115
- this.#changed(false);
119
+ if (bChanged) this.#changed(true);
116
120
  };
117
121
 
118
122
  initData = (jsonData) => {
119
- this.setData(jsonData);
123
+ this.clearData(jsonData); // clearData가 이미 초기화 로직을 포함함
120
124
  this.#changed(false);
121
125
  };
122
126
 
@@ -128,29 +132,14 @@ export class nxDiv extends HTMLElement {
128
132
  }
129
133
  }
130
134
 
131
- #changeHandler = (e) => {
132
- this.#changed(true);
133
- }
135
+ #changeHandler = (e) => this.#changed(true);
134
136
 
135
137
  #init = () => {
136
- /** CSS style 적용 */
137
138
  for (const attr of this.attributes) {
138
139
  if (attr.name.startsWith("css-")) {
139
140
  this.style.setProperty(attr.name.substring(4), attr.value);
140
141
  }
141
142
  }
142
-
143
- //console.log("=========");
144
- //console.log(this.innerHTML.trim());
145
- this.originContents = this.innerHTML.trim();
146
-
147
- /**
148
143
  this.originContents = this.innerHTML.trim();
149
- this.innerHTML = ""; // 기존 내부 HTML 제거
150
-
151
- // 만약 순수 nx-div로만 쓰일 경우(상속 x), 내용을 shadow에 채워줌
152
- if (this.shadowRoot && this.tagName.toLowerCase() === 'nx-div') {
153
- this.shadowRoot.innerHTML = this.originContents;
154
- } */
155
144
  };
156
145
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ninegrid2",
3
3
  "type": "module",
4
- "version": "6.1378.0",
4
+ "version": "6.1379.0",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "exports": {
package/src/nx/_nxDiv.js CHANGED
@@ -3,19 +3,15 @@ import ninegrid from "../index.js";
3
3
  export class nxDiv extends HTMLElement {
4
4
  originContents;
5
5
  #isInitialized = false;
6
- #root; // Shadow DOM 사용 여부에 따라 shadowRoot 또는 this를 가리킴
6
+ #root;
7
7
 
8
8
  constructor() {
9
9
  super();
10
- // constructor에서는 속성을 읽을 수 없으므로 초기화만 준비합니다.
11
10
  }
12
11
 
13
12
  connectedCallback() {
14
13
  if (!this.#isInitialized) {
15
- // 1. 여기서 속성을 읽어 Shadow DOM 사용 여부를 결정합니다.
16
- // use-shadow 속성이 "false"가 아닐 때만 Shadow DOM을 생성 (기본값 true)
17
14
  const useShadow = this.getAttribute("use-shadow") !== "false";
18
-
19
15
  if (useShadow && !this.shadowRoot) {
20
16
  this.attachShadow({ mode: 'open' });
21
17
  this.#root = this.shadowRoot;
@@ -25,22 +21,50 @@ export class nxDiv extends HTMLElement {
25
21
 
26
22
  this.#init();
27
23
  this.#isInitialized = true;
28
- return true;
29
24
  }
30
- return false;
31
25
  }
32
26
 
33
- // 자식 클래스에서 접근 가능하도록 getter 제공
34
- get root() {
35
- return this.#root || this;
36
- }
27
+ get root() { return this.#root || this; }
37
28
 
38
- // 공통 쿼리 함수: 현재 root(Shadow 또는 Light DOM)에서 요소를 찾음
39
29
  #getElements() {
40
- // ShadowRoot가 있으면 shadowRoot에서, 없으면 본체(this)에서 찾음
41
30
  return ninegrid.querySelectorAll("input[name], textarea[name], select[name], nx-editor[name]", this.#root);
42
31
  }
43
32
 
33
+ // [공통 로직 1] 특정 요소에 값을 쓰거나 초기화하는 핵심 함수
34
+ #updateElement(el, value) {
35
+ const tagName = el.tagName.toUpperCase();
36
+ const type = el.type;
37
+ let isChanged = false;
38
+
39
+ if (["INPUT", "TEXTAREA", "SELECT", "NX-EDITOR"].includes(tagName)) {
40
+ if (type === "checkbox") {
41
+ const t = el.getAttribute("true-value") || "Y";
42
+ const isChecked = (String(t) === String(value));
43
+ if (el.checked !== isChecked) isChanged = true;
44
+ el.checked = isChecked;
45
+ } else if (type === "radio") {
46
+ const isChecked = (String(el.value) === String(value));
47
+ if (el.checked !== isChecked) isChanged = true;
48
+ el.checked = isChecked;
49
+ } else {
50
+ if (el.value !== value) isChanged = true;
51
+ el.value = value;
52
+ }
53
+ } else {
54
+ if (el.textContent !== value) isChanged = true;
55
+ el.textContent = value;
56
+ }
57
+ return isChanged;
58
+ }
59
+
60
+ // [공통 로직 2] 이벤트 리스너 일괄 등록
61
+ #refreshListeners() {
62
+ this.#getElements().forEach(el => {
63
+ el.removeEventListener("input", this.#changeHandler);
64
+ el.addEventListener("input", this.#changeHandler);
65
+ });
66
+ }
67
+
44
68
  getData = () => {
45
69
  const jsonData = {};
46
70
  this.#getElements().forEach(el => {
@@ -49,15 +73,14 @@ export class nxDiv extends HTMLElement {
49
73
 
50
74
  let value;
51
75
  if (el.tagName === "INPUT" && el.type === "checkbox") {
52
- let t = el.getAttribute("true-value") || "Y";
53
- let f = el.getAttribute("false-value") || "N";
76
+ const t = el.getAttribute("true-value") || "Y";
77
+ const f = el.getAttribute("false-value") || "N";
54
78
  value = el.checked ? t : f;
55
- } else if (el.tagName === "INPUT" && el.type === "radio") {
56
- value = el.value;
57
79
  } else {
58
80
  value = el.value;
59
81
  }
60
82
 
83
+ // 중복 name 처리 (배열화)
61
84
  if (jsonData[key]) {
62
85
  if (!Array.isArray(jsonData[key])) jsonData[key] = [jsonData[key]];
63
86
  jsonData[key].push(value);
@@ -68,55 +91,36 @@ export class nxDiv extends HTMLElement {
68
91
  return jsonData;
69
92
  };
70
93
 
71
- setData = (jsonData) => {
94
+ // 파라미터가 있으면 해당 값으로, 없으면 전체 공백 초기화
95
+ clearData = (jsonData = {}) => {
96
+ this.#refreshListeners();
72
97
  this.#getElements().forEach(el => {
73
- el.removeEventListener("input", this.#changeHandler);
74
- el.addEventListener("input", this.#changeHandler);
98
+ const key = el.name;
99
+ if (!key) return;
100
+ const val = (jsonData && jsonData[key] !== undefined) ? jsonData[key] : "";
101
+ this.#updateElement(el, val);
75
102
  });
103
+ this.#changed(false);
104
+ };
76
105
 
106
+ setData = (jsonData) => {
77
107
  if (!jsonData || typeof jsonData !== 'object') return;
108
+ this.#refreshListeners();
78
109
 
79
110
  let bChanged = false;
80
111
  this.#getElements().forEach(el => {
81
112
  const key = el.name;
82
- //console.log(el.tagName, key, el.name);
83
-
84
113
  if (!key || !jsonData.hasOwnProperty(key)) return;
85
114
 
86
- const value = jsonData[key];
87
- const inputTags = ["INPUT", "TEXTAREA", "SELECT", "NX-EDITOR"];
88
-
89
- if (inputTags.includes(el.tagName)) {
90
- if (el.type === "checkbox") {
91
- let t = el.getAttribute("true-value") || "Y";
92
- let f = el.getAttribute("false-value") || "N";
93
- const isChecked = (t === String(value));
94
- if (el.checked !== isChecked) bChanged = true;
95
- el.checked = isChecked;
96
- } else if (el.type === "radio") {
97
- const isChecked = (String(el.value) === String(value));
98
- if (el.checked !== isChecked) bChanged = true;
99
- el.checked = isChecked;
100
- } else {
101
- if (el.value !== value) bChanged = true;
102
- el.value = value;
103
- }
104
- } else {
105
- if (el.textContent !== value) bChanged = true;
106
- el.textContent = value;
115
+ if (this.#updateElement(el, jsonData[key])) {
116
+ bChanged = true;
107
117
  }
108
118
  });
109
- if (bChanged) this.#changed(bChanged);
110
- };
111
-
112
- clearData = (bChanged) => {
113
-
114
-
115
- this.#changed(false);
119
+ if (bChanged) this.#changed(true);
116
120
  };
117
121
 
118
122
  initData = (jsonData) => {
119
- this.setData(jsonData);
123
+ this.clearData(jsonData); // clearData가 이미 초기화 로직을 포함함
120
124
  this.#changed(false);
121
125
  };
122
126
 
@@ -128,29 +132,14 @@ export class nxDiv extends HTMLElement {
128
132
  }
129
133
  }
130
134
 
131
- #changeHandler = (e) => {
132
- this.#changed(true);
133
- }
135
+ #changeHandler = (e) => this.#changed(true);
134
136
 
135
137
  #init = () => {
136
- /** CSS style 적용 */
137
138
  for (const attr of this.attributes) {
138
139
  if (attr.name.startsWith("css-")) {
139
140
  this.style.setProperty(attr.name.substring(4), attr.value);
140
141
  }
141
142
  }
142
-
143
- //console.log("=========");
144
- //console.log(this.innerHTML.trim());
145
- this.originContents = this.innerHTML.trim();
146
-
147
- /**
148
143
  this.originContents = this.innerHTML.trim();
149
- this.innerHTML = ""; // 기존 내부 HTML 제거
150
-
151
- // 만약 순수 nx-div로만 쓰일 경우(상속 x), 내용을 shadow에 채워줌
152
- if (this.shadowRoot && this.tagName.toLowerCase() === 'nx-div') {
153
- this.shadowRoot.innerHTML = this.originContents;
154
- } */
155
144
  };
156
145
  }