@iamproperty/components 7.2.0 → 7.2.1--beta1

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 +35 -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 +543 -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 +128 -0
  98. package/assets/sass/components/table-basic.global.scss +355 -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 +48 -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 +655 -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,184 @@ 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
+ if (component.hasAttribute('data-filterby')) {
62
+ form = document.querySelector(`#${component.getAttribute('data-filterby')}`);
63
+ }
64
+ else if (component.closest('form')) {
65
+ form = component.closest('form');
66
+ }
67
+ else {
68
+ table.parentNode.insertBefore(form, table.nextSibling);
69
+ }
70
+ if (form.hasAttribute('data-ajax'))
71
+ component.setAttribute('data-ajax', form.getAttribute('data-ajax'));
72
+ if (form.hasAttribute('data-schema'))
73
+ component.setAttribute('data-schema', form.getAttribute('data-schema'));
74
+ };
75
+ export const paginateTable = (component, table, form, pagination, callback) => {
76
+ if (!form.querySelector('[name=show]'))
77
+ form.insertAdjacentHTML('beforeend', `<input name="show" type="hidden" value="${component.getAttribute('data-show')}" />`);
78
+ if (!form.querySelector('[name=page]'))
79
+ form.insertAdjacentHTML('beforeend', `<input name="page" type="hidden" value="${component.getAttribute('data-page')}" />`);
80
+ pagination.addEventListener('update-show', (event) => {
81
+ if (form.querySelector('[name=show]').value != event.detail.show) {
82
+ form.querySelector('[name=show]').value = event.detail.show;
83
+ const updateEvent = new CustomEvent('update-show', { detail: { show: event.detail.show } });
84
+ component.dispatchEvent(updateEvent);
85
+ updateAttributes(component, pagination);
86
+ callback();
87
+ }
88
+ });
89
+ pagination.addEventListener('update-page', (event) => {
90
+ if (form.querySelector('[name=page]').value != event.detail.page) {
91
+ form.querySelector('[name=page]').value = event.detail.page;
92
+ const updateEvent = new CustomEvent('update-page', { detail: { page: event.detail.page } });
93
+ component.dispatchEvent(updateEvent);
94
+ updateAttributes(component, pagination);
95
+ callback();
96
+ // scroll back to the top of the table
97
+ if (!component.hasAttribute('data-no-scroll')) {
98
+ const yOffset = -250;
99
+ const y = table.getBoundingClientRect().top + window.pageYOffset + yOffset;
100
+ window.scrollTo({ top: y, behavior: 'smooth' });
101
+ }
102
+ }
103
+ });
104
+ };
105
+ export const findForm = (component, table) => {
106
+ let form = document.createElement('form');
107
+ if (component.hasAttribute('data-filterby')) {
108
+ form = document.querySelector(`#${component.getAttribute('data-filterby')}`);
109
+ }
110
+ else if (component.closest('form')) {
111
+ form = component.closest('form');
112
+ }
113
+ else {
114
+ table.parentNode.insertBefore(form, table.nextSibling);
115
+ }
116
+ return form;
117
+ };
118
+ // #endregion
119
+ export const setupBasicTable = (component, table, form, pagination) => {
120
+ const tableWrapper = component.shadowRoot.querySelector('.table__wrapper');
121
+ if (!component.hasAttribute('data-total'))
122
+ component.setAttribute('data-total', component.querySelectorAll('tbody tr').length);
123
+ if (!component.hasAttribute('data-page'))
124
+ component.setAttribute('data-page', 1);
125
+ if (!component.hasAttribute('data-show'))
126
+ component.setAttribute('data-show', 5);
127
+ if (!component.hasAttribute('data-increment'))
128
+ component.setAttribute('data-increment', component.getAttribute('data-show'));
129
+ transferAttributes(component, pagination);
130
+ addDataAttributes(table);
131
+ createMobileButton(component, table);
132
+ // Max height
133
+ if (component.classList.contains('mh-sm'))
134
+ tableWrapper.classList.add('mh-sm');
135
+ if (component.classList.contains('mh-md'))
136
+ tableWrapper.classList.add('mh-md');
137
+ if (component.classList.contains('mh-lg'))
138
+ tableWrapper.classList.add('mh-lg');
139
+ if (component.classList.contains('table--cta')) {
140
+ getLargestLastColWidth(component, table);
141
+ getRowHeight(component, table);
142
+ }
143
+ };
144
+ // #region Basic table fnctions
145
+ export const transferAttributes = (component, pagination) => {
146
+ if (component.hasAttribute('data-total'))
147
+ pagination.setAttribute('data-total', component.getAttribute('data-total'));
148
+ if (component.hasAttribute('data-page'))
149
+ pagination.setAttribute('data-page', component.getAttribute('data-page'));
150
+ if (component.hasAttribute('data-show'))
151
+ pagination.setAttribute('data-show', component.getAttribute('data-show'));
152
+ if (component.hasAttribute('data-increment'))
153
+ pagination.setAttribute('data-increment', component.getAttribute('data-show'));
154
+ if (component.hasAttribute('data-page-jump'))
155
+ pagination.setAttribute('data-page-jump', 'true');
156
+ if (component.hasAttribute('data-per-page'))
157
+ pagination.setAttribute('data-per-page', 'true');
158
+ if (component.hasAttribute('data-item-count'))
159
+ pagination.setAttribute('data-item-count', 'true');
160
+ if (component.hasAttribute('data-loading'))
161
+ pagination.setAttribute('data-loading', 'true');
162
+ if (component.classList.contains('table--fullwidth'))
163
+ pagination.setAttribute('data-minimal', 'true');
164
+ };
165
+ export const updateAttributes = (component, pagination) => {
166
+ component.setAttribute('data-total', pagination.getAttribute('data-total'));
167
+ component.setAttribute('data-page', pagination.getAttribute('data-page'));
168
+ component.setAttribute('data-show', pagination.getAttribute('data-show'));
169
+ component.setAttribute('data-increment', pagination.getAttribute('data-show'));
170
+ };
171
+ export const paginateRows = (component) => {
172
+ const total = component.getAttribute('data-total');
173
+ const page = component.getAttribute('data-page');
174
+ const show = component.getAttribute('data-show');
175
+ const increment = component.getAttribute('data-increment');
176
+ const table = component.querySelector('table');
177
+ const end = page * show;
178
+ const start = end - show;
179
+ Array.from(table.querySelectorAll('tbody tr')).forEach((row, index) => {
180
+ if (index >= start && index < end) {
181
+ row.classList.add('show');
182
+ }
183
+ else {
184
+ row.classList.remove('show');
185
+ }
186
+ });
187
+ };
12
188
  export const addDataAttributes = (table) => {
13
189
  const colHeadings = Array.from(table.querySelectorAll('thead th'));
14
190
  const colRows = Array.from(table.querySelectorAll('tbody tr'));
@@ -35,7 +211,8 @@ export const addDataAttributes = (table) => {
35
211
  'on track',
36
212
  'not started',
37
213
  'warning',
38
- 'error',
214
+ 'successful',
215
+ 'failed',
39
216
  ];
40
217
  cells.forEach((cell, cellIndex) => {
41
218
  const heading = colHeadings[cellIndex];
@@ -57,37 +234,21 @@ export const addDataAttributes = (table) => {
57
234
  });
58
235
  });
59
236
  };
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'))
237
+ export const createMobileButton = (component, table) => {
238
+ if (component.classList.contains('table--fullwidth') && !component.hasAttribute('data-expandable'))
76
239
  return false;
77
- if (table.querySelectorAll('thead tr th').length < 4 && !wrapper.hasAttribute('data-expandable'))
240
+ if (table.querySelectorAll('thead tr th').length < 4 && !component.hasAttribute('data-expandable'))
78
241
  return false;
79
242
  //If the expand column already exists we don't need to add a new one.
80
243
  Array.from(table.querySelectorAll('thead tr')).forEach((row) => {
81
244
  if (!table.querySelectorAll('thead tr th.expand-button-heading').length) {
82
- row.insertAdjacentHTML('afterbegin', `<th class="th--fixed expand-button-heading"></th>`);
245
+ row.insertAdjacentHTML('afterbegin', `<th class="${component.hasAttribute('data-expandable') ? 'th--fixed ' : ''}expand-button-heading"></th>`);
83
246
  }
84
247
  });
85
- Array.from(table.querySelectorAll('tbody tr')).forEach((row) => {
248
+ Array.from(table.querySelectorAll('tbody tr')).forEach((row, index) => {
86
249
  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>`);
250
+ 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
251
  });
89
- };
90
- export const addTableEventListeners = (table, wrapper) => {
91
252
  table.addEventListener('click', (event) => {
92
253
  if (event && event.target instanceof HTMLElement && event.target.closest('[data-expand-button]')) {
93
254
  const button = event.target.closest('[data-expand-button]');
@@ -98,8 +259,164 @@ export const addTableEventListeners = (table, wrapper) => {
98
259
  else
99
260
  tableRow.setAttribute('data-view', 'full');
100
261
  button.blur();
262
+ component.dispatchEvent(new CustomEvent('row-expanded', { detail: { row: button.getAttribute('data-index') } }));
101
263
  }
102
- else if (event && event.target instanceof HTMLElement && event.target.closest('[data-sort]')) {
264
+ });
265
+ };
266
+ export const getLargestLastColWidth = (component, table) => {
267
+ let largestWidth = 0;
268
+ Array.from(table.querySelectorAll('tbody tr')).forEach((row) => {
269
+ const htmlStyles = window.getComputedStyle(document.querySelector('html'));
270
+ const lastColChild = row.querySelector(':scope > *:last-child > *:first-child');
271
+ if (lastColChild) {
272
+ lastColChild.classList.add('text-nowrap');
273
+ let responsiveWidth = lastColChild.offsetWidth / parseFloat(htmlStyles.fontSize);
274
+ responsiveWidth += 1.8;
275
+ largestWidth = largestWidth > responsiveWidth ? largestWidth : responsiveWidth;
276
+ }
277
+ });
278
+ component.style.setProperty('--cta-width', `${largestWidth}rem`);
279
+ };
280
+ export const getRowHeight = (component, table) => {
281
+ function outputsize() {
282
+ Array.from(table.querySelectorAll('tr')).forEach((row) => {
283
+ const rowHeight = row.offsetHeight;
284
+ row.style.setProperty('--row-height', `${rowHeight}px`);
285
+ });
286
+ }
287
+ new ResizeObserver(outputsize).observe(table);
288
+ };
289
+ // #endregion
290
+ export const setupAdvancedTable = (component, table) => {
291
+ if (component.querySelector('iam-actionbar[data-selectall]') ||
292
+ document.querySelector(`iam-actionbar[data-for='${component.getAttribute('id')}']`)) {
293
+ const actionbar = component.querySelector('iam-actionbar[data-selectall]')
294
+ ? component.querySelector('iam-actionbar[data-selectall]')
295
+ : document.querySelector(`iam-actionbar[data-for='${component.getAttribute('id')}']`);
296
+ addSelectboxes(component, table, actionbar);
297
+ }
298
+ component.querySelectorAll('.dialog__wrapper .btn-compact').forEach((btn) => {
299
+ btn.classList.add('btn-sm');
300
+ btn.classList.add('m-0');
301
+ const tr = btn.closest('tr');
302
+ const td = btn.closest('td');
303
+ const trChildren = Array.prototype.slice.call(tr.children);
304
+ const cellIndex = trChildren.indexOf(td);
305
+ td.classList.add('td--fixed');
306
+ table.querySelector(`thead tr th:nth-child(${cellIndex + 1})`).classList.add('th--fixed');
307
+ });
308
+ };
309
+ // #region Advanced table functions
310
+ export const addSelectboxes = (component, table, actionbar) => {
311
+ Array.from(table.querySelectorAll('thead tr')).forEach((row) => {
312
+ if (row.querySelector('.expand-button-heading'))
313
+ row.querySelector('.expand-button-heading').insertAdjacentHTML('afterend', `<th class="th--fixed"></th>`);
314
+ else
315
+ row.insertAdjacentHTML('afterbegin', `<th class="th--fixed"></th>`);
316
+ });
317
+ Array.from(table.querySelectorAll('tbody tr')).forEach((row, index) => {
318
+ row.setAttribute('data-index', index + 1);
319
+ if (!row.querySelector('.selectrow')) {
320
+ const rowID = `row${uniqueID(index)}`;
321
+ if (row.querySelector('.td--expand'))
322
+ row
323
+ .querySelector('.td--expand')
324
+ .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>`);
325
+ else
326
+ 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>`);
327
+ }
328
+ });
329
+ table.addEventListener('change', (event) => {
330
+ if (event && event.target instanceof HTMLElement && event.target.closest('.selectrow input')) {
331
+ const input = event.target.closest('.selectrow input');
332
+ const row = event.target.closest('tr');
333
+ const count = table.querySelectorAll('.selectrow input[type="checkbox"]').length;
334
+ const countChecked = table.querySelectorAll('.selectrow input[type="checkbox"]:checked').length;
335
+ actionbar.setAttribute('data-selected', count == countChecked ? 'all' : countChecked);
336
+ const dispatchedEvent = new CustomEvent('row-selected', {
337
+ detail: {
338
+ rowIndex: row.getAttribute('data-index'),
339
+ checked: input.checked ? true : false,
340
+ },
341
+ });
342
+ component.dispatchEvent(dispatchedEvent);
343
+ }
344
+ });
345
+ actionbar.addEventListener('selected', (event) => {
346
+ if (event.detail.selected == '0') {
347
+ Array.from(table.querySelectorAll('.selectrow input[type="checkbox"]')).forEach((input) => {
348
+ input.checked = false;
349
+ });
350
+ const dispatchedEvent = new CustomEvent('all-rows-unselected');
351
+ component.dispatchEvent(dispatchedEvent);
352
+ }
353
+ else if (event.detail.selected == 'all') {
354
+ Array.from(table.querySelectorAll('.selectrow input[type="checkbox"]')).forEach((input) => {
355
+ input.checked = true;
356
+ });
357
+ const dispatchedEvent = new CustomEvent('all-rows-selected');
358
+ component.dispatchEvent(dispatchedEvent);
359
+ }
360
+ });
361
+ };
362
+ // Export CSV Data
363
+ export const addExportEventListeners = (button, table) => {
364
+ if (!button) {
365
+ return false;
366
+ }
367
+ button.addEventListener('click', () => {
368
+ exportAsCSV(table);
369
+ });
370
+ };
371
+ export const exportAsCSV = function (table) {
372
+ let csvData = [];
373
+ // Get each row data
374
+ const rows = table.getElementsByTagName('tr');
375
+ for (let i = 0; i < rows.length; i++) {
376
+ // Get each column data
377
+ const cols = rows[i].querySelectorAll('td,th');
378
+ // Stores each csv row data
379
+ const csvRow = [];
380
+ for (let j = 0; j < cols.length; j++) {
381
+ // Get the text data of each cell of a row and push it to csvrow
382
+ csvRow.push(`"${cols[j].textContent}"`);
383
+ }
384
+ // Combine each column value with comma
385
+ csvData.push(csvRow.join(','));
386
+ }
387
+ // Combine each row data with new line character
388
+ csvData = csvData.join('\n');
389
+ // Create CSV file object and feed our csvData into it
390
+ const CSVFile = new Blob([csvData], {
391
+ type: 'text/csv',
392
+ });
393
+ // Create to temporary link to initiate download process
394
+ const tempLink = document.createElement('a');
395
+ tempLink.download = 'export.csv';
396
+ const url = window.URL.createObjectURL(CSVFile);
397
+ tempLink.href = url;
398
+ // This link should not be displayed
399
+ tempLink.style.display = 'none';
400
+ document.body.appendChild(tempLink);
401
+ // Automatically click the link to trigger download
402
+ tempLink.click();
403
+ document.body.removeChild(tempLink);
404
+ };
405
+ // #endregion
406
+ export const setupNoSubmitTable = (component, table, form, pagination, savedTableBody) => {
407
+ sortViaHeaders(component, table);
408
+ createSearchDataList(component, table);
409
+ form.addEventListener('change', (event) => {
410
+ if (event && event.target instanceof HTMLElement && event.target.closest('[data-sort]')) {
411
+ sortTable(table, form, savedTableBody);
412
+ }
413
+ });
414
+ addFilterEventListeners(component, table, form, pagination, savedTableBody);
415
+ };
416
+ // #region No submit table functions
417
+ export const sortViaHeaders = (component, table) => {
418
+ table.addEventListener('click', (event) => {
419
+ if (event && event.target instanceof HTMLElement && event.target.closest('[data-sort]')) {
103
420
  const heading = event.target.closest('[data-sort]');
104
421
  heading.setAttribute('data-sort', 'true');
105
422
  // Turn other headings off
@@ -126,32 +443,32 @@ export const addTableEventListeners = (table, wrapper) => {
126
443
  ref: heading.getAttribute('data-ref'),
127
444
  },
128
445
  });
129
- const component = heading.closest('iam-table');
130
446
  component.dispatchEvent(dispatchedEvent);
131
447
  const sortBy = heading.textContent.trim();
132
448
  const order = heading.getAttribute('data-order-by');
133
- if (!wrapper.hasAttribute('data-submit')) {
449
+ if (!component.hasAttribute('data-submit')) {
450
+ // TODO
134
451
  sortTableByValues(table, sortBy, order);
135
452
  }
136
453
  }
137
454
  });
138
455
  };
139
- // Filters
140
- export const createSearchDataList = (table, form) => {
141
- const searchInput = form.querySelector('input[data-search]');
456
+ export const createSearchDataList = (component, table) => {
457
+ var _a;
458
+ const actionbar = component.querySelector('iam-actionbar');
459
+ if (!actionbar)
460
+ return false;
461
+ const searchInput = (_a = actionbar.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('input#search');
142
462
  if (!searchInput)
143
463
  return false;
144
464
  const searchID = searchInput.getAttribute('id');
145
- const searchableColumns = searchInput.getAttribute('data-search').split(',');
146
465
  const inputWrapper = searchInput.parentNode;
147
466
  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
- });
467
+ table.querySelectorAll('tbody td:not(.td--fixed)').forEach((td) => {
468
+ if (td.querySelector('.td__content'))
469
+ searchableTerms[td.querySelector('.td__content').textContent] = td.querySelector('.td__content').textContent;
470
+ else
471
+ searchableTerms[td.textContent] = td.textContent;
155
472
  });
156
473
  searchInput.setAttribute('list', `${searchID}_list`);
157
474
  searchInput.setAttribute('autocomplete', 'off');
@@ -161,13 +478,75 @@ export const createSearchDataList = (table, form) => {
161
478
  .map((term) => `<option value="${term}"></option>`)
162
479
  .join('')}`;
163
480
  };
164
- export const addFilterEventListeners = (table, form, pagination, wrapper, savedTableBody) => {
481
+ export const sortTable = (table, form, savedTableBody) => {
482
+ if (form.getAttribute('data-ajax')) {
483
+ return false;
484
+ }
485
+ const tbody = table.querySelector('tbody');
486
+ let selectedOption = form.querySelector(`input[type="radio"][data-sort]:checked`);
487
+ if (form.querySelector('select[data-sort]')) {
488
+ const select = form.querySelector('select[data-sort]');
489
+ selectedOption = form.querySelector(`select[data-sort] option:nth-child(${select.selectedIndex + 1})`);
490
+ }
491
+ const sortBy = selectedOption.getAttribute('data-sort');
492
+ const order = selectedOption.getAttribute('data-order');
493
+ const format = selectedOption.getAttribute('data-format');
494
+ if (!sortBy) {
495
+ tbody.innerHTML = savedTableBody.innerHTML;
496
+ addDataAttributes(table);
497
+ return false;
498
+ }
499
+ sortTableByValues(table, sortBy, order, format);
500
+ };
501
+ export const sortTableByValues = (table, sortBy, order, format = '') => {
502
+ const tbody = table.querySelector('tbody');
503
+ let orderArray = [];
504
+ if (!['asc', 'desc', 'descending'].includes(order)) {
505
+ orderArray = order.split(',');
506
+ }
507
+ // Create an array from the table rows, the index created is then used to sort the array
508
+ let tableArr = [];
509
+ Array.from(tbody.querySelectorAll('tr')).forEach((tableRow) => {
510
+ let rowIndex = tableRow
511
+ .querySelector('td[data-label="' + sortBy + '"], th[data-label="' + sortBy + '"]')
512
+ .textContent.trim();
513
+ if (tableRow.querySelector('[data-label="' + sortBy + '"] .td__content')) {
514
+ rowIndex = tableRow.querySelector('[data-label="' + sortBy + '"] .td__content').textContent.trim();
515
+ }
516
+ // If a predefined order set replace the search term with an ordered numeric value so it can be sorted
517
+ if (orderArray.length && orderArray.includes(rowIndex)) {
518
+ rowIndex = orderArray.indexOf(rowIndex);
519
+ }
520
+ if (isNumeric(rowIndex)) {
521
+ rowIndex = zeroPad(rowIndex, 10);
522
+ }
523
+ // If the sort format is date then lets transform the index to a sortable date (this is never displayed)
524
+ if (format && format == 'date') {
525
+ rowIndex = new Date(rowIndex);
526
+ }
527
+ const dataRow = {
528
+ index: rowIndex,
529
+ row: tableRow,
530
+ };
531
+ tableArr.push(dataRow);
532
+ });
533
+ // Sort array alphabetically
534
+ tableArr.sort((a, b) => (a.index > b.index ? 1 : -1));
535
+ // Reverse if descending
536
+ if (order == 'descending' || order == 'desc') {
537
+ tableArr = tableArr.reverse();
538
+ }
539
+ // Create a string to return and populate the tbody
540
+ let strTbody = '';
541
+ tableArr.forEach((tableRow) => {
542
+ strTbody += tableRow.row.outerHTML;
543
+ });
544
+ tbody.innerHTML = strTbody;
545
+ };
546
+ export const addFilterEventListeners = (component, table, form, pagination, savedTableBody) => {
165
547
  let timer;
166
548
  // Check what conditions are set on the table to see what the form actions are
167
549
  const formSubmit = function (event, paginate = false) {
168
- if (wrapper.hasAttribute('data-no-submit')) {
169
- return false;
170
- }
171
550
  if (form.classList.contains('processing'))
172
551
  return false;
173
552
  Array.from(form.querySelectorAll('iam-applied-filters')).forEach((element) => {
@@ -193,43 +572,44 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
193
572
  });
194
573
  form.classList.remove('processing');
195
574
  }
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
- }
575
+ filterTable(component, table, form, pagination);
576
+ populateDataQueries(component, table, form);
577
+ /*
212
578
  // Pass post data back to the page
213
579
  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();
580
+ const formData = new FormData(form);
581
+ const queryString = new URLSearchParams(formData).toString();
582
+ const http = new XMLHttpRequest();
583
+ http.open('GET', `${window.location.href}?ajax=true&${queryString}`);
584
+ http.send();
219
585
  }
586
+ */
220
587
  };
221
- if (form.querySelector('iam-actionbar[data-search]')) {
222
- form.querySelector('iam-actionbar[data-search]').addEventListener('search-submit', (event) => {
588
+ if (component.querySelector('iam-actionbar[data-search]')) {
589
+ component.querySelector('iam-actionbar[data-search]').addEventListener('search-submit', (event) => {
223
590
  if (form.querySelector('input[data-search]')) {
224
591
  form.querySelector('input[data-search]').value = event.detail.search;
225
592
  }
226
593
  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}"/>`);
594
+ form.insertAdjacentHTML('beforeend', `<input type="hidden" name="search" data-search="${component.querySelector('iam-actionbar[data-search]').getAttribute('data-search')}" value="${event.detail.search}"/>`);
228
595
  }
596
+ const submitEvent = new CustomEvent('search-submit', {
597
+ detail: event.details,
598
+ });
599
+ component.dispatchEvent(submitEvent);
229
600
  clearTimeout(timer);
230
601
  formSubmit(event);
231
602
  });
232
603
  }
604
+ if (component.querySelector('iam-actionbar') && !component.querySelector('iam-actionbar').closest('form')) {
605
+ component.querySelector('iam-actionbar').addEventListener('change', (event) => {
606
+ if (!form.querySelector('.duplicate-actionbar')) {
607
+ form.insertAdjacentHTML('beforeend', `<div class="duplicate-actionbar" style="visibility: hidden; pointer-events: none; position: absolute;"></div>`);
608
+ }
609
+ form.querySelector('.duplicate-actionbar').innerHTML = component.querySelector('iam-actionbar').innerHTML;
610
+ filterTable(component, table, form, pagination);
611
+ });
612
+ }
233
613
  form.addEventListener('keyup', (event) => {
234
614
  clearTimeout(timer);
235
615
  if (event && event.target instanceof HTMLElement && event.target.closest('input[data-search]')) {
@@ -240,18 +620,12 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
240
620
  });
241
621
  form.addEventListener('change', (event) => {
242
622
  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
623
  if (event && event.target instanceof HTMLElement && event.target.closest('input[data-search]')) {
250
624
  formSubmit(event);
251
625
  }
252
626
  if (event && event.target instanceof HTMLElement && event.target.closest('[data-filter][data-no-ajax]')) {
253
627
  // Allow for input fields to filter the current results without a new ajax call
254
- filterTable(table, form, wrapper);
628
+ filterTable(component, table, form, pagination);
255
629
  populateDataQueries(table, form);
256
630
  }
257
631
  else if (event &&
@@ -402,72 +776,7 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
402
776
  });
403
777
  });
404
778
  };
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) => {
779
+ export const filterTable = (component, table, form, pagination) => {
471
780
  table.classList.remove('table--filtered');
472
781
  const filters = filterFilters(form);
473
782
  const searches = [];
@@ -484,9 +793,9 @@ export const filterTable = (table, form, wrapper) => {
484
793
  // Add search columns too
485
794
  if (form.querySelector('input[data-search]')) {
486
795
  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}` });
796
+ //const searchColumns = form.querySelector('input[data-search],[part="search-input"]').getAttribute('data-search').split(',');
797
+ table.querySelectorAll('thead tr th').forEach((column) => {
798
+ searches.push({ column: `${column.textContent.trim()}`, value: `${searchInput.value}` });
490
799
  });
491
800
  }
492
801
  //Display the filter count
@@ -628,20 +937,20 @@ export const filterTable = (table, form, wrapper) => {
628
937
  row.classList.add('filtered--show');
629
938
  }
630
939
  });
631
- if (wrapper) {
632
- wrapper.setAttribute('data-total', matched);
633
- wrapper.setAttribute('data-show', showRows);
634
- wrapper.setAttribute('data-page', page);
940
+ if (pagination) {
941
+ pagination.setAttribute('data-total', matched);
942
+ pagination.setAttribute('data-show', showRows);
943
+ pagination.setAttribute('data-page', page);
635
944
  }
636
945
  };
637
- export const populateDataQueries = (table, form, wrapper) => {
946
+ export const populateDataQueries = (component, table, form) => {
638
947
  const dataQueries = Array.from(form.querySelectorAll('[data-query]'));
639
948
  dataQueries.forEach((queryElement) => {
640
949
  const query = queryElement.getAttribute('data-query');
641
950
  let numberOfMatchedRows = 0;
642
951
  if (query == 'total') {
643
- if (wrapper.hasAttribute('data-total'))
644
- numberOfMatchedRows = wrapper.getAttribute('data-total');
952
+ if (component.hasAttribute('data-total'))
953
+ numberOfMatchedRows = component.getAttribute('data-total');
645
954
  else
646
955
  numberOfMatchedRows = table.classList.contains('table--filtered')
647
956
  ? table.querySelectorAll('tbody tr').length
@@ -685,134 +994,54 @@ export const populateDataQueries = (table, form, wrapper) => {
685
994
  }
686
995
  });
687
996
  };
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;
997
+ // #endregion
998
+ export const setupSubmitTable = (component, table, form, pagination) => {
999
+ form.setAttribute('method', 'get');
1000
+ const actionbar = component.querySelector('iam-actionbar');
1001
+ if (actionbar) {
1002
+ actionbar.addEventListener('change', (event) => {
1003
+ form.submit();
1004
+ });
725
1005
  }
726
- button.addEventListener('click', () => {
727
- exportAsCSV(table);
728
- });
729
1006
  };
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',
1007
+ // #region submit tables functions
1008
+ // #endregion
1009
+ export const setupAjaxTable = (component, table, form, pagination) => {
1010
+ loadAjaxTable(component, table, form, pagination);
1011
+ const actionbar = component.querySelector('iam-actionbar');
1012
+ form.addEventListener('submit', (event) => {
1013
+ loadAjaxTable(component, table, form, pagination);
1014
+ event.preventDefault();
751
1015
  });
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);
1016
+ if (actionbar) {
1017
+ actionbar.addEventListener('change', (event) => {
1018
+ loadAjaxTable(component, table, form, pagination);
1019
+ });
780
1020
  }
781
1021
  };
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) {
1022
+ // #region ajax tables functions
1023
+ export const loadAjaxTable = function (component, table, form, pagination) {
809
1024
  return __awaiter(this, void 0, void 0, function* () {
1025
+ // Add actionbar inputs into form
1026
+ if (component.querySelector('iam-actionbar') && !component.querySelector('iam-actionbar').closest('form')) {
1027
+ if (!form.querySelector('.duplicate-actionbar'))
1028
+ form.insertAdjacentHTML('beforeend', `<div class="duplicate-actionbar" style="visibility: hidden; pointer-events: none; position: absolute;"></div>`);
1029
+ form.querySelector('.duplicate-actionbar').innerHTML = component.querySelector('iam-actionbar').innerHTML;
1030
+ }
1031
+ // Add pagination inputs into form
1032
+ if (!form.querySelector('input[name=show]'))
1033
+ form.insertAdjacentHTML('beforeend', `<input name="show" type="hidden" value="${component.getAttribute('data-show')}" />`);
1034
+ if (!form.querySelector('input[name=page]'))
1035
+ form.insertAdjacentHTML('beforeend', `<input name="page" type="hidden" value="${component.getAttribute('data-page')}" />`);
1036
+ form.querySelector('input[name=page]').value = component.getAttribute('data-page');
1037
+ form.querySelector('input[name=show]').value = component.getAttribute('data-show');
1038
+ // Construct form data to send to api
810
1039
  const formData = new FormData(form);
811
1040
  const queryString = new URLSearchParams(formData).toString();
812
1041
  const columns = table.querySelectorAll('thead tr th:not(.expand-button-heading)');
813
1042
  const tbody = table.querySelector('tbody');
814
1043
  const ajaxURL = form.getAttribute('data-ajax');
815
- wrapper.classList.add('table--loading');
1044
+ component.classList.add('table--loading');
816
1045
  // Display the filter count
817
1046
  const filters = filterFilters(form);
818
1047
  Array.from(form.querySelectorAll('[data-filter-count]')).forEach((element) => {
@@ -867,8 +1096,8 @@ export const loadAjaxTable = function (table, form, pagination, wrapper) {
867
1096
  const totalNumber = resolvePath(response, totalNumberSchema, 15);
868
1097
  const currentPage = resolvePath(response, currentPageSchema, 1);
869
1098
  const data = resolvePath(response, schema);
870
- const emptyMsg = wrapper.hasAttribute('data-empty-msg')
871
- ? wrapper.getAttribute('data-empty-msg')
1099
+ const emptyMsg = component.hasAttribute('data-empty-msg')
1100
+ ? component.getAttribute('data-empty-msg')
872
1101
  : 'No results found';
873
1102
  if (data) {
874
1103
  tbody.innerHTML = '';
@@ -919,11 +1148,10 @@ export const loadAjaxTable = function (table, form, pagination, wrapper) {
919
1148
  });
920
1149
  tbody.appendChild(table_row);
921
1150
  });
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);
1151
+ component.setAttribute('data-total', parseInt(totalNumber));
1152
+ component.setAttribute('data-page', parseInt(currentPage));
1153
+ pagination.setAttribute('data-total', totalNumber);
1154
+ pagination.setAttribute('data-page', currentPage);
927
1155
  Array.from(form.querySelectorAll('[data-ajax-query]')).forEach((queryElement) => {
928
1156
  const totalNumber = resolvePath(response, queryElement.getAttribute('data-ajax-query'), '');
929
1157
  if (queryElement.hasAttribute('data-total'))
@@ -934,13 +1162,15 @@ export const loadAjaxTable = function (table, form, pagination, wrapper) {
934
1162
  if (parseInt(totalNumber) == 0) {
935
1163
  tbody.innerHTML = `<tr><td colspan="100%"><span>${emptyMsg}</span></td></tr>`;
936
1164
  }
937
- wrapper.classList.remove('table--loading');
1165
+ component.classList.remove('table--loading');
938
1166
  window.dataLayer = window.dataLayer || [];
939
1167
  window.dataLayer.push({
940
1168
  event: 'Ajax table loaded',
941
1169
  url: ajaxURL,
942
1170
  formData: queryString,
943
1171
  });
1172
+ setupBasicTable(component, table, form, pagination);
1173
+ setupAdvancedTable(component, table, form, pagination);
944
1174
  }
945
1175
  else {
946
1176
  tbody.innerHTML = '<tr><td colspan="100%"><span>Error loading table</span></td></tr>';
@@ -955,24 +1185,43 @@ export const loadAjaxTable = function (table, form, pagination, wrapper) {
955
1185
  }
956
1186
  });
957
1187
  };
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));
1188
+ // #endregion
1189
+ /*
1190
+ // Pagination - still needed?
1191
+ export const addPaginationEventListeners = function (component, table, form, pagination): void | boolean {
1192
+
1193
+
1194
+ pagination.addEventListener('update-page', (event) => {
1195
+ const paginationInput = form.querySelector('[data-pagination]');
1196
+ const newPage = event.detail.page;
1197
+
1198
+ // Set the filter value
1199
+ paginationInput.value = newPage;
1200
+ form.dispatchEvent(new Event('paginate'));
1201
+
1202
+ // Reset the data attribute
1203
+ component.setAttribute('data-page', newPage);
1204
+
1205
+ if (table.hasAttribute('data-show-history')) {
1206
+ const url = new URL(location);
1207
+ url.searchParams.set('page', newPage);
1208
+ history.pushState({ type: 'pagination', form: form.getAttribute('id'), page: newPage }, '', url);
1209
+ }
1210
+
1211
+ // scroll back to the top of the table
1212
+ if (!component.hasAttribute('data-no-scroll')) {
1213
+ const yOffset = -250;
1214
+ const y = table.getBoundingClientRect().top + window.pageYOffset + yOffset;
1215
+ window.scrollTo({ top: y, behavior: 'smooth' });
977
1216
  }
1217
+ });
1218
+
1219
+ pagination.addEventListener('update-show', (event) => {
1220
+ const showInput = form.querySelector('[data-show]');
1221
+ const showRows = event.detail.show;
1222
+ showInput.value = showRows;
1223
+ component.setAttribute('data-show', showRows);
1224
+ form.dispatchEvent(new Event('submit'));
1225
+ });
978
1226
  };
1227
+ */