@iamproperty/components 7.2.0 → 7.2.1--beta2

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 (126) hide show
  1. package/assets/css/components/actionbar.component.css +1 -1
  2. package/assets/css/components/actionbar.component.css.map +1 -1
  3. package/assets/css/components/actionbar.global.css +1 -1
  4. package/assets/css/components/actionbar.global.css.map +1 -1
  5. package/assets/css/components/barchart.component.css +1 -1
  6. package/assets/css/components/barchart.component.css.map +1 -1
  7. package/assets/css/components/card.component.css +1 -1
  8. package/assets/css/components/card.component.css.map +1 -1
  9. package/assets/css/components/carousel.component.css +1 -1
  10. package/assets/css/components/carousel.component.css.map +1 -1
  11. package/assets/css/components/doughnutchart.component.css +1 -1
  12. package/assets/css/components/doughnutchart.component.css.map +1 -1
  13. package/assets/css/components/pagination.css +1 -1
  14. package/assets/css/components/pagination.css.map +1 -1
  15. package/assets/css/components/table-basic.component.css +1 -0
  16. package/assets/css/components/table-basic.component.css.map +1 -0
  17. package/assets/css/components/table-basic.global.css +1 -0
  18. package/assets/css/components/table-basic.global.css.map +1 -0
  19. package/assets/css/components/table.component.css +1 -1
  20. package/assets/css/components/table.component.css.map +1 -1
  21. package/assets/css/components/table.global.css +1 -1
  22. package/assets/css/components/table.global.css.map +1 -1
  23. package/assets/css/components/tabs.config.css +1 -0
  24. package/assets/css/components/tabs.config.css.map +1 -0
  25. package/assets/css/components/tabs.css +1 -1
  26. package/assets/css/components/tabs.css.map +1 -1
  27. package/assets/css/core.min.css +1 -1
  28. package/assets/css/core.min.css.map +1 -1
  29. package/assets/css/mobile-core.min.css +1 -1
  30. package/assets/css/mobile-core.min.css.map +1 -1
  31. package/assets/css/mobile.min.css +1 -1
  32. package/assets/css/mobile.min.css.map +1 -1
  33. package/assets/css/style.min.css +1 -1
  34. package/assets/css/style.min.css.map +1 -1
  35. package/assets/js/components/accordion/accordion.component.min.js +1 -1
  36. package/assets/js/components/actionbar/actionbar.component.min.js +4 -4
  37. package/assets/js/components/address-lookup/address-lookup.component.min.js +1 -1
  38. package/assets/js/components/applied-filters/applied-filters.component.min.js +1 -1
  39. package/assets/js/components/barchart/barchart.component.min.js +2 -2
  40. package/assets/js/components/barchart/barchart.component.min.js.map +1 -1
  41. package/assets/js/components/bento-grid/bento-grid.component.min.js +1 -1
  42. package/assets/js/components/card/card.component.min.js +2 -2
  43. package/assets/js/components/carousel/carousel.component.min.js +2 -2
  44. package/assets/js/components/collapsible-side/collapsible-side.component.min.js +1 -1
  45. package/assets/js/components/doughnutchart/doughnutchart.component.min.js +2 -2
  46. package/assets/js/components/doughnutchart/doughnutchart.component.min.js.map +1 -1
  47. package/assets/js/components/fileupload/fileupload.component.min.js +1 -1
  48. package/assets/js/components/filter-card/filter-card.component.min.js +1 -1
  49. package/assets/js/components/filterlist/filterlist.component.min.js +1 -1
  50. package/assets/js/components/header/header.component.min.js +1 -1
  51. package/assets/js/components/inline-edit/inline-edit.component.min.js +1 -1
  52. package/assets/js/components/marketing/marketing.component.min.js +1 -1
  53. package/assets/js/components/menu/menu.component.min.js +1 -1
  54. package/assets/js/components/multi-step/multi-step.component.min.js +1 -1
  55. package/assets/js/components/multiselect/multiselect.component.min.js +1 -1
  56. package/assets/js/components/nav/nav.component.min.js +1 -1
  57. package/assets/js/components/notification/notification.component.min.js +1 -1
  58. package/assets/js/components/pagination/pagination.component.js +11 -4
  59. package/assets/js/components/pagination/pagination.component.min.js +5 -5
  60. package/assets/js/components/pagination/pagination.component.min.js.map +1 -1
  61. package/assets/js/components/record-card/record-card.component.min.js +1 -1
  62. package/assets/js/components/search/search.component.min.js +1 -1
  63. package/assets/js/components/search/search.component.min.js.map +1 -1
  64. package/assets/js/components/slider/slider.component.min.js +1 -1
  65. package/assets/js/components/table/table.component.js +36 -198
  66. package/assets/js/components/table/table.component.min.js +13 -23
  67. package/assets/js/components/table/table.component.min.js.map +1 -1
  68. package/assets/js/components/table-ajax/table-ajax.component.js +46 -0
  69. package/assets/js/components/table-ajax/table-ajax.component.min.js +22 -0
  70. package/assets/js/components/table-ajax/table-ajax.component.min.js.map +1 -0
  71. package/assets/js/components/table-basic/table-basic.component.js +46 -0
  72. package/assets/js/components/table-basic/table-basic.component.min.js +22 -0
  73. package/assets/js/components/table-basic/table-basic.component.min.js.map +1 -0
  74. package/assets/js/components/table-no-submit/table-no-submit.component.js +77 -0
  75. package/assets/js/components/table-no-submit/table-no-submit.component.min.js +22 -0
  76. package/assets/js/components/table-no-submit/table-no-submit.component.min.js.map +1 -0
  77. package/assets/js/components/table-submit/table-submit.component.js +55 -0
  78. package/assets/js/components/table-submit/table-submit.component.min.js +22 -0
  79. package/assets/js/components/table-submit/table-submit.component.min.js.map +1 -0
  80. package/assets/js/components/tabs/tabs.component.js +2 -0
  81. package/assets/js/components/tabs/tabs.component.min.js +6 -4
  82. package/assets/js/components/tabs/tabs.component.min.js.map +1 -1
  83. package/assets/js/components/video-card/video-card.component.min.js +1 -1
  84. package/assets/js/modules/helpers.js +4 -0
  85. package/assets/js/modules/table.js +544 -294
  86. package/assets/js/modules/tabs.js +43 -13
  87. package/assets/js/scripts.bundle.js +3 -3
  88. package/assets/js/scripts.bundle.js.map +1 -1
  89. package/assets/js/scripts.bundle.min.js +2 -2
  90. package/assets/js/scripts.bundle.min.js.map +1 -1
  91. package/assets/js/scripts.js +31 -24
  92. package/assets/js/tests/table.spec.js +0 -31
  93. package/assets/sass/_components.scss +3 -0
  94. package/assets/sass/components/actionbar.component.scss +1 -0
  95. package/assets/sass/components/actionbar.global.scss +0 -70
  96. package/assets/sass/components/pagination.scss +2 -1
  97. package/assets/sass/components/table-basic.component.scss +132 -0
  98. package/assets/sass/components/table-basic.global.scss +365 -0
  99. package/assets/sass/components/table.component.scss +2 -133
  100. package/assets/sass/components/table.global.scss +175 -434
  101. package/assets/sass/components/tabs.config.scss +27 -0
  102. package/assets/sass/components/tabs.scss +33 -1
  103. package/assets/sass/elements/buttons--global.scss +2 -1
  104. package/assets/sass/elements/table.element.scss +9 -7
  105. package/assets/sass/foundations/root.scss +1 -1
  106. package/assets/ts/components/pagination/pagination.component.ts +17 -4
  107. package/assets/ts/components/table/table.component.ts +49 -243
  108. package/assets/ts/components/table-ajax/table-ajax.component.ts +64 -0
  109. package/assets/ts/components/table-basic/README.md +40 -0
  110. package/assets/ts/components/table-basic/table-basic.component.ts +56 -0
  111. package/assets/ts/components/table-no-submit/table-no-submit.component.ts +134 -0
  112. package/assets/ts/components/table-submit/table-submit.component.ts +64 -0
  113. package/assets/ts/components/tabs/tabs.component.ts +2 -0
  114. package/assets/ts/modules/helpers.ts +6 -0
  115. package/assets/ts/modules/table.ts +656 -328
  116. package/assets/ts/modules/tabs.ts +54 -12
  117. package/assets/ts/scripts.ts +5 -3
  118. package/assets/ts/tests/table.spec.ts +0 -38
  119. package/dist/components.es.js +138 -136
  120. package/dist/components.umd.js +108 -116
  121. package/package.json +1 -1
  122. package/src/components/Table/TableAjax.vue +34 -0
  123. package/src/components/Table/TableBasic.vue +34 -0
  124. package/src/components/Table/TableNoSubmit.vue +34 -0
  125. package/src/components/Table/TableSubmit.vue +34 -0
  126. package/src/components/Table/Table.spec.js +0 -47
@@ -7,8 +7,185 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { zeroPad, isNumeric, ucfirst, resolvePath } from './helpers.js';
11
- // Basic functionality needed
10
+ import { zeroPad, isNumeric, ucfirst, resolvePath, uniqueID } from './helpers.js';
11
+ // #region Helpers
12
+ export const formatCell = (format, cellOutput) => {
13
+ switch (format) {
14
+ case 'datetime':
15
+ return (new Date(cellOutput).toLocaleDateString('en-gb', {
16
+ weekday: 'short',
17
+ year: '2-digit',
18
+ month: 'long',
19
+ day: 'numeric',
20
+ }) +
21
+ ' ' +
22
+ new Date(cellOutput).toLocaleTimeString('en-gb', { hour: '2-digit', minute: '2-digit' }));
23
+ case 'date':
24
+ return new Date(cellOutput).toLocaleDateString('en-gb', {
25
+ day: 'numeric',
26
+ month: 'long',
27
+ year: '2-digit',
28
+ });
29
+ case 'capitalise':
30
+ return (cellOutput = ucfirst(cellOutput));
31
+ }
32
+ };
33
+ const filterFilters = function (form) {
34
+ const filters = new Object();
35
+ // Filter
36
+ const filterInputs = Array.from(form.querySelectorAll('[data-filter]'));
37
+ filterInputs.forEach((filterInput) => {
38
+ // Ignore uncked radio inputs
39
+ if (filterInput.type == 'radio' && !filterInput.checked) {
40
+ return;
41
+ }
42
+ if (filterInput.type == 'checkbox' && !filterInput.checked) {
43
+ return;
44
+ }
45
+ if (filterInput && filterInput.value) {
46
+ const dataFilter = filterInput.getAttribute('data-filter');
47
+ let filterValue = filterInput.value;
48
+ if (filterInput.hasAttribute('data-date-from'))
49
+ filterValue += '-date-from';
50
+ if (filterInput.hasAttribute('data-date-to'))
51
+ filterValue += '-date-to';
52
+ if (!filters[dataFilter])
53
+ filters[dataFilter] = [];
54
+ filters[dataFilter].push(filterValue);
55
+ }
56
+ });
57
+ return filters;
58
+ };
59
+ export const moveAttributesToComponents = (component) => {
60
+ let form = document.createElement('form');
61
+ const table = component.querySelector('table');
62
+ if (component.hasAttribute('data-filterby')) {
63
+ form = document.querySelector(`#${component.getAttribute('data-filterby')}`);
64
+ }
65
+ else if (component.closest('form')) {
66
+ form = component.closest('form');
67
+ }
68
+ else {
69
+ table.parentNode.insertBefore(form, table.nextSibling);
70
+ }
71
+ if (form.hasAttribute('data-ajax'))
72
+ component.setAttribute('data-ajax', form.getAttribute('data-ajax'));
73
+ if (form.hasAttribute('data-schema'))
74
+ component.setAttribute('data-schema', form.getAttribute('data-schema'));
75
+ };
76
+ export const paginateTable = (component, table, form, pagination, callback) => {
77
+ if (!form.querySelector('[name=show]'))
78
+ form.insertAdjacentHTML('beforeend', `<input name="show" type="hidden" value="${component.getAttribute('data-show')}" />`);
79
+ if (!form.querySelector('[name=page]'))
80
+ form.insertAdjacentHTML('beforeend', `<input name="page" type="hidden" value="${component.getAttribute('data-page')}" />`);
81
+ pagination.addEventListener('update-show', (event) => {
82
+ if (form.querySelector('[name=show]').value != event.detail.show) {
83
+ form.querySelector('[name=show]').value = event.detail.show;
84
+ const updateEvent = new CustomEvent('update-show', { detail: { show: event.detail.show } });
85
+ component.dispatchEvent(updateEvent);
86
+ updateAttributes(component, pagination);
87
+ callback();
88
+ }
89
+ });
90
+ pagination.addEventListener('update-page', (event) => {
91
+ if (form.querySelector('[name=page]').value != event.detail.page) {
92
+ form.querySelector('[name=page]').value = event.detail.page;
93
+ const updateEvent = new CustomEvent('update-page', { detail: { page: event.detail.page } });
94
+ component.dispatchEvent(updateEvent);
95
+ updateAttributes(component, pagination);
96
+ callback();
97
+ // scroll back to the top of the table
98
+ if (!component.hasAttribute('data-no-scroll')) {
99
+ const yOffset = -250;
100
+ const y = table.getBoundingClientRect().top + window.pageYOffset + yOffset;
101
+ window.scrollTo({ top: y, behavior: 'smooth' });
102
+ }
103
+ }
104
+ });
105
+ };
106
+ export const findForm = (component, table) => {
107
+ let form = document.createElement('form');
108
+ if (component.hasAttribute('data-filterby')) {
109
+ form = document.querySelector(`#${component.getAttribute('data-filterby')}`);
110
+ }
111
+ else if (component.closest('form')) {
112
+ form = component.closest('form');
113
+ }
114
+ else {
115
+ table.parentNode.insertBefore(form, table.nextSibling);
116
+ }
117
+ return form;
118
+ };
119
+ // #endregion
120
+ export const setupBasicTable = (component, table, form, pagination) => {
121
+ const tableWrapper = component.shadowRoot.querySelector('.table__wrapper');
122
+ if (!component.hasAttribute('data-total'))
123
+ component.setAttribute('data-total', component.querySelectorAll('tbody tr').length);
124
+ if (!component.hasAttribute('data-page'))
125
+ component.setAttribute('data-page', 1);
126
+ if (!component.hasAttribute('data-show'))
127
+ component.setAttribute('data-show', 5);
128
+ if (!component.hasAttribute('data-increment'))
129
+ component.setAttribute('data-increment', component.getAttribute('data-show'));
130
+ transferAttributes(component, pagination);
131
+ addDataAttributes(table);
132
+ createMobileButton(component, table);
133
+ // Max height
134
+ if (component.classList.contains('mh-sm'))
135
+ tableWrapper.classList.add('mh-sm');
136
+ if (component.classList.contains('mh-md'))
137
+ tableWrapper.classList.add('mh-md');
138
+ if (component.classList.contains('mh-lg'))
139
+ tableWrapper.classList.add('mh-lg');
140
+ if (component.classList.contains('table--cta')) {
141
+ getLargestLastColWidth(component, table);
142
+ getRowHeight(component, table);
143
+ }
144
+ };
145
+ // #region Basic table fnctions
146
+ export const transferAttributes = (component, pagination) => {
147
+ if (component.hasAttribute('data-total'))
148
+ pagination.setAttribute('data-total', component.getAttribute('data-total'));
149
+ if (component.hasAttribute('data-page'))
150
+ pagination.setAttribute('data-page', component.getAttribute('data-page'));
151
+ if (component.hasAttribute('data-show'))
152
+ pagination.setAttribute('data-show', component.getAttribute('data-show'));
153
+ if (component.hasAttribute('data-increment'))
154
+ pagination.setAttribute('data-increment', component.getAttribute('data-show'));
155
+ if (component.hasAttribute('data-page-jump'))
156
+ pagination.setAttribute('data-page-jump', 'true');
157
+ if (component.hasAttribute('data-per-page'))
158
+ pagination.setAttribute('data-per-page', 'true');
159
+ if (component.hasAttribute('data-item-count'))
160
+ pagination.setAttribute('data-item-count', 'true');
161
+ if (component.hasAttribute('data-loading'))
162
+ pagination.setAttribute('data-loading', 'true');
163
+ if (component.classList.contains('table--fullwidth'))
164
+ pagination.setAttribute('data-minimal', 'true');
165
+ };
166
+ export const updateAttributes = (component, pagination) => {
167
+ component.setAttribute('data-total', pagination.getAttribute('data-total'));
168
+ component.setAttribute('data-page', pagination.getAttribute('data-page'));
169
+ component.setAttribute('data-show', pagination.getAttribute('data-show'));
170
+ component.setAttribute('data-increment', pagination.getAttribute('data-show'));
171
+ };
172
+ export const paginateRows = (component) => {
173
+ const total = component.getAttribute('data-total');
174
+ const page = component.getAttribute('data-page');
175
+ const show = component.getAttribute('data-show');
176
+ const increment = component.getAttribute('data-increment');
177
+ const table = component.querySelector('table');
178
+ const end = page * show;
179
+ const start = end - show;
180
+ Array.from(table.querySelectorAll('tbody tr')).forEach((row, index) => {
181
+ if (index >= start && index < end) {
182
+ row.classList.add('show');
183
+ }
184
+ else {
185
+ row.classList.remove('show');
186
+ }
187
+ });
188
+ };
12
189
  export const addDataAttributes = (table) => {
13
190
  const colHeadings = Array.from(table.querySelectorAll('thead th'));
14
191
  const colRows = Array.from(table.querySelectorAll('tbody tr'));
@@ -35,7 +212,8 @@ export const addDataAttributes = (table) => {
35
212
  'on track',
36
213
  'not started',
37
214
  'warning',
38
- 'error',
215
+ 'successful',
216
+ 'failed',
39
217
  ];
40
218
  cells.forEach((cell, cellIndex) => {
41
219
  const heading = colHeadings[cellIndex];
@@ -57,37 +235,21 @@ export const addDataAttributes = (table) => {
57
235
  });
58
236
  });
59
237
  };
60
- export const getLargestLastColWidth = (table) => {
61
- let largestWidth = 0;
62
- Array.from(table.querySelectorAll('tbody tr')).forEach((row) => {
63
- const htmlStyles = window.getComputedStyle(document.querySelector('html'));
64
- const lastColChild = row.querySelector(':scope > *:last-child > *:first-child');
65
- if (lastColChild) {
66
- lastColChild.classList.add('text-nowrap');
67
- let responsiveWidth = lastColChild.offsetWidth / parseFloat(htmlStyles.fontSize);
68
- responsiveWidth += 1.7;
69
- largestWidth = largestWidth > responsiveWidth ? largestWidth : responsiveWidth;
70
- }
71
- });
72
- return largestWidth;
73
- };
74
- export const createMobileButton = (table, wrapper) => {
75
- if (wrapper.classList.contains('table--fullwidth') && !wrapper.hasAttribute('data-expandable'))
238
+ export const createMobileButton = (component, table) => {
239
+ if (component.classList.contains('table--fullwidth') && !component.hasAttribute('data-expandable'))
76
240
  return false;
77
- if (table.querySelectorAll('thead tr th').length < 4 && !wrapper.hasAttribute('data-expandable'))
241
+ if (table.querySelectorAll('thead tr th').length < 4 && !component.hasAttribute('data-expandable'))
78
242
  return false;
79
243
  //If the expand column already exists we don't need to add a new one.
80
244
  Array.from(table.querySelectorAll('thead tr')).forEach((row) => {
81
245
  if (!table.querySelectorAll('thead tr th.expand-button-heading').length) {
82
- row.insertAdjacentHTML('afterbegin', `<th class="th--fixed expand-button-heading"></th>`);
246
+ row.insertAdjacentHTML('afterbegin', `<th class="${component.hasAttribute('data-expandable') ? 'th--fixed ' : ''}expand-button-heading"></th>`);
83
247
  }
84
248
  });
85
- Array.from(table.querySelectorAll('tbody tr')).forEach((row) => {
249
+ Array.from(table.querySelectorAll('tbody tr')).forEach((row, index) => {
86
250
  const preExpanded = row.getAttribute('data-view') === 'full' ? 'aria-expanded' : '';
87
- row.insertAdjacentHTML('afterbegin', `<td class="td--fixed td--expand"><button class="btn btn-compact btn-secondary" data-expand-button ${preExpanded}>Expand</button></td>`);
251
+ row.insertAdjacentHTML('afterbegin', `<td class="${component.hasAttribute('data-expandable') ? 'td--fixed ' : ''}td--expand"><button class="btn btn-compact btn-secondary btn-sm" data-expand-button ${preExpanded} data-index="${index}">Expand</button></td>`);
88
252
  });
89
- };
90
- export const addTableEventListeners = (table, wrapper) => {
91
253
  table.addEventListener('click', (event) => {
92
254
  if (event && event.target instanceof HTMLElement && event.target.closest('[data-expand-button]')) {
93
255
  const button = event.target.closest('[data-expand-button]');
@@ -98,8 +260,164 @@ export const addTableEventListeners = (table, wrapper) => {
98
260
  else
99
261
  tableRow.setAttribute('data-view', 'full');
100
262
  button.blur();
263
+ component.dispatchEvent(new CustomEvent('row-expanded', { detail: { row: button.getAttribute('data-index') } }));
101
264
  }
102
- else if (event && event.target instanceof HTMLElement && event.target.closest('[data-sort]')) {
265
+ });
266
+ };
267
+ export const getLargestLastColWidth = (component, table) => {
268
+ let largestWidth = 0;
269
+ Array.from(table.querySelectorAll('tbody tr')).forEach((row) => {
270
+ const htmlStyles = window.getComputedStyle(document.querySelector('html'));
271
+ const lastColChild = row.querySelector(':scope > *:last-child > *:first-child');
272
+ if (lastColChild) {
273
+ lastColChild.classList.add('text-nowrap');
274
+ let responsiveWidth = lastColChild.offsetWidth / parseFloat(htmlStyles.fontSize);
275
+ responsiveWidth += 1.8;
276
+ largestWidth = largestWidth > responsiveWidth ? largestWidth : responsiveWidth;
277
+ }
278
+ });
279
+ component.style.setProperty('--cta-width', `${largestWidth}rem`);
280
+ };
281
+ export const getRowHeight = (component, table) => {
282
+ function outputsize() {
283
+ Array.from(table.querySelectorAll('tr')).forEach((row) => {
284
+ const rowHeight = row.offsetHeight;
285
+ row.style.setProperty('--row-height', `${rowHeight}px`);
286
+ });
287
+ }
288
+ new ResizeObserver(outputsize).observe(table);
289
+ };
290
+ // #endregion
291
+ export const setupAdvancedTable = (component, table) => {
292
+ if (component.querySelector('iam-actionbar[data-selectall]') ||
293
+ document.querySelector(`iam-actionbar[data-for='${component.getAttribute('id')}']`)) {
294
+ const actionbar = component.querySelector('iam-actionbar[data-selectall]')
295
+ ? component.querySelector('iam-actionbar[data-selectall]')
296
+ : document.querySelector(`iam-actionbar[data-for='${component.getAttribute('id')}']`);
297
+ addSelectboxes(component, table, actionbar);
298
+ }
299
+ component.querySelectorAll('.dialog__wrapper .btn-compact').forEach((btn) => {
300
+ btn.classList.add('btn-sm');
301
+ btn.classList.add('m-0');
302
+ const tr = btn.closest('tr');
303
+ const td = btn.closest('td');
304
+ const trChildren = Array.prototype.slice.call(tr.children);
305
+ const cellIndex = trChildren.indexOf(td);
306
+ td.classList.add('td--fixed');
307
+ table.querySelector(`thead tr th:nth-child(${cellIndex + 1})`).classList.add('th--fixed');
308
+ });
309
+ };
310
+ // #region Advanced table functions
311
+ export const addSelectboxes = (component, table, actionbar) => {
312
+ Array.from(table.querySelectorAll('thead tr')).forEach((row) => {
313
+ if (row.querySelector('.expand-button-heading'))
314
+ row.querySelector('.expand-button-heading').insertAdjacentHTML('afterend', `<th class="th--fixed"></th>`);
315
+ else
316
+ row.insertAdjacentHTML('afterbegin', `<th class="th--fixed"></th>`);
317
+ });
318
+ Array.from(table.querySelectorAll('tbody tr')).forEach((row, index) => {
319
+ row.setAttribute('data-index', index + 1);
320
+ if (!row.querySelector('.selectrow')) {
321
+ const rowID = `row${uniqueID(index)}`;
322
+ if (row.querySelector('.td--expand'))
323
+ row
324
+ .querySelector('.td--expand')
325
+ .insertAdjacentHTML('afterend', `<td class="td--fixed selectrow selected"><input type="checkbox" name="row" id="${rowID}" ${row.hasAttribute('data-selected') ? `checked="true"` : ''}/><label for="${rowID}"><span class="visually-hidden">Select row</span></label></td>`);
326
+ else
327
+ row.insertAdjacentHTML('afterbegin', `<td class="td--fixed selectrow selected"><input type="checkbox" name="row" id="${rowID}" ${row.hasAttribute('data-selected') ? `checked="true"` : ''}/><label for="${rowID}"><span class="visually-hidden">Select row</span></label></td>`);
328
+ }
329
+ });
330
+ table.addEventListener('change', (event) => {
331
+ if (event && event.target instanceof HTMLElement && event.target.closest('.selectrow input')) {
332
+ const input = event.target.closest('.selectrow input');
333
+ const row = event.target.closest('tr');
334
+ const count = table.querySelectorAll('.selectrow input[type="checkbox"]').length;
335
+ const countChecked = table.querySelectorAll('.selectrow input[type="checkbox"]:checked').length;
336
+ actionbar.setAttribute('data-selected', count == countChecked ? 'all' : countChecked);
337
+ const dispatchedEvent = new CustomEvent('row-selected', {
338
+ detail: {
339
+ rowIndex: row.getAttribute('data-index'),
340
+ checked: input.checked ? true : false,
341
+ },
342
+ });
343
+ component.dispatchEvent(dispatchedEvent);
344
+ }
345
+ });
346
+ actionbar.addEventListener('selected', (event) => {
347
+ if (event.detail.selected == '0') {
348
+ Array.from(table.querySelectorAll('.selectrow input[type="checkbox"]')).forEach((input) => {
349
+ input.checked = false;
350
+ });
351
+ const dispatchedEvent = new CustomEvent('all-rows-unselected');
352
+ component.dispatchEvent(dispatchedEvent);
353
+ }
354
+ else if (event.detail.selected == 'all') {
355
+ Array.from(table.querySelectorAll('.selectrow input[type="checkbox"]')).forEach((input) => {
356
+ input.checked = true;
357
+ });
358
+ const dispatchedEvent = new CustomEvent('all-rows-selected');
359
+ component.dispatchEvent(dispatchedEvent);
360
+ }
361
+ });
362
+ };
363
+ // Export CSV Data
364
+ export const addExportEventListeners = (button, table) => {
365
+ if (!button) {
366
+ return false;
367
+ }
368
+ button.addEventListener('click', () => {
369
+ exportAsCSV(table);
370
+ });
371
+ };
372
+ export const exportAsCSV = function (table) {
373
+ let csvData = [];
374
+ // Get each row data
375
+ const rows = table.getElementsByTagName('tr');
376
+ for (let i = 0; i < rows.length; i++) {
377
+ // Get each column data
378
+ const cols = rows[i].querySelectorAll('td,th');
379
+ // Stores each csv row data
380
+ const csvRow = [];
381
+ for (let j = 0; j < cols.length; j++) {
382
+ // Get the text data of each cell of a row and push it to csvrow
383
+ csvRow.push(`"${cols[j].textContent}"`);
384
+ }
385
+ // Combine each column value with comma
386
+ csvData.push(csvRow.join(','));
387
+ }
388
+ // Combine each row data with new line character
389
+ csvData = csvData.join('\n');
390
+ // Create CSV file object and feed our csvData into it
391
+ const CSVFile = new Blob([csvData], {
392
+ type: 'text/csv',
393
+ });
394
+ // Create to temporary link to initiate download process
395
+ const tempLink = document.createElement('a');
396
+ tempLink.download = 'export.csv';
397
+ const url = window.URL.createObjectURL(CSVFile);
398
+ tempLink.href = url;
399
+ // This link should not be displayed
400
+ tempLink.style.display = 'none';
401
+ document.body.appendChild(tempLink);
402
+ // Automatically click the link to trigger download
403
+ tempLink.click();
404
+ document.body.removeChild(tempLink);
405
+ };
406
+ // #endregion
407
+ export const setupNoSubmitTable = (component, table, form, pagination, savedTableBody) => {
408
+ sortViaHeaders(component, table);
409
+ createSearchDataList(component, table);
410
+ form.addEventListener('change', (event) => {
411
+ if (event && event.target instanceof HTMLElement && event.target.closest('[data-sort]')) {
412
+ sortTable(table, form, savedTableBody);
413
+ }
414
+ });
415
+ addFilterEventListeners(component, table, form, pagination, savedTableBody);
416
+ };
417
+ // #region No submit table functions
418
+ export const sortViaHeaders = (component, table) => {
419
+ table.addEventListener('click', (event) => {
420
+ if (event && event.target instanceof HTMLElement && event.target.closest('[data-sort]')) {
103
421
  const heading = event.target.closest('[data-sort]');
104
422
  heading.setAttribute('data-sort', 'true');
105
423
  // Turn other headings off
@@ -126,32 +444,32 @@ export const addTableEventListeners = (table, wrapper) => {
126
444
  ref: heading.getAttribute('data-ref'),
127
445
  },
128
446
  });
129
- const component = heading.closest('iam-table');
130
447
  component.dispatchEvent(dispatchedEvent);
131
448
  const sortBy = heading.textContent.trim();
132
449
  const order = heading.getAttribute('data-order-by');
133
- if (!wrapper.hasAttribute('data-submit')) {
450
+ if (!component.hasAttribute('data-submit')) {
451
+ // TODO
134
452
  sortTableByValues(table, sortBy, order);
135
453
  }
136
454
  }
137
455
  });
138
456
  };
139
- // Filters
140
- export const createSearchDataList = (table, form) => {
141
- const searchInput = form.querySelector('input[data-search]');
457
+ export const createSearchDataList = (component, table) => {
458
+ var _a;
459
+ const actionbar = component.querySelector('iam-actionbar');
460
+ if (!actionbar)
461
+ return false;
462
+ const searchInput = (_a = actionbar.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('input#search');
142
463
  if (!searchInput)
143
464
  return false;
144
465
  const searchID = searchInput.getAttribute('id');
145
- const searchableColumns = searchInput.getAttribute('data-search').split(',');
146
466
  const inputWrapper = searchInput.parentNode;
147
467
  const searchableTerms = {};
148
- searchableColumns.forEach((columnHeading) => {
149
- Array.from(table.querySelectorAll('td[data-label="' + columnHeading.trim() + '"]')).forEach((td) => {
150
- if (td.querySelector('.td__content'))
151
- searchableTerms[td.querySelector('.td__content').textContent] = td.querySelector('.td__content').textContent;
152
- else
153
- searchableTerms[td.textContent] = td.textContent;
154
- });
468
+ table.querySelectorAll('tbody td:not(.td--fixed)').forEach((td) => {
469
+ if (td.querySelector('.td__content'))
470
+ searchableTerms[td.querySelector('.td__content').textContent] = td.querySelector('.td__content').textContent;
471
+ else
472
+ searchableTerms[td.textContent] = td.textContent;
155
473
  });
156
474
  searchInput.setAttribute('list', `${searchID}_list`);
157
475
  searchInput.setAttribute('autocomplete', 'off');
@@ -161,13 +479,75 @@ export const createSearchDataList = (table, form) => {
161
479
  .map((term) => `<option value="${term}"></option>`)
162
480
  .join('')}`;
163
481
  };
164
- export const addFilterEventListeners = (table, form, pagination, wrapper, savedTableBody) => {
482
+ export const sortTable = (table, form, savedTableBody) => {
483
+ if (form.getAttribute('data-ajax')) {
484
+ return false;
485
+ }
486
+ const tbody = table.querySelector('tbody');
487
+ let selectedOption = form.querySelector(`input[type="radio"][data-sort]:checked`);
488
+ if (form.querySelector('select[data-sort]')) {
489
+ const select = form.querySelector('select[data-sort]');
490
+ selectedOption = form.querySelector(`select[data-sort] option:nth-child(${select.selectedIndex + 1})`);
491
+ }
492
+ const sortBy = selectedOption.getAttribute('data-sort');
493
+ const order = selectedOption.getAttribute('data-order');
494
+ const format = selectedOption.getAttribute('data-format');
495
+ if (!sortBy) {
496
+ tbody.innerHTML = savedTableBody.innerHTML;
497
+ addDataAttributes(table);
498
+ return false;
499
+ }
500
+ sortTableByValues(table, sortBy, order, format);
501
+ };
502
+ export const sortTableByValues = (table, sortBy, order, format = '') => {
503
+ const tbody = table.querySelector('tbody');
504
+ let orderArray = [];
505
+ if (!['asc', 'desc', 'descending'].includes(order)) {
506
+ orderArray = order.split(',');
507
+ }
508
+ // Create an array from the table rows, the index created is then used to sort the array
509
+ let tableArr = [];
510
+ Array.from(tbody.querySelectorAll('tr')).forEach((tableRow) => {
511
+ let rowIndex = tableRow
512
+ .querySelector('td[data-label="' + sortBy + '"], th[data-label="' + sortBy + '"]')
513
+ .textContent.trim();
514
+ if (tableRow.querySelector('[data-label="' + sortBy + '"] .td__content')) {
515
+ rowIndex = tableRow.querySelector('[data-label="' + sortBy + '"] .td__content').textContent.trim();
516
+ }
517
+ // If a predefined order set replace the search term with an ordered numeric value so it can be sorted
518
+ if (orderArray.length && orderArray.includes(rowIndex)) {
519
+ rowIndex = orderArray.indexOf(rowIndex);
520
+ }
521
+ if (isNumeric(rowIndex)) {
522
+ rowIndex = zeroPad(rowIndex, 10);
523
+ }
524
+ // If the sort format is date then lets transform the index to a sortable date (this is never displayed)
525
+ if (format && format == 'date') {
526
+ rowIndex = new Date(rowIndex);
527
+ }
528
+ const dataRow = {
529
+ index: rowIndex,
530
+ row: tableRow,
531
+ };
532
+ tableArr.push(dataRow);
533
+ });
534
+ // Sort array alphabetically
535
+ tableArr.sort((a, b) => (a.index > b.index ? 1 : -1));
536
+ // Reverse if descending
537
+ if (order == 'descending' || order == 'desc') {
538
+ tableArr = tableArr.reverse();
539
+ }
540
+ // Create a string to return and populate the tbody
541
+ let strTbody = '';
542
+ tableArr.forEach((tableRow) => {
543
+ strTbody += tableRow.row.outerHTML;
544
+ });
545
+ tbody.innerHTML = strTbody;
546
+ };
547
+ export const addFilterEventListeners = (component, table, form, pagination, savedTableBody) => {
165
548
  let timer;
166
549
  // Check what conditions are set on the table to see what the form actions are
167
550
  const formSubmit = function (event, paginate = false) {
168
- if (wrapper.hasAttribute('data-no-submit')) {
169
- return false;
170
- }
171
551
  if (form.classList.contains('processing'))
172
552
  return false;
173
553
  Array.from(form.querySelectorAll('iam-applied-filters')).forEach((element) => {
@@ -193,43 +573,44 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
193
573
  });
194
574
  form.classList.remove('processing');
195
575
  }
196
- if (form.hasAttribute('data-ajax')) {
197
- // Default back to page 1
198
- if (!paginate) {
199
- const paginationInput = form.querySelector('[data-pagination]');
200
- paginationInput.value = 1;
201
- wrapper.setAttribute('data-page', 1);
202
- }
203
- loadAjaxTable(table, form, pagination, wrapper);
204
- }
205
- else if (form.hasAttribute('data-submit')) {
206
- form.submit();
207
- }
208
- else {
209
- filterTable(table, form, wrapper);
210
- populateDataQueries(table, form);
211
- }
576
+ filterTable(component, table, form, pagination);
577
+ populateDataQueries(component, table, form);
578
+ /*
212
579
  // Pass post data back to the page
213
580
  if (form.hasAttribute('data-ajax-post')) {
214
- const formData = new FormData(form);
215
- const queryString = new URLSearchParams(formData).toString();
216
- const http = new XMLHttpRequest();
217
- http.open('GET', `${window.location.href}?ajax=true&${queryString}`);
218
- http.send();
581
+ const formData = new FormData(form);
582
+ const queryString = new URLSearchParams(formData).toString();
583
+ const http = new XMLHttpRequest();
584
+ http.open('GET', `${window.location.href}?ajax=true&${queryString}`);
585
+ http.send();
219
586
  }
587
+ */
220
588
  };
221
- if (form.querySelector('iam-actionbar[data-search]')) {
222
- form.querySelector('iam-actionbar[data-search]').addEventListener('search-submit', (event) => {
589
+ if (component.querySelector('iam-actionbar[data-search]')) {
590
+ component.querySelector('iam-actionbar[data-search]').addEventListener('search-submit', (event) => {
223
591
  if (form.querySelector('input[data-search]')) {
224
592
  form.querySelector('input[data-search]').value = event.detail.search;
225
593
  }
226
594
  else {
227
- form.insertAdjacentHTML('beforeend', `<input type="hidden" name="search" data-search="${form.querySelector('iam-actionbar[data-search]').getAttribute('data-search')}" value="${event.detail.search}"/>`);
595
+ form.insertAdjacentHTML('beforeend', `<input type="hidden" name="search" data-search="${component.querySelector('iam-actionbar[data-search]').getAttribute('data-search')}" value="${event.detail.search}"/>`);
228
596
  }
597
+ const submitEvent = new CustomEvent('search-submit', {
598
+ detail: event.details,
599
+ });
600
+ component.dispatchEvent(submitEvent);
229
601
  clearTimeout(timer);
230
602
  formSubmit(event);
231
603
  });
232
604
  }
605
+ if (component.querySelector('iam-actionbar') && !component.querySelector('iam-actionbar').closest('form')) {
606
+ component.querySelector('iam-actionbar').addEventListener('change', (event) => {
607
+ if (!form.querySelector('.duplicate-actionbar')) {
608
+ form.insertAdjacentHTML('beforeend', `<div class="duplicate-actionbar" style="visibility: hidden; pointer-events: none; position: absolute;"></div>`);
609
+ }
610
+ form.querySelector('.duplicate-actionbar').innerHTML = component.querySelector('iam-actionbar').innerHTML;
611
+ filterTable(component, table, form, pagination);
612
+ });
613
+ }
233
614
  form.addEventListener('keyup', (event) => {
234
615
  clearTimeout(timer);
235
616
  if (event && event.target instanceof HTMLElement && event.target.closest('input[data-search]')) {
@@ -240,18 +621,12 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
240
621
  });
241
622
  form.addEventListener('change', (event) => {
242
623
  clearTimeout(timer);
243
- if (event && event.target instanceof HTMLElement && event.target.closest('[data-sort]')) {
244
- if (!form.hasAttribute('data-submit')) {
245
- sortTable(table, form, savedTableBody);
246
- }
247
- formSubmit(event);
248
- }
249
624
  if (event && event.target instanceof HTMLElement && event.target.closest('input[data-search]')) {
250
625
  formSubmit(event);
251
626
  }
252
627
  if (event && event.target instanceof HTMLElement && event.target.closest('[data-filter][data-no-ajax]')) {
253
628
  // Allow for input fields to filter the current results without a new ajax call
254
- filterTable(table, form, wrapper);
629
+ filterTable(component, table, form, pagination);
255
630
  populateDataQueries(table, form);
256
631
  }
257
632
  else if (event &&
@@ -402,72 +777,7 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
402
777
  });
403
778
  });
404
779
  };
405
- export const sortTable = (table, form, savedTableBody) => {
406
- if (form.getAttribute('data-ajax')) {
407
- return false;
408
- }
409
- const tbody = table.querySelector('tbody');
410
- let selectedOption = form.querySelector(`input[type="radio"][data-sort]:checked`);
411
- if (form.querySelector('select[data-sort]')) {
412
- const select = form.querySelector('select[data-sort]');
413
- selectedOption = form.querySelector(`select[data-sort] option:nth-child(${select.selectedIndex + 1})`);
414
- }
415
- const sortBy = selectedOption.getAttribute('data-sort');
416
- const order = selectedOption.getAttribute('data-order');
417
- const format = selectedOption.getAttribute('data-format');
418
- if (!sortBy) {
419
- tbody.innerHTML = savedTableBody.innerHTML;
420
- addDataAttributes(table);
421
- return false;
422
- }
423
- sortTableByValues(table, sortBy, order, format);
424
- };
425
- export const sortTableByValues = (table, sortBy, order, format = '') => {
426
- const tbody = table.querySelector('tbody');
427
- let orderArray = [];
428
- if (!['asc', 'desc', 'descending'].includes(order)) {
429
- orderArray = order.split(',');
430
- }
431
- // Create an array from the table rows, the index created is then used to sort the array
432
- let tableArr = [];
433
- Array.from(tbody.querySelectorAll('tr')).forEach((tableRow) => {
434
- let rowIndex = tableRow
435
- .querySelector('td[data-label="' + sortBy + '"], th[data-label="' + sortBy + '"]')
436
- .textContent.trim();
437
- if (tableRow.querySelector('[data-label="' + sortBy + '"] .td__content')) {
438
- rowIndex = tableRow.querySelector('[data-label="' + sortBy + '"] .td__content').textContent.trim();
439
- }
440
- // If a predefined order set replace the search term with an ordered numeric value so it can be sorted
441
- if (orderArray.length && orderArray.includes(rowIndex)) {
442
- rowIndex = orderArray.indexOf(rowIndex);
443
- }
444
- if (isNumeric(rowIndex)) {
445
- rowIndex = zeroPad(rowIndex, 10);
446
- }
447
- // If the sort format is date then lets transform the index to a sortable date (this is never displayed)
448
- if (format && format == 'date') {
449
- rowIndex = new Date(rowIndex);
450
- }
451
- const dataRow = {
452
- index: rowIndex,
453
- row: tableRow,
454
- };
455
- tableArr.push(dataRow);
456
- });
457
- // Sort array alphabetically
458
- tableArr.sort((a, b) => (a.index > b.index ? 1 : -1));
459
- // Reverse if descending
460
- if (order == 'descending' || order == 'desc') {
461
- tableArr = tableArr.reverse();
462
- }
463
- // Create a string to return and populate the tbody
464
- let strTbody = '';
465
- tableArr.forEach((tableRow) => {
466
- strTbody += tableRow.row.outerHTML;
467
- });
468
- tbody.innerHTML = strTbody;
469
- };
470
- export const filterTable = (table, form, wrapper) => {
780
+ export const filterTable = (component, table, form, pagination) => {
471
781
  table.classList.remove('table--filtered');
472
782
  const filters = filterFilters(form);
473
783
  const searches = [];
@@ -484,9 +794,9 @@ export const filterTable = (table, form, wrapper) => {
484
794
  // Add search columns too
485
795
  if (form.querySelector('input[data-search]')) {
486
796
  const searchInput = form.querySelector('input[data-search]');
487
- const searchColumns = form.querySelector('input[data-search]').getAttribute('data-search').split(',');
488
- searchColumns.forEach((column) => {
489
- searches.push({ column: `${column.trim()}`, value: `${searchInput.value}` });
797
+ //const searchColumns = form.querySelector('input[data-search],[part="search-input"]').getAttribute('data-search').split(',');
798
+ table.querySelectorAll('thead tr th').forEach((column) => {
799
+ searches.push({ column: `${column.textContent.trim()}`, value: `${searchInput.value}` });
490
800
  });
491
801
  }
492
802
  //Display the filter count
@@ -628,20 +938,20 @@ export const filterTable = (table, form, wrapper) => {
628
938
  row.classList.add('filtered--show');
629
939
  }
630
940
  });
631
- if (wrapper) {
632
- wrapper.setAttribute('data-total', matched);
633
- wrapper.setAttribute('data-show', showRows);
634
- wrapper.setAttribute('data-page', page);
941
+ if (pagination) {
942
+ pagination.setAttribute('data-total', matched);
943
+ pagination.setAttribute('data-show', showRows);
944
+ pagination.setAttribute('data-page', page);
635
945
  }
636
946
  };
637
- export const populateDataQueries = (table, form, wrapper) => {
947
+ export const populateDataQueries = (component, table, form) => {
638
948
  const dataQueries = Array.from(form.querySelectorAll('[data-query]'));
639
949
  dataQueries.forEach((queryElement) => {
640
950
  const query = queryElement.getAttribute('data-query');
641
951
  let numberOfMatchedRows = 0;
642
952
  if (query == 'total') {
643
- if (wrapper.hasAttribute('data-total'))
644
- numberOfMatchedRows = wrapper.getAttribute('data-total');
953
+ if (component.hasAttribute('data-total'))
954
+ numberOfMatchedRows = component.getAttribute('data-total');
645
955
  else
646
956
  numberOfMatchedRows = table.classList.contains('table--filtered')
647
957
  ? table.querySelectorAll('tbody tr').length
@@ -685,134 +995,54 @@ export const populateDataQueries = (table, form, wrapper) => {
685
995
  }
686
996
  });
687
997
  };
688
- // Pagination
689
- export const addPaginationEventListeners = function (table, form, pagination, wrapper) {
690
- if (wrapper.hasAttribute('data-no-submit')) {
691
- return false;
692
- }
693
- pagination.addEventListener('update-page', (event) => {
694
- const paginationInput = form.querySelector('[data-pagination]');
695
- const newPage = event.detail.page;
696
- // Set the filter value
697
- paginationInput.value = newPage;
698
- form.dispatchEvent(new Event('paginate'));
699
- // Reset the data attribute
700
- wrapper.setAttribute('data-page', newPage);
701
- if (table.hasAttribute('data-show-history')) {
702
- const url = new URL(location);
703
- url.searchParams.set('page', newPage);
704
- history.pushState({ type: 'pagination', form: form.getAttribute('id'), page: newPage }, '', url);
705
- }
706
- // scroll back to the top of the table
707
- if (!wrapper.hasAttribute('data-no-scroll')) {
708
- const yOffset = -250;
709
- const y = table.getBoundingClientRect().top + window.pageYOffset + yOffset;
710
- window.scrollTo({ top: y, behavior: 'smooth' });
711
- }
712
- });
713
- pagination.addEventListener('update-show', (event) => {
714
- const showInput = form.querySelector('[data-show]');
715
- const showRows = event.detail.show;
716
- showInput.value = showRows;
717
- wrapper.setAttribute('data-show', showRows);
718
- form.dispatchEvent(new Event('submit'));
719
- });
720
- };
721
- // Export CSV Data
722
- export const addExportEventListeners = (button, table) => {
723
- if (!button) {
724
- return false;
998
+ // #endregion
999
+ export const setupSubmitTable = (component, table, form, pagination) => {
1000
+ form.setAttribute('method', 'get');
1001
+ const actionbar = component.querySelector('iam-actionbar');
1002
+ if (actionbar) {
1003
+ actionbar.addEventListener('change', (event) => {
1004
+ form.submit();
1005
+ });
725
1006
  }
726
- button.addEventListener('click', () => {
727
- exportAsCSV(table);
728
- });
729
1007
  };
730
- export const exportAsCSV = function (table) {
731
- let csvData = [];
732
- // Get each row data
733
- const rows = table.getElementsByTagName('tr');
734
- for (let i = 0; i < rows.length; i++) {
735
- // Get each column data
736
- const cols = rows[i].querySelectorAll('td,th');
737
- // Stores each csv row data
738
- const csvRow = [];
739
- for (let j = 0; j < cols.length; j++) {
740
- // Get the text data of each cell of a row and push it to csvrow
741
- csvRow.push(`"${cols[j].textContent}"`);
742
- }
743
- // Combine each column value with comma
744
- csvData.push(csvRow.join(','));
745
- }
746
- // Combine each row data with new line character
747
- csvData = csvData.join('\n');
748
- // Create CSV file object and feed our csvData into it
749
- const CSVFile = new Blob([csvData], {
750
- type: 'text/csv',
1008
+ // #region submit tables functions
1009
+ // #endregion
1010
+ export const setupAjaxTable = (component, table, form, pagination) => {
1011
+ loadAjaxTable(component, table, form, pagination);
1012
+ const actionbar = component.querySelector('iam-actionbar');
1013
+ form.addEventListener('submit', (event) => {
1014
+ loadAjaxTable(component, table, form, pagination);
1015
+ event.preventDefault();
751
1016
  });
752
- // Create to temporary link to initiate download process
753
- const tempLink = document.createElement('a');
754
- tempLink.download = 'export.csv';
755
- const url = window.URL.createObjectURL(CSVFile);
756
- tempLink.href = url;
757
- // This link should not be displayed
758
- tempLink.style.display = 'none';
759
- document.body.appendChild(tempLink);
760
- // Automatically click the link to trigger download
761
- tempLink.click();
762
- document.body.removeChild(tempLink);
763
- };
764
- // After table is loaded
765
- export const makeTableFunctional = function (table, form, pagination, wrapper) {
766
- addDataAttributes(table);
767
- createMobileButton(table, wrapper);
768
- populateDataQueries(table, form, wrapper);
769
- // Work out the largest width of the CTA's in the last column
770
- if (wrapper && wrapper.classList.contains('table--cta')) {
771
- const largestWidth = getLargestLastColWidth(table);
772
- wrapper.style.setProperty('--cta-width', `${largestWidth}rem`);
773
- function outputsize() {
774
- Array.from(table.querySelectorAll('tr')).forEach((row) => {
775
- const rowHeight = row.offsetHeight;
776
- row.style.setProperty('--row-height', `${rowHeight}px`);
777
- });
778
- }
779
- new ResizeObserver(outputsize).observe(table);
1017
+ if (actionbar) {
1018
+ actionbar.addEventListener('change', (event) => {
1019
+ loadAjaxTable(component, table, form, pagination);
1020
+ });
780
1021
  }
781
1022
  };
782
- const filterFilters = function (form) {
783
- const filters = new Object();
784
- // Filter
785
- const filterInputs = Array.from(form.querySelectorAll('[data-filter]'));
786
- filterInputs.forEach((filterInput) => {
787
- // Ignore uncked radio inputs
788
- if (filterInput.type == 'radio' && !filterInput.checked) {
789
- return;
790
- }
791
- if (filterInput.type == 'checkbox' && !filterInput.checked) {
792
- return;
793
- }
794
- if (filterInput && filterInput.value) {
795
- const dataFilter = filterInput.getAttribute('data-filter');
796
- let filterValue = filterInput.value;
797
- if (filterInput.hasAttribute('data-date-from'))
798
- filterValue += '-date-from';
799
- if (filterInput.hasAttribute('data-date-to'))
800
- filterValue += '-date-to';
801
- if (!filters[dataFilter])
802
- filters[dataFilter] = [];
803
- filters[dataFilter].push(filterValue);
804
- }
805
- });
806
- return filters;
807
- };
808
- export const loadAjaxTable = function (table, form, pagination, wrapper) {
1023
+ // #region ajax tables functions
1024
+ export const loadAjaxTable = function (component, table, form, pagination) {
809
1025
  return __awaiter(this, void 0, void 0, function* () {
1026
+ // Add actionbar inputs into form
1027
+ if (component.querySelector('iam-actionbar') && !component.querySelector('iam-actionbar').closest('form')) {
1028
+ if (!form.querySelector('.duplicate-actionbar'))
1029
+ form.insertAdjacentHTML('beforeend', `<div class="duplicate-actionbar" style="visibility: hidden; pointer-events: none; position: absolute;"></div>`);
1030
+ form.querySelector('.duplicate-actionbar').innerHTML = component.querySelector('iam-actionbar').innerHTML;
1031
+ }
1032
+ // Add pagination inputs into form
1033
+ if (!form.querySelector('input[name=show]'))
1034
+ form.insertAdjacentHTML('beforeend', `<input name="show" type="hidden" value="${component.getAttribute('data-show')}" />`);
1035
+ if (!form.querySelector('input[name=page]'))
1036
+ form.insertAdjacentHTML('beforeend', `<input name="page" type="hidden" value="${component.getAttribute('data-page')}" />`);
1037
+ form.querySelector('input[name=page]').value = component.getAttribute('data-page');
1038
+ form.querySelector('input[name=show]').value = component.getAttribute('data-show');
1039
+ // Construct form data to send to api
810
1040
  const formData = new FormData(form);
811
1041
  const queryString = new URLSearchParams(formData).toString();
812
1042
  const columns = table.querySelectorAll('thead tr th:not(.expand-button-heading)');
813
1043
  const tbody = table.querySelector('tbody');
814
1044
  const ajaxURL = form.getAttribute('data-ajax');
815
- wrapper.classList.add('table--loading');
1045
+ component.classList.add('table--loading');
816
1046
  // Display the filter count
817
1047
  const filters = filterFilters(form);
818
1048
  Array.from(form.querySelectorAll('[data-filter-count]')).forEach((element) => {
@@ -867,8 +1097,8 @@ export const loadAjaxTable = function (table, form, pagination, wrapper) {
867
1097
  const totalNumber = resolvePath(response, totalNumberSchema, 15);
868
1098
  const currentPage = resolvePath(response, currentPageSchema, 1);
869
1099
  const data = resolvePath(response, schema);
870
- const emptyMsg = wrapper.hasAttribute('data-empty-msg')
871
- ? wrapper.getAttribute('data-empty-msg')
1100
+ const emptyMsg = component.hasAttribute('data-empty-msg')
1101
+ ? component.getAttribute('data-empty-msg')
872
1102
  : 'No results found';
873
1103
  if (data) {
874
1104
  tbody.innerHTML = '';
@@ -919,11 +1149,10 @@ export const loadAjaxTable = function (table, form, pagination, wrapper) {
919
1149
  });
920
1150
  tbody.appendChild(table_row);
921
1151
  });
922
- createSearchDataList(table, form);
923
- // Add data to the pagination
924
- wrapper.setAttribute('data-total', parseInt(totalNumber));
925
- wrapper.setAttribute('data-page', parseInt(currentPage));
926
- makeTableFunctional(table, form, pagination, wrapper);
1152
+ component.setAttribute('data-total', parseInt(totalNumber));
1153
+ component.setAttribute('data-page', parseInt(currentPage));
1154
+ pagination.setAttribute('data-total', totalNumber);
1155
+ pagination.setAttribute('data-page', currentPage);
927
1156
  Array.from(form.querySelectorAll('[data-ajax-query]')).forEach((queryElement) => {
928
1157
  const totalNumber = resolvePath(response, queryElement.getAttribute('data-ajax-query'), '');
929
1158
  if (queryElement.hasAttribute('data-total'))
@@ -934,13 +1163,15 @@ export const loadAjaxTable = function (table, form, pagination, wrapper) {
934
1163
  if (parseInt(totalNumber) == 0) {
935
1164
  tbody.innerHTML = `<tr><td colspan="100%"><span>${emptyMsg}</span></td></tr>`;
936
1165
  }
937
- wrapper.classList.remove('table--loading');
1166
+ component.classList.remove('table--loading');
938
1167
  window.dataLayer = window.dataLayer || [];
939
1168
  window.dataLayer.push({
940
1169
  event: 'Ajax table loaded',
941
1170
  url: ajaxURL,
942
1171
  formData: queryString,
943
1172
  });
1173
+ setupBasicTable(component, table, form, pagination);
1174
+ setupAdvancedTable(component, table, form, pagination);
944
1175
  }
945
1176
  else {
946
1177
  tbody.innerHTML = '<tr><td colspan="100%"><span>Error loading table</span></td></tr>';
@@ -955,24 +1186,43 @@ export const loadAjaxTable = function (table, form, pagination, wrapper) {
955
1186
  }
956
1187
  });
957
1188
  };
958
- export const formatCell = (format, cellOutput) => {
959
- switch (format) {
960
- case 'datetime':
961
- return (new Date(cellOutput).toLocaleDateString('en-gb', {
962
- weekday: 'short',
963
- year: '2-digit',
964
- month: 'long',
965
- day: 'numeric',
966
- }) +
967
- ' ' +
968
- new Date(cellOutput).toLocaleTimeString('en-gb', { hour: '2-digit', minute: '2-digit' }));
969
- case 'date':
970
- return new Date(cellOutput).toLocaleDateString('en-gb', {
971
- day: 'numeric',
972
- month: 'long',
973
- year: '2-digit',
974
- });
975
- case 'capitalise':
976
- return (cellOutput = ucfirst(cellOutput));
1189
+ // #endregion
1190
+ /*
1191
+ // Pagination - still needed?
1192
+ export const addPaginationEventListeners = function (component, table, form, pagination): void | boolean {
1193
+
1194
+
1195
+ pagination.addEventListener('update-page', (event) => {
1196
+ const paginationInput = form.querySelector('[data-pagination]');
1197
+ const newPage = event.detail.page;
1198
+
1199
+ // Set the filter value
1200
+ paginationInput.value = newPage;
1201
+ form.dispatchEvent(new Event('paginate'));
1202
+
1203
+ // Reset the data attribute
1204
+ component.setAttribute('data-page', newPage);
1205
+
1206
+ if (table.hasAttribute('data-show-history')) {
1207
+ const url = new URL(location);
1208
+ url.searchParams.set('page', newPage);
1209
+ history.pushState({ type: 'pagination', form: form.getAttribute('id'), page: newPage }, '', url);
1210
+ }
1211
+
1212
+ // scroll back to the top of the table
1213
+ if (!component.hasAttribute('data-no-scroll')) {
1214
+ const yOffset = -250;
1215
+ const y = table.getBoundingClientRect().top + window.pageYOffset + yOffset;
1216
+ window.scrollTo({ top: y, behavior: 'smooth' });
977
1217
  }
1218
+ });
1219
+
1220
+ pagination.addEventListener('update-show', (event) => {
1221
+ const showInput = form.querySelector('[data-show]');
1222
+ const showRows = event.detail.show;
1223
+ showInput.value = showRows;
1224
+ component.setAttribute('data-show', showRows);
1225
+ form.dispatchEvent(new Event('submit'));
1226
+ });
978
1227
  };
1228
+ */