@iamproperty/components 4.0.0 → 4.0.1

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 (90) hide show
  1. package/assets/css/components/actionbar-global.css +1 -1
  2. package/assets/css/components/actionbar-global.css.map +1 -1
  3. package/assets/css/components/actionbar.css +1 -1
  4. package/assets/css/components/actionbar.css.map +1 -1
  5. package/assets/css/components/admin-panel.css +1 -1
  6. package/assets/css/components/admin-panel.css.map +1 -1
  7. package/assets/css/components/card-global.css +1 -1
  8. package/assets/css/components/card-global.css.map +1 -1
  9. package/assets/css/components/card.css +1 -1
  10. package/assets/css/components/card.css.map +1 -1
  11. package/assets/css/components/charts.css.map +1 -1
  12. package/assets/css/components/collapsible-side.css.map +1 -1
  13. package/assets/css/components/dialog.css +1 -1
  14. package/assets/css/components/dialog.css.map +1 -1
  15. package/assets/css/components/fileupload.css.map +1 -1
  16. package/assets/css/components/forms.css +1 -1
  17. package/assets/css/components/forms.css.map +1 -1
  18. package/assets/css/components/header.css.map +1 -1
  19. package/assets/css/components/lists.css.map +1 -1
  20. package/assets/css/components/nav-global.css +1 -1
  21. package/assets/css/components/nav-global.css.map +1 -1
  22. package/assets/css/components/nav.css.map +1 -1
  23. package/assets/css/components/nav.old.css.map +1 -1
  24. package/assets/css/components/notification.css.map +1 -1
  25. package/assets/css/components/pagination.css.map +1 -1
  26. package/assets/css/components/property-searchbar.css.map +1 -1
  27. package/assets/css/components/table.css +1 -1
  28. package/assets/css/components/table.css.map +1 -1
  29. package/assets/css/core.min.css +1 -1
  30. package/assets/css/core.min.css.map +1 -1
  31. package/assets/css/style.min.css +1 -1
  32. package/assets/css/style.min.css.map +1 -1
  33. package/assets/js/components/accordion/accordion.component.min.js +1 -1
  34. package/assets/js/components/actionbar/actionbar.component.js +45 -0
  35. package/assets/js/components/actionbar/actionbar.component.min.js +4 -4
  36. package/assets/js/components/actionbar/actionbar.component.min.js.map +1 -1
  37. package/assets/js/components/applied-filters/applied-filters.component.min.js +3 -3
  38. package/assets/js/components/applied-filters/applied-filters.component.min.js.map +1 -1
  39. package/assets/js/components/card/card.component.js +9 -1
  40. package/assets/js/components/card/card.component.min.js +7 -5
  41. package/assets/js/components/card/card.component.min.js.map +1 -1
  42. package/assets/js/components/collapsible-side/collapsible-side.component.min.js +1 -1
  43. package/assets/js/components/filterlist/filterlist.component.min.js +1 -1
  44. package/assets/js/components/header/header.component.min.js +1 -1
  45. package/assets/js/components/nav/nav.component.min.js +1 -1
  46. package/assets/js/components/notification/notification.component.min.js +1 -1
  47. package/assets/js/components/pagination/pagination.component.min.js +1 -1
  48. package/assets/js/components/table/table.component.js +3 -0
  49. package/assets/js/components/table/table.component.min.js +10 -10
  50. package/assets/js/components/table/table.component.min.js.map +1 -1
  51. package/assets/js/components/tabs/tabs.component.min.js +1 -1
  52. package/assets/js/dynamic.min.js +4 -4
  53. package/assets/js/dynamic.min.js.map +1 -1
  54. package/assets/js/modules/applied-filters.js +6 -7
  55. package/assets/js/modules/dialogs.js +32 -4
  56. package/assets/js/modules/table.js +68 -13
  57. package/assets/js/scripts.bundle.js +18 -16
  58. package/assets/js/scripts.bundle.js.map +1 -1
  59. package/assets/js/scripts.bundle.min.js +2 -2
  60. package/assets/js/scripts.bundle.min.js.map +1 -1
  61. package/assets/sass/_corefiles.scss +0 -1
  62. package/assets/sass/_func.scss +1 -0
  63. package/assets/sass/_functions/mixins.scss +22 -0
  64. package/assets/sass/components/actionbar-global.scss +69 -7
  65. package/assets/sass/components/actionbar.scss +20 -8
  66. package/assets/sass/components/admin-panel.scss +47 -2
  67. package/assets/sass/components/card-global.scss +53 -1
  68. package/assets/sass/components/card.scss +14 -12
  69. package/assets/sass/components/charts.scss +1 -1
  70. package/assets/sass/components/collapsible-side.scss +1 -1
  71. package/assets/sass/components/dialog.scss +62 -61
  72. package/assets/sass/components/fileupload.scss +1 -1
  73. package/assets/sass/components/forms.scss +112 -102
  74. package/assets/sass/components/nav-global.scss +15 -9
  75. package/assets/sass/components/nav.scss +9 -10
  76. package/assets/sass/components/notification.scss +1 -1
  77. package/assets/sass/components/table.scss +85 -4
  78. package/assets/sass/core.scss +1 -0
  79. package/assets/sass/error.scss +2 -1
  80. package/assets/sass/foundations/root.scss +3 -3
  81. package/assets/sass/main.scss +4 -3
  82. package/assets/ts/components/actionbar/actionbar.component.ts +67 -2
  83. package/assets/ts/components/card/card.component.ts +12 -2
  84. package/assets/ts/components/table/table.component.ts +4 -0
  85. package/assets/ts/modules/applied-filters.ts +8 -10
  86. package/assets/ts/modules/dialogs.ts +42 -5
  87. package/assets/ts/modules/table.ts +82 -13
  88. package/dist/components.es.js +914 -838
  89. package/dist/components.umd.js +47 -45
  90. package/package.json +1 -1
@@ -132,6 +132,43 @@ class iamActionbar extends HTMLElement {
132
132
  });
133
133
  }
134
134
  }
135
+
136
+ // Wtach div for the select inputs
137
+ if(this.hasAttribute('data-select-watch')){
138
+
139
+ const element = document.getElementById(this.getAttribute('data-select-watch'));
140
+ element.setAttribute('data-select-container','true');
141
+ Array.from(element.querySelectorAll('input[type="checkbox"]')).forEach((input,index) => {
142
+ input.parentElement.setAttribute('slot','checkbox');
143
+ });
144
+ element.addEventListener('change',(event) => {
145
+
146
+ if (event && event.target instanceof HTMLElement && event.target.closest('[type="checkbox"]')){
147
+
148
+ let count = element.querySelectorAll('input[type="checkbox"]').length;
149
+ let countChecked = element.querySelectorAll('input[type="checkbox"]:checked').length;
150
+ that.setAttribute('data-selected', count == countChecked ? "all" : countChecked);
151
+
152
+ let input = event.target.closest('[type="checkbox"]');
153
+
154
+ if(countChecked){
155
+ Array.from(element.querySelectorAll('input[type="checkbox"]')).forEach((input,index) => {
156
+
157
+ if(input.closest('iam-card'))
158
+ input.closest('iam-card').setAttribute('data-selected','true');
159
+ });
160
+ }
161
+ else {
162
+ Array.from(element.querySelectorAll('input[type="checkbox"]')).forEach((input,index) => {
163
+
164
+ if(input.closest('iam-card'))
165
+ input.closest('iam-card').removeAttribute('data-selected');
166
+ });
167
+ }
168
+
169
+ };
170
+ });
171
+ }
135
172
  // #endregion
136
173
 
137
174
  // #region switchviews
@@ -385,8 +422,36 @@ class iamActionbar extends HTMLElement {
385
422
 
386
423
  if(selectAll)
387
424
  setSelectAllInput(selectAll, newVal);
388
- const event = new CustomEvent("selected", { detail: { selected: newVal } });
389
- this.dispatchEvent(event);
425
+
426
+ const event = new CustomEvent("selected", { detail: { selected: newVal } });
427
+ this.dispatchEvent(event);
428
+
429
+ if(newVal == "all" && this.hasAttribute('data-select-watch')){
430
+
431
+ const element = document.getElementById(this.getAttribute('data-select-watch'));
432
+
433
+ Array.from(element.querySelectorAll('input[type="checkbox"]')).forEach((input,index) => {
434
+
435
+ input.checked = true;
436
+
437
+ if(input.closest('iam-card'))
438
+ input.closest('iam-card').setAttribute('data-selected','true');
439
+ });
440
+ }
441
+
442
+ if(newVal == "0" && this.hasAttribute('data-select-watch')){
443
+
444
+ const element = document.getElementById(this.getAttribute('data-select-watch'));
445
+
446
+ Array.from(element.querySelectorAll('input[type="checkbox"]')).forEach((input,index) => {
447
+
448
+ input.checked = false;
449
+
450
+ if(input.closest('iam-card'))
451
+ input.closest('iam-card').removeAttribute('data-selected','true');
452
+ });
453
+ }
454
+
390
455
  break;
391
456
  }
392
457
  }
@@ -37,6 +37,8 @@ class iamCard extends HTMLElement {
37
37
  ${this.hasAttribute('data-illustration') ? `<div class="card__illustration"><img src="${this.getAttribute('data-illustration')}" alt="" loading="lazy" /></div>` : ''}
38
38
  <slot></slot>
39
39
  </div>
40
+
41
+ <slot name="checkbox"></slot>
40
42
  ${this.hasAttribute('data-cta') ? `<div class="card__footer"><span class="link">${this.getAttribute('data-cta')}</span></div>` : ''}
41
43
  </div>
42
44
  `;
@@ -44,7 +46,7 @@ class iamCard extends HTMLElement {
44
46
  }
45
47
 
46
48
  connectedCallback() {
47
-
49
+
48
50
  this.classList.add('loaded');
49
51
 
50
52
  // Mimic clicking the parent node so the focus and target events can be on the card
@@ -64,6 +66,13 @@ class iamCard extends HTMLElement {
64
66
  card.classList.remove('checked');
65
67
  }
66
68
 
69
+ // Click event down
70
+ this.addEventListener('click', (event) => {
71
+
72
+ let clickEvent = new Event('click');
73
+ card.dispatchEvent(clickEvent);
74
+ });
75
+
67
76
  card.addEventListener('click', (event) => {
68
77
 
69
78
  if(parentNode.matches('label[for]')){
@@ -151,7 +160,8 @@ class iamCard extends HTMLElement {
151
160
  attributeChangedCallback(attrName, oldVal, newVal) {
152
161
  switch (attrName) {
153
162
  case "data-total": {
154
- this.shadowRoot.querySelector('.card__total').innerHTML = newVal;
163
+ if(this.shadowRoot.querySelector('.card__total'))
164
+ this.shadowRoot.querySelector('.card__total').innerHTML = newVal;
155
165
  break;
156
166
  }
157
167
  case "class": {
@@ -65,6 +65,10 @@ class iamTable extends HTMLElement {
65
65
  classList = classList.replace('table--loading','');
66
66
  this.shadowRoot.querySelector('.table__wrapper').className += ` ${classList}`;
67
67
 
68
+ // set actionbar class if needed
69
+ if(this.querySelector('.actionbar__sticky'))
70
+ this.shadowRoot.querySelector('.table__wrapper').classList.add('has-actionbar');
71
+
68
72
  this.table = this.querySelector('table');
69
73
  this.savedTableBody = this.table.querySelector('tbody').cloneNode(true);
70
74
  this.pagination = this.shadowRoot.querySelector('.table__pagination');
@@ -96,17 +96,14 @@ function createAppliedFilters(container,filters) {
96
96
  Array.from(container.querySelectorAll('input[type="checkbox"]:checked')).forEach((input, index) => {
97
97
  addFilterButton(filters, input)
98
98
  });
99
-
100
- container.addEventListener('change', function(event){
101
99
 
102
- if (event && event.target instanceof HTMLElement && event.target.closest('input[data-filter-text]')){
103
-
104
- let input = event.target.closest('input[data-filter-text]');
105
-
106
- addFilterButton (filters, input);
107
- };
100
+ Array.from(container.querySelectorAll('input[data-filter-text]')).forEach((input, index) => {
108
101
 
109
- }, false);
102
+ input.addEventListener('change', function(event){
103
+
104
+ addFilterButton(filters, input)
105
+ });
106
+ });
110
107
 
111
108
  filters.addEventListener('click', function(event){
112
109
 
@@ -136,7 +133,8 @@ function createAppliedFilters(container,filters) {
136
133
  input.checked = false;
137
134
 
138
135
  var event = new Event('force');
139
- input.closest('form').dispatchEvent(event);
136
+ if(!container.hasAttribute('data-nosubmit'))
137
+ input.closest('form').dispatchEvent(event);
140
138
  }
141
139
  }
142
140
  }
@@ -36,6 +36,23 @@ const extendDialogs = (body) => {
36
36
  dialog.showModal();
37
37
  dialog.focus();
38
38
 
39
+ let firstWidth = dialog.offsetWidth;
40
+ dialog.setAttribute('style',`max-width: ${firstWidth}px;`);
41
+
42
+ // When the modal is opened we want to make sure any duplicate checkboxes are matching the originals
43
+ Array.from(dialog.querySelectorAll('[data-duplicate]')).forEach((element,index) => {
44
+
45
+ const id = element.getAttribute('data-duplicate');
46
+ const originalInput = document.getElementById(id);
47
+
48
+ if(element.checked != originalInput.checked){
49
+
50
+ element.checked = originalInput.checked;
51
+ let changeEvent = new Event('change');
52
+ element.dispatchEvent(changeEvent);
53
+ }
54
+ });
55
+
39
56
  window.dataLayer = window.dataLayer || [];
40
57
  window.dataLayer.push({
41
58
  "event": "openModal",
@@ -244,6 +261,7 @@ export const createMultiFormDialog = (dialog) => {
244
261
 
245
262
  let buttons = "";
246
263
  let fieldsets = Array.from(dialog.querySelectorAll('fieldset[data-title]'));
264
+ let form = dialog.querySelector('form');
247
265
 
248
266
  fieldsets.forEach((fieldset,index) => {
249
267
  buttons += `<button data-title="${fieldset.getAttribute('data-title')}" type="button" class="${index == 0 ? "active":""}" tabindex="-1">${fieldset.getAttribute('data-title')}</button>`;
@@ -258,8 +276,18 @@ export const createMultiFormDialog = (dialog) => {
258
276
  if(index != fieldsets.length - 1)
259
277
  btnWrapper.innerHTML += `<button data-title="${fieldsets[index+1].getAttribute('data-title')}" class="btn btn-primary mb-0" data-next type="button">Next</button>`;
260
278
 
261
- if(index == fieldsets.length - 1)
262
- btnWrapper.innerHTML += `<button data-title="${fieldsets[index].getAttribute('data-title')}" class="btn btn-primary mb-0" data-next type="submit">Submit</button>`;
279
+ // Last fieldset
280
+ if(index == fieldsets.length - 1){
281
+ if(form && form.querySelector(':scope > button[type="submit"]')){
282
+
283
+ let existingButton = form.querySelector(':scope > button[type="submit"]');
284
+ existingButton.classList.add('mb-0')
285
+
286
+ btnWrapper.insertAdjacentElement('beforeend',existingButton);
287
+ }
288
+ else
289
+ btnWrapper.innerHTML += `<button data-title="${fieldsets[index].getAttribute('data-title')}" class="btn btn-primary mb-0" data-next type="submit">Submit</button>`;
290
+ }
263
291
  });
264
292
 
265
293
  dialog.insertAdjacentHTML('afterbegin',`<div class="steps bg-primary">${buttons}</div>`);
@@ -359,11 +387,12 @@ export const createMultiFormDialog = (dialog) => {
359
387
 
360
388
  const button = event.target.closest('button');
361
389
 
362
- if(event.keyCode == 13){
390
+ if(event.keyCode == 13 && button.getAttribute('type') != "submit"){
363
391
 
364
392
  event.preventDefault();
365
393
  validateFieldset(button);
366
394
  }
395
+
367
396
  }
368
397
 
369
398
  if (event && event.target instanceof HTMLElement && event.target.closest('input')){
@@ -371,13 +400,21 @@ export const createMultiFormDialog = (dialog) => {
371
400
 
372
401
  input.classList.remove('is-invalid');
373
402
 
374
-
403
+ if(event.keyCode == 13){
404
+
405
+ event.preventDefault();
406
+ }
375
407
  }
376
408
  });
377
409
 
378
410
 
379
411
  dialog.addEventListener('click', (event) => {
380
- if (event && event.target instanceof HTMLElement && event.target.closest('button[data-title]')){
412
+ if (event && event.target instanceof HTMLElement && event.target.closest('button[type="submit"]')){
413
+
414
+ const form = event.target.closest('form');
415
+ form.classList.add('was-validated');
416
+ }
417
+ else if (event && event.target instanceof HTMLElement && event.target.closest('button[data-title]')){
381
418
 
382
419
  const button = event.target.closest('button[data-title]');
383
420
  validateFieldset(button);
@@ -140,7 +140,35 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
140
140
  var timer;
141
141
 
142
142
  // Check what conditions are set on the table to see what the form actions are
143
- let formSubmit = function(paginate = false){
143
+ let formSubmit = function(event, paginate = false){
144
+
145
+ if(form.classList.contains('processing'))
146
+ return false;
147
+
148
+
149
+ // Before submitting check if any duplicate checkboxes within the filters dialog needs to upset the original input
150
+ if(event.type == "submit"){
151
+ form.classList.add('processing');
152
+ Array.from(form.querySelectorAll('[data-duplicate]')).forEach((element,index) => {
153
+
154
+ const id = element.getAttribute('data-duplicate');
155
+ const input = document.getElementById(id);
156
+ const card = document.querySelector(`[for="${id}"] iam-card`);
157
+
158
+
159
+ if(input.checked != element.checked){
160
+
161
+ if(card){
162
+ let clickEvent = new Event('click');
163
+ card.dispatchEvent(clickEvent);
164
+ }
165
+ else {
166
+ input.checked = element.checked;
167
+ }
168
+ }
169
+ });
170
+ form.classList.remove('processing');
171
+ }
144
172
 
145
173
  if(form.hasAttribute('data-ajax')){
146
174
 
@@ -179,7 +207,7 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
179
207
  if (event && event.target instanceof HTMLElement && event.target.closest('[data-search]')){
180
208
 
181
209
  timer = setTimeout(function(){
182
- formSubmit();
210
+ formSubmit(event);
183
211
  }, 500);
184
212
  };
185
213
  });
@@ -193,12 +221,12 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
193
221
  if(!form.hasAttribute('data-submit'))
194
222
  sortTable(table, form, savedTableBody);
195
223
 
196
- formSubmit();
224
+ formSubmit(event);
197
225
  }
198
226
 
199
227
  if (event && event.target instanceof HTMLElement && event.target.closest('[data-search]')){
200
228
 
201
- formSubmit();
229
+ formSubmit(event);
202
230
  }
203
231
 
204
232
  if (event && event.target instanceof HTMLElement && event.target.closest('[data-filter][data-no-ajax]')){ // Allow for input fields to filter the current results without a new ajax call
@@ -209,21 +237,21 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
209
237
  }
210
238
  else if (event && event.target instanceof HTMLElement && event.target.closest('[data-filter]') && event.target.closest('form .dialog__wrapper > dialog')){
211
239
 
212
- formSubmit();
240
+ formSubmit(event);
213
241
  }
214
242
  else if (event && event.target instanceof HTMLElement && event.target.closest('[data-filter]') && !event.target.closest('form dialog')){
215
243
 
216
- formSubmit();
244
+ formSubmit(event);
217
245
  }
218
246
 
219
247
  if (event && event.target instanceof HTMLElement && event.target.closest('[data-show]')){
220
248
 
221
- formSubmit();
249
+ formSubmit(event);
222
250
  }
223
251
 
224
252
  if (event && event.target instanceof HTMLElement && event.target.closest('[data-mimic]')){
225
253
 
226
- formSubmit();
254
+ formSubmit(event);
227
255
  }
228
256
  });
229
257
 
@@ -249,12 +277,53 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
249
277
 
250
278
  if (event && event.target instanceof HTMLElement && event.target.closest('[data-clear]')){
251
279
 
252
- form.reset();
280
+ form.classList.add('processing');
281
+ // Make sure any applied filters have been removed
282
+ Array.from(form.querySelectorAll('.applied-filters')).forEach((filters,index) => {
283
+ filters.innerHTML = "";
284
+ });
285
+
286
+ // Make sure cards are unlicked
287
+ let frm_elements = form.elements;
288
+
289
+ for (let i = 0; i < frm_elements.length; i++)
290
+ {
291
+ let field_type = frm_elements[i].type.toLowerCase() ? frm_elements[i].type.toLowerCase() : "text";
292
+ switch (field_type)
293
+ {
294
+ case "text":
295
+ case "password":
296
+ case "textarea":
297
+ frm_elements[i].value = "";
298
+ break;
299
+ case "radio":
300
+ case "checkbox":
301
+ if (frm_elements[i].checked)
302
+ {
303
+ frm_elements[i].checked = false;
304
+ }
305
+ break;
306
+ case "select-one":
307
+ case "select-multi":
308
+ frm_elements[i].selectedIndex = -1;
309
+ break;
310
+ case "hidden":
311
+ default:
312
+ break;
313
+ }
314
+ }
315
+
316
+ Array.from(form.querySelectorAll('label iam-card')).forEach((card,index) => {
317
+ let clickEvent = new Event('click');
318
+ card.dispatchEvent(clickEvent);
319
+ });
320
+
321
+ form.classList.remove('processing');
253
322
 
254
323
  if(!form.hasAttribute('data-submit'))
255
324
  sortTable(table, form, savedTableBody);
256
325
 
257
- formSubmit();
326
+ formSubmit(event);
258
327
  }
259
328
  });
260
329
 
@@ -265,17 +334,17 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
265
334
  if(!form.hasAttribute('data-submit'))
266
335
  event.preventDefault();
267
336
 
268
- formSubmit();
337
+ formSubmit(event);
269
338
  });
270
339
 
271
340
  form.addEventListener('force', (event) => {
272
341
 
273
- formSubmit();
342
+ formSubmit(event);
274
343
  });
275
344
 
276
345
  form.addEventListener('paginate', (event) => {
277
346
 
278
- formSubmit(true);
347
+ formSubmit(event,true);
279
348
  });
280
349
 
281
350