@nys-cui/cui-formpill 0.1.0 → 0.2.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/cui-formpill.js +238 -27
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "main": "./dist/js/cui-formpill.js",
8
8
  "type": "module",
9
- "version": "0.1.0",
9
+ "version": "0.2.0",
10
10
  "scripts": {
11
11
  "clean": "rm -rf ./dist",
12
12
  "build": "npm run clean && cui --dep",
@@ -7,6 +7,7 @@ class CUI_FORMPILL_PILL extends HTMLElement {
7
7
 
8
8
  this.attachShadow({ mode: 'open' });
9
9
 
10
+ this._connected = false;
10
11
  this._state = {};
11
12
 
12
13
  this.oPropsToStateNames = {
@@ -50,8 +51,7 @@ class CUI_FORMPILL_PILL extends HTMLElement {
50
51
  setState(props) {
51
52
  // Need to map props to state variable names if we want to keep them prefixed.
52
53
  this._state = Object.assign(this._state, this.normalizeProps(props));
53
-
54
- this.render();
54
+ if (this._connected) this.render();
55
55
  }
56
56
 
57
57
  clearSlottedElements(slotName) {
@@ -90,7 +90,7 @@ class CUI_FORMPILL_PILL extends HTMLElement {
90
90
  this._state.sValue3 = (this.getAttribute('value3')) ? this.getAttribute('value3') : null;
91
91
  this._state.asValues = (this.getAttribute('values')) ? this.getAttribute('values') : null;
92
92
 
93
- this._initialState = this._state;
93
+ this._connected = true;
94
94
  this.render();
95
95
  }
96
96
 
@@ -142,7 +142,6 @@ class CUI_FORMPILL_PILL extends HTMLElement {
142
142
 
143
143
  removeButton.addEventListener('click', (e) => {
144
144
  this.remove();
145
-
146
145
  this.dispatchEvent(myEvent)
147
146
  })
148
147
 
@@ -187,7 +186,8 @@ class CUI_FORMPILL extends HTMLElement {
187
186
  "html": "sHtmlContent",
188
187
  "config": "configData",
189
188
  "addTitle": "sAddTitle",
190
- "updateTitle": "sUpdateTitle"
189
+ "updateTitle": "sUpdateTitle",
190
+ "value": "aoValue"
191
191
 
192
192
  }
193
193
 
@@ -205,15 +205,99 @@ class CUI_FORMPILL extends HTMLElement {
205
205
  </div>`;
206
206
  }
207
207
 
208
- setState(props) {
208
+ setInitialState(state) {
209
+ for (let [k, v] of Object.entries(this._state)) {
210
+ switch (k) {
211
+ case "adPills":
212
+ this._initialState[k] = [];
213
+ for (let pill of v) {
214
+ let copiedPill = document.createElement("cui-formpill-pill");
215
+ if (!state) {
216
+ for (const attrValue of structuredClone(pill.getAttributeNames()))
217
+ copiedPill.setAttribute(attrValue, pill.getAttribute(attrValue));
218
+
219
+ } else {
220
+
221
+ for (const attrValue of structuredClone(pill.getAttributeNames()))
222
+ copiedPill.setAttribute(attrValue, pill._state[pill.oPropsToStateNames[attrValue]]);
223
+
224
+ }
225
+ this._initialState[k].push(copiedPill);
226
+
227
+ }
228
+ break;
229
+
230
+ case "criteriaList":
231
+ this._initialState[k] = structuredClone(v);
232
+ break;
233
+
234
+ case "configData":
235
+ this._initialState[k] = structuredClone(v);
236
+ break;
237
+
238
+ default:
239
+ this._initialState[k] = v;
240
+
241
+ }
242
+
243
+ }
244
+ }
245
+
246
+ setState(props, bOverrideInitialState = false) {
209
247
  // Need to map props to state variable names if we want to keep them prefixed.
248
+ if (!this._initialState) this._initialState = {};
249
+
210
250
  this._state = Object.assign(this._state, this.normalizeProps(props));
211
251
 
212
252
  if (this._connected) {
213
253
  this.render();
214
254
  }
255
+
256
+ if (bOverrideInitialState) {
257
+ if (this._connected) {
258
+ this.setInitialState(true);
259
+ } else {
260
+ this.setInitialState();
261
+ }
262
+ }
215
263
  }
264
+ reset() {
216
265
 
266
+ for (const [k, v] of Object.entries(this._initialState)) {
267
+ switch (k) {
268
+ case "adPills":
269
+ this._state[k] = [];
270
+ for (const pill of v) {
271
+ const myEvent = new CustomEvent("pill-removed", {
272
+ detail: { pill: pill }
273
+ });
274
+ this.dispatchEvent(myEvent);
275
+ let copiedPill = document.createElement("cui-formpill-pill");
276
+ for (const attrValue of structuredClone(pill.getAttributeNames())) {
277
+ copiedPill.setAttribute(attrValue, pill.getAttribute(attrValue));
278
+ }
279
+ this._state[k].push(copiedPill);
280
+
281
+ }
282
+ break;
283
+
284
+ case "criteriaList":
285
+ this._state[k] = structuredClone(v);
286
+ break;
287
+
288
+ case "configData":
289
+ this._state[k] = structuredClone(v);
290
+ break;
291
+
292
+ default:
293
+ this._state[k] = v;
294
+
295
+ }
296
+
297
+ }
298
+
299
+ this.render(true);
300
+ }
217
301
  get label() {
218
302
 
219
303
  if (this.dLabelContents) {
@@ -270,15 +354,17 @@ class CUI_FORMPILL extends HTMLElement {
270
354
  this._state.sComponentKey = (this.getAttribute('componentKey')) ? this.getAttribute('componentKey') : "";
271
355
  this._state.bAccessibleHideLabel = this.hasAttribute('accessiblehidelabel') ? true : false;
272
356
  this._state.sPosition = (this.getAttribute('position')) ? this.getAttribute('position') : "bottom-center";
357
+ this._state.aoValue = (this.getAttribute('value')) ? this.getAttribute('value') : [];
273
358
 
274
359
  //Set initial state only once at connection to page. At this point any initial data should have been passed to the field.
275
360
  if (!this._initialState || this._initialState == null) {
276
361
  // Shallow clone for now unless it's determined we need a deep clone.
277
- this._initialState = { ...this._state };
362
+ this._initialState = {};
278
363
  }
279
364
 
280
- this._state.fGlobalBodyClick = this.globalBodyClick.bind(this);
365
+ this.fGlobalBodyClick = this.globalBodyClick.bind(this);
281
366
 
367
+ this.setInitialState();
282
368
  this.render();
283
369
  }
284
370
 
@@ -304,7 +390,7 @@ class CUI_FORMPILL extends HTMLElement {
304
390
  </div>`
305
391
  }
306
392
 
307
- render() {
393
+ render(reset = false) {
308
394
  this.clearShadowDom(this.shadowRoot);
309
395
  this.clearSlottedElements("menu-trigger");
310
396
  this.clearSlottedElements("labelContents");
@@ -312,6 +398,25 @@ class CUI_FORMPILL extends HTMLElement {
312
398
 
313
399
  this.shadowRoot.innerHTML = `${this.sFieldLayout} `;
314
400
 
401
+ this._state.adPills = [];
402
+
403
+ if (this._state.configData?.filterCriteria && !this._state.configData.filterCriteria.loadedPills) {
404
+ this._state.configData.filterCriteria.loadedPills = []
405
+ }
406
+
407
+ if (this._state.aoValue && this._state.aoValue.length > 0 && this._state.configData?.filterCriteria?.loadedPills && reset === false) {
408
+ this._state.configData.filterCriteria.loadedPills = []
409
+ for (let pill of this._state.aoValue) {
410
+ this._state.configData.filterCriteria.loadedPills.push(pill);
411
+ }
412
+ this.addPillfromJSON();
413
+
414
+ } else if (reset === true) {
415
+ this.addPillfromJSON();
416
+ }
417
+
418
+
419
+
315
420
  let adSlots = this.shadowRoot.querySelectorAll('slot');
316
421
 
317
422
  if (adSlots.length) {
@@ -341,12 +446,40 @@ class CUI_FORMPILL extends HTMLElement {
341
446
  pillDiv.classList.add('pill-container');
342
447
  pillDiv.part = "pill-container"
343
448
  pillDiv.slot = "pill-container"
344
- let dTriggerElem = document.createElement('button');
449
+ this.appendChild(label);
450
+ this.appendChild(pillDiv);
345
451
 
452
+ let dTriggerElem = document.createElement('button');
346
453
  if (this._state.adPills.length > 0) {
454
+
347
455
  for (let i = 0; i < this._state.adPills.length; i++) {
456
+
348
457
  pillDiv.append(this._state.adPills[i])
458
+ const customEvent = new CustomEvent('pill-created', { detail: { pill: this._state.adPills[i] } });
459
+ this.dispatchEvent(customEvent);
460
+ this._state.adPills[i].addEventListener('pill_removed', (e) => {
461
+ let removedValue = e.detail.state.sValue1;
462
+ if (!this._state.criteriaList.some(item => item.value === removedValue)) {
463
+ this._state.criteriaList.unshift(this._state.configData.filterCriteria.items.find(item => item.value === removedValue));
464
+ }
465
+ const myEvent = new CustomEvent("pill-removed", {
466
+ detail: { pill: e.detail }
467
+ });
468
+ let index = this._state.adPills.findIndex(item => item._state == e.detail.state);
469
+
470
+ if (index > 0) {
471
+ this._state.adPills.splice(index, 1);
472
+
473
+ } else if (index === 0) {
474
+ this._state.adPills = [];
475
+ }
476
+ this.dispatchEvent(myEvent);
477
+ });
478
+ this.querySelectorAll('.pill-title')[pillDiv.children.length - 1].addEventListener('click', (e) => {
479
+ this.menuTriggerOnClick(e.target.closest("cui-formpill-pill"));
480
+ });
349
481
  }
482
+
350
483
  }
351
484
 
352
485
  dTriggerElem.title = this._state.sLabel;
@@ -383,10 +516,8 @@ class CUI_FORMPILL extends HTMLElement {
383
516
  dTriggerElem.prepend(addIconDiv);
384
517
  }
385
518
 
386
- this._state.dTriggerElem = dTriggerElem;
387
- this.appendChild(label)
388
- this.appendChild(pillDiv)
389
- this.appendChild(this._state.dTriggerElem);
519
+ this.dTriggerElem = dTriggerElem;
520
+ this.appendChild(this.dTriggerElem);
390
521
 
391
522
  window.addEventListener('resize', (e) => {
392
523
  this.windowResize(e);
@@ -455,11 +586,11 @@ class CUI_FORMPILL extends HTMLElement {
455
586
 
456
587
  dPopoverHeader.appendChild(dPopoverTitle);
457
588
 
458
- let closeButton = document.createElement('button');
589
+ let closeButton = document.createElement('button');
459
590
  closeButton.classList.add('close-button');
460
591
  closeButton.textContent = '×'
461
592
  dPopoverHeader.appendChild(closeButton);
462
- closeButton.addEventListener('click', () => {this.hidePopover()})
593
+ closeButton.addEventListener('click', () => { this.hidePopover() })
463
594
 
464
595
  let dPopoverFooter = document.createElement('div');
465
596
  dPopoverFooter.classList.add("popover-footer");
@@ -525,7 +656,7 @@ class CUI_FORMPILL extends HTMLElement {
525
656
 
526
657
  async displayPopover() {
527
658
 
528
- let adPopoverElements = await this.createPopover(this._state.dTriggerElem);
659
+ let adPopoverElements = await this.createPopover(this.dTriggerElem);
529
660
  let dPopoverBody = adPopoverElements[0];
530
661
  let dPopoverContent = adPopoverElements[1];
531
662
  let dMenuPopover = adPopoverElements[2];
@@ -541,7 +672,7 @@ class CUI_FORMPILL extends HTMLElement {
541
672
  if (this._state.configData) {
542
673
  if (this._state.configData.filterCriteria) {
543
674
  this.criteria = document.createElement('cui-listbox');
544
- this.criteria.setAttribute('search', '')
675
+ this.criteria.setAttribute('search', '');
545
676
  let items = []
546
677
 
547
678
  if (this._state.criteriaList === null) {
@@ -558,7 +689,7 @@ class CUI_FORMPILL extends HTMLElement {
558
689
  items.push(item);
559
690
  }
560
691
  }
561
-
692
+
562
693
  this.criteria.setState({ 'items': items, 'label': `${(this._state.configData.filterCriteria.fieldLabel) ? this._state.configData.filterCriteria.fieldLabel : 'Criteria'}` })
563
694
  this.criteria.setAttribute('required', '');
564
695
  this.criteria.setAttribute('componentKey', 'contextHeaderCriteria');
@@ -586,7 +717,7 @@ class CUI_FORMPILL extends HTMLElement {
586
717
  this.hidePopover();
587
718
  })
588
719
  }
589
- document.body.addEventListener('click', this._state.fGlobalBodyClick, false);
720
+ document.body.addEventListener('click', this.fGlobalBodyClick, false);
590
721
  });
591
722
 
592
723
 
@@ -644,7 +775,7 @@ class CUI_FORMPILL extends HTMLElement {
644
775
  this.hidePopover();
645
776
  })
646
777
  }
647
- document.body.addEventListener('click', this._state.fGlobalBodyClick, false);
778
+ document.body.addEventListener('click', this.fGlobalBodyClick, false);
648
779
  });
649
780
 
650
781
 
@@ -661,6 +792,7 @@ class CUI_FORMPILL extends HTMLElement {
661
792
  if (controls.options && controls.value) {
662
793
 
663
794
  this.method = document.createElement('cui-listbox');
795
+ if (controls.search) this.method.setAttribute('search', '');
664
796
  this.method.setState({ 'items': controls.options, 'label': `${(controls.fieldLabel) ? controls.fieldLabel : 'Method'}` });
665
797
  this.method.setAttribute('value', pill._state.sValue2)
666
798
  this.method.setAttribute('required', '');
@@ -743,6 +875,7 @@ class CUI_FORMPILL extends HTMLElement {
743
875
  if (controls.options && controls.value) {
744
876
 
745
877
  this.method = document.createElement('cui-listbox');
878
+ if (controls.search) this.method.setAttribute("search", "");
746
879
  this.method.setState({ 'items': controls.options, 'label': `${(controls.fieldLabel) ? controls.fieldLabel : 'Method'}` });
747
880
  this.method.setAttribute('required', '');
748
881
  this.method.setAttribute('componentKey', 'contextHeaderMethod');
@@ -764,6 +897,9 @@ class CUI_FORMPILL extends HTMLElement {
764
897
  if (controls.value.multiple) {
765
898
  this.dValueField.setAttribute('multiple', true)
766
899
  }
900
+ if (controls.value.search) {
901
+ this.dValueField.setAttribute('search', true)
902
+ }
767
903
  dPopoverBody.insertBefore(this.dValueField, dPopoverFooter);
768
904
  } else if (controls.value && controls.value.control) {
769
905
 
@@ -812,7 +948,6 @@ class CUI_FORMPILL extends HTMLElement {
812
948
  formPill.setAttribute('value2', this.method.value)
813
949
  formPill.setAttribute('value3', this.dValueField.value)
814
950
  let pillText = `${this.criteria._state.aItems.find(item => item.value === this.criteria.value)?.label}: ${this.dValueField.value}`
815
-
816
951
  if (sFor === 'update') {
817
952
  formPill.setState({
818
953
  'value1': this.criteria.value, 'value2': this.method.value, 'value3': this.dValueField.value,
@@ -836,10 +971,19 @@ class CUI_FORMPILL extends HTMLElement {
836
971
  if (!this._state.criteriaList.some(item => item.value === removedValue)) {
837
972
  this._state.criteriaList.unshift(this._state.configData.filterCriteria.items.find(item => item.value === removedValue));
838
973
  }
839
-
840
974
  const myEvent = new CustomEvent("pill-removed", {
841
975
  detail: { pill: e.detail }
842
976
  });
977
+
978
+ let index = this._state.adPills.findIndex(item => item._state == e.detail.state);
979
+
980
+ //if(index > 0){
981
+ this._state.adPills.splice(index, 1);
982
+
983
+ //}else if(index === 0){
984
+ //this._state.adPills = [];
985
+ //}
986
+
843
987
  this.dispatchEvent(myEvent);
844
988
  });
845
989
  }
@@ -855,8 +999,6 @@ class CUI_FORMPILL extends HTMLElement {
855
999
 
856
1000
  let curValue = this.criteria.value;
857
1001
  formPill.setAttribute('value1', curValue)
858
-
859
-
860
1002
  let pillText;
861
1003
  if (this.dValueField.value.indexOf(',') == -1) {
862
1004
  formPill.setAttribute('value2', this.dValueField.value)
@@ -908,6 +1050,15 @@ class CUI_FORMPILL extends HTMLElement {
908
1050
  const myEvent = new CustomEvent("pill-removed", {
909
1051
  detail: { pill: e.detail }
910
1052
  });
1053
+
1054
+ let index = this._state.adPills.findIndex(item => item._state == e.detail.state);
1055
+
1056
+ //if(index > 0){
1057
+ this._state.adPills.splice(index, 1);
1058
+
1059
+ //}else if(index === 0){
1060
+ // this._state.adPills = [];
1061
+ //}
911
1062
  this.dispatchEvent(myEvent);
912
1063
  });
913
1064
 
@@ -961,6 +1112,15 @@ class CUI_FORMPILL extends HTMLElement {
961
1112
  const myEvent = new CustomEvent("pill-removed", {
962
1113
  detail: { pill: e.detail }
963
1114
  });
1115
+ let index = this._state.adPills.findIndex(item => item._state == e.detail.state);
1116
+
1117
+ //if(index > 0){
1118
+ this._state.adPills.splice(index, 1);
1119
+
1120
+ //}else if(index === 0){
1121
+ //this._state.adPills = [];
1122
+ //}
1123
+
964
1124
  this.dispatchEvent(myEvent);
965
1125
  });
966
1126
  }
@@ -993,6 +1153,57 @@ class CUI_FORMPILL extends HTMLElement {
993
1153
 
994
1154
  }
995
1155
 
1156
+ addPillfromJSON() {
1157
+ if (this._state?.configData?.filterCriteria?.loadedPills) {
1158
+ for (let pill of this._state.configData.filterCriteria?.loadedPills) {
1159
+ let formPill;
1160
+ formPill = document.createElement('cui-formpill-pill');
1161
+ this._state.adPills.push(formPill);
1162
+
1163
+ for (const [k, v] of Object.entries(pill)) {
1164
+ formPill.setAttribute(k, v);
1165
+ }
1166
+
1167
+ let pillText;
1168
+
1169
+ if (pill.value2 != null && pill.value3 != null) {
1170
+ pillText = `${this._state.configData.filterCriteria.items.find(item => item.value === pill.value1)?.label}: ${pill.value3}`
1171
+ } else if (pill.values != null) {
1172
+ pillText = `${this._state.configData.filterCriteria.items.find(item => item.value === pill.value1)?.label}: ${pill.values}`
1173
+ } else if (pill.value2 != null) {
1174
+ pillText = `${this._state.configData.filterCriteria.items.find(item => item.value === pill.value1)?.label}: ${pill.value2}`
1175
+
1176
+ }
1177
+
1178
+ formPill.setAttribute('text', pillText.slice(0, 30) + (pillText.length > 30 ? "..." : ""))
1179
+ let items = [];
1180
+ if (this._state.criteriaList === null) {
1181
+ for (let item of this._state.configData.filterCriteria.items) {
1182
+ let lbValue = { 'label': item.label, 'value': item.value };
1183
+ if (item.multiple) {
1184
+ lbValue.multiple = item.multiple
1185
+ }
1186
+ items.push(lbValue);
1187
+ }
1188
+ this._state.criteriaList = items;
1189
+ } else {
1190
+ for (let item of this._state.criteriaList) {
1191
+ items.push(item);
1192
+ }
1193
+ }
1194
+ let updatedList = this._state.criteriaList.filter(item => {
1195
+ if (item.multiple) {
1196
+ return true;
1197
+ }
1198
+ return item.value !== pill.value1;
1199
+ });
1200
+
1201
+ this._state.criteriaList = updatedList;
1202
+
1203
+ }
1204
+ }
1205
+ }
1206
+
996
1207
  validateRegion(dRegion) {
997
1208
  let validationResult = this.cValidator.validateRegion(dRegion);
998
1209
 
@@ -1048,7 +1259,7 @@ class CUI_FORMPILL extends HTMLElement {
1048
1259
  this._state.dMenuPopover = null;
1049
1260
  }
1050
1261
 
1051
- document.body.removeEventListener('click', this._state.fGlobalBodyClick);
1262
+ document.body.removeEventListener('click', this.fGlobalBodyClick);
1052
1263
 
1053
1264
  this._state.bMenuDisplayed = false;
1054
1265
  }
@@ -1056,7 +1267,7 @@ class CUI_FORMPILL extends HTMLElement {
1056
1267
  disconnectedCallback() {
1057
1268
  this.hidePopover();
1058
1269
  // closeBtn.removeEventListener('click', (e));
1059
- document.body.removeEventListener('click', this._state.fGlobalBodyClick);
1270
+ document.body.removeEventListener('click', this.fGlobalBodyClick);
1060
1271
  }
1061
1272
 
1062
1273
  // Utility function function to clear all elements from shadow root.