@iamproperty/components 4.1.0-beta-2 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/assets/css/components/accordion.css.map +1 -1
  2. package/assets/css/components/actionbar-global.css +1 -1
  3. package/assets/css/components/actionbar-global.css.map +1 -1
  4. package/assets/css/components/address-lookup.css +1 -0
  5. package/assets/css/components/address-lookup.css.map +1 -0
  6. package/assets/css/components/admin-panel.css +1 -1
  7. package/assets/css/components/admin-panel.css.map +1 -1
  8. package/assets/css/components/dialog.css +1 -1
  9. package/assets/css/components/dialog.css.map +1 -1
  10. package/assets/css/components/fileupload.css +1 -1
  11. package/assets/css/components/fileupload.css.map +1 -1
  12. package/assets/css/components/forms.css +1 -1
  13. package/assets/css/components/forms.css.map +1 -1
  14. package/assets/css/components/header.css +1 -1
  15. package/assets/css/components/header.css.map +1 -1
  16. package/assets/css/components/lists.css +1 -1
  17. package/assets/css/components/lists.css.map +1 -1
  18. package/assets/css/components/nav-global.css +1 -1
  19. package/assets/css/components/nav-global.css.map +1 -1
  20. package/assets/css/components/nav.css +1 -1
  21. package/assets/css/components/nav.css.map +1 -1
  22. package/assets/css/components/nav.old.css +1 -1
  23. package/assets/css/components/nav.old.css.map +1 -1
  24. package/assets/css/components/notification.css +1 -1
  25. package/assets/css/components/notification.css.map +1 -1
  26. package/assets/css/components/pagination.css +1 -1
  27. package/assets/css/components/pagination.css.map +1 -1
  28. package/assets/css/components/property-searchbar.css +1 -1
  29. package/assets/css/components/property-searchbar.css.map +1 -1
  30. package/assets/css/components/table.css +1 -1
  31. package/assets/css/components/table.css.map +1 -1
  32. package/assets/css/components/table.extras.css +1 -0
  33. package/assets/css/components/table.extras.css.map +1 -0
  34. package/assets/css/components/table.global.css +1 -0
  35. package/assets/css/components/table.global.css.map +1 -0
  36. package/assets/css/components/tabs.css +1 -1
  37. package/assets/css/components/tabs.css.map +1 -1
  38. package/assets/css/core.min.css +1 -1
  39. package/assets/css/core.min.css.map +1 -1
  40. package/assets/css/style.min.css +1 -1
  41. package/assets/css/style.min.css.map +1 -1
  42. package/assets/js/components/accordion/accordion.component.min.js +1 -1
  43. package/assets/js/components/actionbar/actionbar.component.min.js +3 -3
  44. package/assets/js/components/actionbar/actionbar.component.min.js.map +1 -1
  45. package/assets/js/components/address-lookup/address-lookup.component.js +172 -0
  46. package/assets/js/components/address-lookup/address-lookup.component.min.js +36 -0
  47. package/assets/js/components/address-lookup/address-lookup.component.min.js.map +1 -0
  48. package/assets/js/components/applied-filters/applied-filters.component.min.js +2 -2
  49. package/assets/js/components/applied-filters/applied-filters.component.min.js.map +1 -1
  50. package/assets/js/components/card/card.component.min.js +1 -1
  51. package/assets/js/components/collapsible-side/collapsible-side.component.min.js +1 -1
  52. package/assets/js/components/filterlist/filterlist.component.min.js +1 -1
  53. package/assets/js/components/header/header.component.min.js +2 -2
  54. package/assets/js/components/nav/nav.component.min.js +2 -2
  55. package/assets/js/components/notification/notification.component.min.js +4 -4
  56. package/assets/js/components/notification/notification.component.min.js.map +1 -1
  57. package/assets/js/components/pagination/pagination.component.js +152 -7
  58. package/assets/js/components/pagination/pagination.component.min.js +38 -12
  59. package/assets/js/components/pagination/pagination.component.min.js.map +1 -1
  60. package/assets/js/components/table/table.component.js +95 -69
  61. package/assets/js/components/table/table.component.min.js +9 -13
  62. package/assets/js/components/table/table.component.min.js.map +1 -1
  63. package/assets/js/components/tabs/tabs.component.js +3 -1
  64. package/assets/js/components/tabs/tabs.component.min.js +7 -5
  65. package/assets/js/components/tabs/tabs.component.min.js.map +1 -1
  66. package/assets/js/dynamic.min.js +5 -5
  67. package/assets/js/dynamic.min.js.map +1 -1
  68. package/assets/js/modules/applied-filters.js +3 -4
  69. package/assets/js/modules/dialogs.js +15 -3
  70. package/assets/js/modules/dynamicEvents.js +116 -0
  71. package/assets/js/modules/helpers.js +9 -0
  72. package/assets/js/modules/pagination.js +7 -10
  73. package/assets/js/modules/table.js +51 -52
  74. package/assets/js/modules/tabs.js +10 -1
  75. package/assets/js/scripts.bundle.js +53 -25
  76. package/assets/js/scripts.bundle.js.map +1 -1
  77. package/assets/js/scripts.bundle.min.js +2 -2
  78. package/assets/js/scripts.bundle.min.js.map +1 -1
  79. package/assets/js/tests/table.spec.js +0 -57
  80. package/assets/sass/_components.scss +2 -0
  81. package/assets/sass/_corefiles.scss +6 -2
  82. package/assets/sass/_functions/variables.scss +5 -1
  83. package/assets/sass/components/actionbar-global.scss +11 -2
  84. package/assets/sass/components/address-lookup.scss +22 -0
  85. package/assets/sass/components/admin-panel.scss +4 -0
  86. package/assets/sass/components/dialog.scss +22 -13
  87. package/assets/sass/components/fileupload.scss +2 -0
  88. package/assets/sass/components/forms.scss +231 -71
  89. package/assets/sass/components/lists.scss +119 -1
  90. package/assets/sass/components/nav-global.scss +1 -0
  91. package/assets/sass/components/notification.scss +6 -1
  92. package/assets/sass/components/pagination.scss +192 -100
  93. package/assets/sass/components/table.extras.scss +650 -0
  94. package/assets/sass/components/table.global.scss +103 -0
  95. package/assets/sass/components/table.scss +41 -565
  96. package/assets/sass/components/tabs.scss +95 -32
  97. package/assets/sass/foundations/brand.scss +4 -0
  98. package/assets/sass/foundations/buttons.scss +14 -12
  99. package/assets/sass/foundations/links.scss +2 -1
  100. package/assets/sass/helpers/dynamic.scss +3 -0
  101. package/assets/sass/templates/form.scss +84 -0
  102. package/assets/svg/logo.svg +7 -0
  103. package/assets/ts/components/address-lookup/address-lookup.component.ts +215 -0
  104. package/assets/ts/components/pagination/README.md +11 -0
  105. package/assets/ts/components/pagination/pagination.component.ts +182 -8
  106. package/assets/ts/components/table/README.md +4 -2
  107. package/assets/ts/components/table/table.component.ts +134 -83
  108. package/assets/ts/components/tabs/README.md +6 -5
  109. package/assets/ts/components/tabs/tabs.component.ts +3 -1
  110. package/assets/ts/modules/applied-filters.ts +5 -8
  111. package/assets/ts/modules/dialogs.ts +19 -4
  112. package/assets/ts/modules/dynamicEvents.ts +145 -0
  113. package/assets/ts/modules/helpers.ts +16 -1
  114. package/assets/ts/modules/pagination.ts +7 -10
  115. package/assets/ts/modules/table.ts +70 -57
  116. package/assets/ts/modules/tabs.ts +21 -10
  117. package/assets/ts/tests/table.spec.ts +1 -61
  118. package/dist/components.es.js +1123 -1008
  119. package/dist/components.umd.js +165 -80
  120. package/dist/style.css +1 -1
  121. package/package.json +3 -2
  122. package/src/components/AddressLookup/AddressLookup.vue +27 -0
  123. package/src/components/Pagination/README.md +11 -0
  124. package/src/components/Table/README.md +4 -3
  125. package/src/components/Table/Table.vue +4 -0
  126. package/src/components/Tabs/README.md +10 -7
  127. package/src/components/Tabs/Tab.vue +7 -8
  128. package/src/components/Tabs/Tabs.vue +0 -1
  129. package/src/index.js +1 -0
  130. package/assets/js/tests/pagination.spec.js +0 -15
  131. package/assets/ts/tests/pagination.spec.ts +0 -21
@@ -192,6 +192,7 @@ export const createDialog = (dialog) => {
192
192
  export const createMultiFormDialog = (dialog) => {
193
193
  let buttons = "";
194
194
  let fieldsets = Array.from(dialog.querySelectorAll('fieldset[data-title]'));
195
+ let form = dialog.querySelector('form');
195
196
  fieldsets.forEach((fieldset, index) => {
196
197
  buttons += `<button data-title="${fieldset.getAttribute('data-title')}" type="button" class="${index == 0 ? "active" : ""}" tabindex="-1">${fieldset.getAttribute('data-title')}</button>`;
197
198
  const btnWrapper = document.createElement("div");
@@ -201,8 +202,16 @@ export const createMultiFormDialog = (dialog) => {
201
202
  btnWrapper.innerHTML += `<button data-title="${fieldsets[index - 1].getAttribute('data-title')}" class="btn btn-secondary mb-0" data-previous type="button">Previous</button>`;
202
203
  if (index != fieldsets.length - 1)
203
204
  btnWrapper.innerHTML += `<button data-title="${fieldsets[index + 1].getAttribute('data-title')}" class="btn btn-primary mb-0" data-next type="button">Next</button>`;
204
- if (index == fieldsets.length - 1)
205
- btnWrapper.innerHTML += `<button data-title="${fieldsets[index].getAttribute('data-title')}" class="btn btn-primary mb-0" data-next type="submit">Submit</button>`;
205
+ // Last fieldset
206
+ if (index == fieldsets.length - 1) {
207
+ if (form && form.querySelector(':scope > button[type="submit"]')) {
208
+ let existingButton = form.querySelector(':scope > button[type="submit"]');
209
+ existingButton.classList.add('mb-0');
210
+ btnWrapper.insertAdjacentElement('beforeend', existingButton);
211
+ }
212
+ else
213
+ btnWrapper.innerHTML += `<button data-title="${fieldsets[index].getAttribute('data-title')}" class="btn btn-primary mb-0" data-next type="submit">Submit</button>`;
214
+ }
206
215
  });
207
216
  dialog.insertAdjacentHTML('afterbegin', `<div class="steps bg-primary">${buttons}</div>`);
208
217
  // Open the fieldset with an error inside
@@ -270,7 +279,7 @@ export const createMultiFormDialog = (dialog) => {
270
279
  dialog.addEventListener('keydown', (event) => {
271
280
  if (event && event.target instanceof HTMLElement && event.target.closest('button')) {
272
281
  const button = event.target.closest('button');
273
- if (event.keyCode == 13) {
282
+ if (event.keyCode == 13 && button.getAttribute('type') != "submit") {
274
283
  event.preventDefault();
275
284
  validateFieldset(button);
276
285
  }
@@ -278,6 +287,9 @@ export const createMultiFormDialog = (dialog) => {
278
287
  if (event && event.target instanceof HTMLElement && event.target.closest('input')) {
279
288
  const input = event.target.closest('input');
280
289
  input.classList.remove('is-invalid');
290
+ if (event.keyCode == 13) {
291
+ event.preventDefault();
292
+ }
281
293
  }
282
294
  });
283
295
  dialog.addEventListener('click', (event) => {
@@ -0,0 +1,116 @@
1
+ // @ts-nocheck
2
+ // Create the event listeners
3
+ const createDynamicEvents = () => {
4
+ // Change event
5
+ document.addEventListener('change', (event) => {
6
+ if (event && event.target instanceof HTMLElement && event.target.closest('[data-change-events]'))
7
+ readMatches(event.target, event.target.closest('[data-change-events]').getAttribute('data-change-events'));
8
+ });
9
+ document.addEventListener('change', (event) => {
10
+ if (event && event.target instanceof HTMLElement && event.target.closest('[data-change-events]'))
11
+ readMatches(event.target, event.target.closest('[data-change-events]').getAttribute('data-change-events'));
12
+ });
13
+ document.addEventListener('keyup', (event) => {
14
+ if (event && event.target instanceof HTMLElement && event.target.closest('[data-change-events]'))
15
+ readMatches(event.target, event.target.closest('[data-change-events]').getAttribute('data-change-events'));
16
+ });
17
+ // Click event
18
+ document.addEventListener('click', (event) => {
19
+ if (event && event.target instanceof HTMLElement && event.target.closest('[data-click-events]'))
20
+ readMatches(event.target, event.target.closest('[data-click-events]').getAttribute('data-click-events'));
21
+ });
22
+ };
23
+ // Parse the JSON and trigger the events, this may be singular or multiple set of events
24
+ const readMatches = (element, events) => {
25
+ // an empty events will trigger looking up the dom chain for
26
+ if (!events) {
27
+ events = element.parentNode.getAttribute('data-change-events');
28
+ }
29
+ // If still empty bail out
30
+ if (!events)
31
+ return false;
32
+ // Split out each event
33
+ Array.from(JSON.parse(events)).forEach((event, index) => {
34
+ checkMatch(element, event);
35
+ });
36
+ };
37
+ const checkMatch = (element, event) => {
38
+ if ("matches" in event) {
39
+ if (event['matches'] == 'any')
40
+ runEvent(element, event, 'if');
41
+ else if (element.value == event.matches)
42
+ runEvent(element, event, 'if');
43
+ else
44
+ runEvent(element, event, 'else');
45
+ return false;
46
+ }
47
+ else if ("in-list" in event) {
48
+ if (document.querySelector(`${event['in-list']} option[value="${element.value}"]`)) {
49
+ let match = document.querySelector(`${event['in-list']} option[value="${element.value}"]`);
50
+ runEvent(element, event, 'if', match);
51
+ }
52
+ else
53
+ runEvent(element, event, 'else');
54
+ return false;
55
+ }
56
+ else if ("event" in event) {
57
+ runEvent(element, event, 'event');
58
+ }
59
+ };
60
+ const runEvent = (element, event, eventType, match) => {
61
+ if (eventType in event == false)
62
+ return false;
63
+ switch (event[eventType]) {
64
+ case "hide":
65
+ let hideElement = document.querySelector(event['target']);
66
+ hideElement.classList.add('js-hide');
67
+ Array.from(hideElement.querySelectorAll('[data-required]')).forEach((input, index) => {
68
+ input.removeAttribute('required');
69
+ });
70
+ break;
71
+ case "show":
72
+ let showElement = document.querySelector(event['target']);
73
+ showElement.classList.remove('js-hide');
74
+ Array.from(showElement.querySelectorAll('[data-required]')).forEach((input, index) => {
75
+ if (!input.closest('.js-hide'))
76
+ input.setAttribute('required', 'true');
77
+ });
78
+ break;
79
+ case "populate-form":
80
+ populateForm(element, event, match);
81
+ break;
82
+ case "setAttribute":
83
+ document.querySelector(`${event['target']}`).setAttribute(event['attribute'], event['value']);
84
+ break;
85
+ case "removeAttribute":
86
+ document.querySelector(`${event['target']}`).removeAttribute(event['attribute']);
87
+ break;
88
+ case "updateValue":
89
+ document.querySelector(`${event['target']}`).value = event['value'] ? event['value'] : "";
90
+ let changeEvent = new Event('change');
91
+ document.querySelector(`${event['target']}`).dispatchEvent(changeEvent);
92
+ break;
93
+ default:
94
+ break;
95
+ }
96
+ };
97
+ const populateForm = function (element, event, match) {
98
+ let response = JSON.parse(match.getAttribute('data-values'));
99
+ let form = document.querySelector(event['target']);
100
+ Object.keys(response).forEach((field, index) => {
101
+ if (document.getElementById(field) && document.getElementById(field).tagName == "SPAN")
102
+ document.getElementById(field).innerHTML = response[field];
103
+ if (form.querySelector(`input[name="${field}"][type="radio"][value="${response[field]}"]`)) {
104
+ Array.from(form.querySelectorAll(`input[name="${field}"][type="radio"]`)).forEach(function (input, index) {
105
+ input.disabled = true;
106
+ });
107
+ form.querySelector(`input[name="${field}"][type="radio"][value="${response[field]}"]`).checked = true;
108
+ form.querySelector(`input[name="${field}"][type="radio"][value="${response[field]}"]`).disabled = false;
109
+ }
110
+ else if (form.querySelector(`input[name="${field}"]`)) {
111
+ form.querySelector(`input[name="${field}"]`).value = response[field];
112
+ form.querySelector(`input[name="${field}"]`).setAttribute('readonly', 'true');
113
+ }
114
+ });
115
+ };
116
+ export default createDynamicEvents;
@@ -44,6 +44,15 @@ export const addGlobalEvents = (body) => {
44
44
  form.dispatchEvent(new Event("submit"));
45
45
  }
46
46
  });
47
+ document.addEventListener("submit", (event) => {
48
+ if (event && event.target instanceof HTMLElement && event.target.matches('form')) {
49
+ let form = event.target;
50
+ if (form.querySelector(':invalid')) {
51
+ form.classList.add('was-validated');
52
+ event.preventDefault();
53
+ }
54
+ }
55
+ });
47
56
  return null;
48
57
  };
49
58
  export const isNumeric = function (str) {
@@ -12,18 +12,15 @@ const createPaginationButttons = function (controller, pagination) {
12
12
  pagination.innerHTML = '';
13
13
  return false;
14
14
  }
15
- let strButtons = '';
15
+ let strOptions = '';
16
16
  for (let i = 1; i <= numberPages; i++) {
17
- if (i == currentPage)
18
- strButtons += `<li class="page-item active" aria-current="page"><span class="page-link">${i}</span></li>`;
19
- else
20
- strButtons += `<li class="page-item"><a href="?page=${i}" class="page-link" data-page="${i}">${i}</a></li>`;
17
+ strOptions += `<option value="${i}" ${i == currentPage ? 'selected' : ''}>${i}</option>`;
21
18
  }
22
- pagination.innerHTML = `<ul class="pagination mb-0 d-none d-sm-flex">
23
- ${currentPage == 1 ? `<li class="page-item disabled"><span class="page-link">Previous</span></li>` : `<li class="page-item"><a href="?page=${parseInt(currentPage) - 1}" class="page-link" data-page="${parseInt(currentPage) - 1}">Previous</a></li>`}
24
- ${strButtons}
25
- ${currentPage == numberPages ? `<li class="page-item disabled"><span class="page-link">Next</span></li>` : `<li class="page-item"><a href="?page=${parseInt(currentPage) + 1}" class="page-link" data-page="${parseInt(currentPage) + 1}">Next</a></li>`}
26
- </ul>`;
19
+ pagination.innerHTML = `<div class="pagination mb-0 d-none d-sm-flex">
20
+ <div><select>${strOptions}</select></div>
21
+ <button class="prev" ${currentPage == 1 ? 'disabled' : ''} data-page="${parseInt(currentPage) - 1}">Previous</button>
22
+ <button class="next" ${currentPage == numberPages ? 'disabled' : ''} data-page="${parseInt(currentPage) + 1}">Next</button>
23
+ </div>`;
27
24
  pagination.innerHTML += `<div class="d-sm-none text-center">
28
25
  <span class="d-block pb-2">You've viewed ${showRows} of ${numberRows} results</span>
29
26
  <a href="?show=${parseInt(showRows) + parseInt(addRows)}" class="btn btn-primary w-100 m-0" data-show="${parseInt(showRows) + parseInt(addRows)}">Load more results</a>
@@ -9,7 +9,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  };
10
10
  // @ts-nocheck
11
11
  import { zeroPad, isNumeric, ucfirst } from "./helpers.js";
12
- import createPaginationButttons from "./pagination.js";
13
12
  // Basic functionality needed
14
13
  export const addDataAttributes = (table) => {
15
14
  const colHeadings = Array.from(table.querySelectorAll('thead th'));
@@ -51,33 +50,28 @@ export const getLargestLastColWidth = (table) => {
51
50
  });
52
51
  return largestWidth;
53
52
  };
54
- export const createMobileButton = (table) => {
55
- if (table.closest('.table--fullwidth'))
53
+ export const createMobileButton = (table, wrapper) => {
54
+ if (wrapper.classList.contains('.table--fullwidth') && !wrapper.hasAttribute('data-expandable'))
56
55
  return false;
57
- if (table.querySelectorAll('thead tr th').length < 4)
56
+ if (table.querySelectorAll('thead tr th').length < 4 && !wrapper.hasAttribute('data-expandable'))
58
57
  return false;
58
+ Array.from(table.querySelectorAll('thead tr')).forEach((row, index) => {
59
+ row.insertAdjacentHTML('afterbegin', `<th class="th--fixed expand-button-heading"></th>`);
60
+ });
59
61
  Array.from(table.querySelectorAll('tbody tr')).forEach((row, index) => {
60
- let firstCol = row.querySelector(':scope > :is(td,th):first-child');
61
- let colContent = firstCol.textContent;
62
- if (colContent != "")
63
- firstCol.innerHTML = `<span class="td__content">${colContent}</span><button type="button" class="d-none">${colContent}</button>`;
64
- else {
65
- let secondCol = row.querySelector(':scope > :is(td,th):nth-child(2)');
66
- let secondColContent = secondCol.textContent;
67
- secondCol.innerHTML = `<span class="td__content">${secondColContent}</span><button type="button" class="d-none">${secondColContent}</button>`;
68
- }
62
+ row.insertAdjacentHTML('afterbegin', `<td class="td--fixed td--expand"><button class="btn btn-compact btn-secondary" data-expand-button>Expand</button></td>`);
69
63
  });
70
64
  };
71
65
  export const addTableEventListeners = (table) => {
72
66
  table.addEventListener('click', (event) => {
73
- if (event && event.target instanceof HTMLElement && event.target.closest('tr > :is(td,th):first-child button')) {
74
- let firstCol = event.target.closest('tr > :is(td,th):first-child button');
75
- let tableRow = firstCol.parentNode.closest('tr');
67
+ if (event && event.target instanceof HTMLElement && event.target.closest('[data-expand-button]')) {
68
+ let button = event.target.closest('[data-expand-button]');
69
+ let tableRow = button.closest('tr');
76
70
  if (tableRow.getAttribute('data-view') == "full")
77
71
  tableRow.setAttribute('data-view', 'default');
78
72
  else
79
73
  tableRow.setAttribute('data-view', 'full');
80
- firstCol.blur();
74
+ button.blur();
81
75
  }
82
76
  ;
83
77
  });
@@ -143,7 +137,6 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
143
137
  form.submit();
144
138
  else {
145
139
  filterTable(table, form, wrapper);
146
- createPaginationButttons(wrapper, pagination);
147
140
  populateDataQueries(table, form);
148
141
  }
149
142
  // Pass post data back to the page
@@ -176,7 +169,6 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
176
169
  }
177
170
  if (event && event.target instanceof HTMLElement && event.target.closest('[data-filter][data-no-ajax]')) { // Allow for input fields to filter the current results without a new ajax call
178
171
  filterTable(table, form, wrapper);
179
- createPaginationButttons(wrapper, pagination);
180
172
  populateDataQueries(table, form);
181
173
  }
182
174
  else if (event && event.target instanceof HTMLElement && event.target.closest('[data-filter]') && event.target.closest('form .dialog__wrapper > dialog')) {
@@ -223,7 +215,15 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
223
215
  case "radio":
224
216
  case "checkbox":
225
217
  if (frm_elements[i].checked) {
226
- frm_elements[i].checked = false;
218
+ let input = frm_elements[i];
219
+ let id = input.getAttribute('id');
220
+ let label = document.querySelector(`[for="${id}"`);
221
+ if (label.querySelector('iam-card')) {
222
+ let card = label.querySelector('iam-card');
223
+ let clickEvent = new Event('click');
224
+ card.dispatchEvent(clickEvent);
225
+ }
226
+ input.checked = false;
227
227
  }
228
228
  break;
229
229
  case "select-one":
@@ -235,10 +235,6 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
235
235
  break;
236
236
  }
237
237
  }
238
- Array.from(form.querySelectorAll('label iam-card')).forEach((card, index) => {
239
- let clickEvent = new Event('click');
240
- card.dispatchEvent(clickEvent);
241
- });
242
238
  form.classList.remove('processing');
243
239
  if (!form.hasAttribute('data-submit'))
244
240
  sortTable(table, form, savedTableBody);
@@ -486,10 +482,9 @@ export const filterTable = (table, form, wrapper) => {
486
482
  row.classList.add('filtered--show');
487
483
  });
488
484
  if (wrapper) {
489
- wrapper.setAttribute('data-page', page);
490
- wrapper.setAttribute('data-pages', Math.ceil(matched / showRows));
491
485
  wrapper.setAttribute('data-total', matched);
492
486
  wrapper.setAttribute('data-show', showRows);
487
+ wrapper.setAttribute('data-page', page);
493
488
  }
494
489
  };
495
490
  export const populateDataQueries = (table, form, wrapper) => {
@@ -540,32 +535,32 @@ export const populateDataQueries = (table, form, wrapper) => {
540
535
  };
541
536
  // Pagination
542
537
  export const addPaginationEventListeners = function (table, form, pagination, wrapper) {
543
- pagination.addEventListener('click', (event) => {
544
- if (event && event.target instanceof HTMLElement && event.target.closest('[data-page]')) {
545
- event.preventDefault();
546
- let paginationInput = form.querySelector('[data-pagination]');
547
- let newPage = event.target.closest('[data-page]').getAttribute('data-page');
548
- paginationInput.value = newPage;
549
- wrapper.setAttribute('data-page', newPage);
550
- form.dispatchEvent(new Event("paginate"));
551
- if (table.hasAttribute('data-show-history')) {
552
- const url = new URL(location);
553
- url.searchParams.set("page", newPage);
554
- history.pushState({ 'type': 'pagination', 'form': form.getAttribute('id'), 'page': newPage }, "", url);
555
- }
556
- // scroll back to the top of the table
538
+ pagination.addEventListener('update-page', (event) => {
539
+ let paginationInput = form.querySelector('[data-pagination]');
540
+ let newPage = event.detail.page;
541
+ // Set the filter value
542
+ paginationInput.value = newPage;
543
+ form.dispatchEvent(new Event("paginate"));
544
+ // Reset the data attribute
545
+ wrapper.setAttribute('data-page', newPage);
546
+ if (table.hasAttribute('data-show-history')) {
547
+ const url = new URL(location);
548
+ url.searchParams.set("page", newPage);
549
+ history.pushState({ 'type': 'pagination', 'form': form.getAttribute('id'), 'page': newPage }, "", url);
550
+ }
551
+ // scroll back to the top of the table
552
+ if (!wrapper.hasAttribute('data-no-scroll')) {
557
553
  const yOffset = -250;
558
554
  const y = table.getBoundingClientRect().top + window.pageYOffset + yOffset;
559
555
  window.scrollTo({ top: y, behavior: 'smooth' });
560
556
  }
561
- if (event && event.target instanceof HTMLElement && event.target.closest('[data-show]')) {
562
- event.preventDefault();
563
- let showInput = form.querySelector('[data-show]');
564
- let showRows = event.target.closest('[data-show]').getAttribute('data-show');
565
- showInput.value = showRows;
566
- wrapper.setAttribute('data-show', showRows);
567
- form.dispatchEvent(new Event("submit"));
568
- }
557
+ });
558
+ pagination.addEventListener('update-show', (event) => {
559
+ let showInput = form.querySelector('[data-show]');
560
+ let showRows = event.detail.show;
561
+ showInput.value = showRows;
562
+ wrapper.setAttribute('data-show', showRows);
563
+ form.dispatchEvent(new Event("submit"));
569
564
  });
570
565
  };
571
566
  // Export CSV Data
@@ -613,7 +608,7 @@ export const exportAsCSV = function (table) {
613
608
  // After table is loaded
614
609
  export const makeTableFunctional = function (table, form, pagination, wrapper) {
615
610
  addDataAttributes(table);
616
- createMobileButton(table);
611
+ createMobileButton(table, wrapper);
617
612
  populateDataQueries(table, form, wrapper);
618
613
  // Work out the largest width of the CTA's in the last column
619
614
  if (wrapper && wrapper.classList.contains('table--cta')) {
@@ -686,6 +681,9 @@ export const loadAjaxTable = function (table, form, pagination, wrapper) {
686
681
  // Create a new controller so it can be aborted if new fetch made
687
682
  window.controller[ajaxURL] = new AbortController();
688
683
  const { signal } = controller[ajaxURL];
684
+ // Set loading on the pagination
685
+ pagination.setAttribute('data-loading', 'true');
686
+ form.classList.add('processing');
689
687
  try {
690
688
  yield fetch(ajaxURL + '?' + queryString, {
691
689
  signal: signal,
@@ -701,7 +699,7 @@ export const loadAjaxTable = function (table, form, pagination, wrapper) {
701
699
  let schema = form.hasAttribute('data-schema') ? form.getAttribute('data-schema') : 'data';
702
700
  let totalNumberSchema = form.hasAttribute('data-schema-total') ? form.getAttribute('data-schema-total') : 'meta.total';
703
701
  let currentPageSchema = form.hasAttribute('data-schema-page') ? form.getAttribute('data-schema-page') : 'meta.current_page';
704
- let totalNumber = resolvePath(response, totalNumberSchema, 1);
702
+ let totalNumber = resolvePath(response, totalNumberSchema, 15);
705
703
  let currentPage = resolvePath(response, currentPageSchema, 1);
706
704
  let data = resolvePath(response, schema);
707
705
  let emptyMsg = wrapper.hasAttribute('data-empty-msg') ? wrapper.getAttribute('data-empty-msg') : "No results found";
@@ -753,9 +751,7 @@ export const loadAjaxTable = function (table, form, pagination, wrapper) {
753
751
  // Add data to the pagination
754
752
  wrapper.setAttribute('data-total', parseInt(totalNumber));
755
753
  wrapper.setAttribute('data-page', parseInt(currentPage));
756
- wrapper.setAttribute('data-pages', Math.ceil(wrapper.getAttribute('data-total') / wrapper.getAttribute('data-show')));
757
754
  makeTableFunctional(table, form, pagination, wrapper);
758
- createPaginationButttons(wrapper, pagination);
759
755
  Array.from(form.querySelectorAll('[data-ajax-query]')).forEach((queryElement, index) => {
760
756
  let totalNumber = resolvePath(response, queryElement.getAttribute('data-ajax-query'), '');
761
757
  if (queryElement.hasAttribute('data-total'))
@@ -777,6 +773,9 @@ export const loadAjaxTable = function (table, form, pagination, wrapper) {
777
773
  else {
778
774
  tbody.innerHTML = '<tr><td colspan="100%"><span>Error loading table</span></td></tr>';
779
775
  }
776
+ // Remove loading on the pagination
777
+ pagination.removeAttribute('data-loading');
778
+ form.classList.remove('processing');
780
779
  });
781
780
  }
782
781
  catch (error) {
@@ -8,11 +8,15 @@ export const createTabsLinks = function (tabsElement) {
8
8
  if (!tabLinks) {
9
9
  tabLinks = document.createElement('div');
10
10
  tabLinks.classList.add('tabs__links');
11
- tabsElement.prepend(tabLinks);
11
+ let tabLinksWrapper = document.createElement('div');
12
+ tabLinksWrapper.classList.add('tabs__links__wrapper');
13
+ tabLinksWrapper.prepend(tabLinks);
14
+ tabsElement.prepend(tabLinksWrapper);
12
15
  }
13
16
  // Create the tab buttons from the summary titles
14
17
  details.forEach((detail, index) => {
15
18
  let summary = detail.querySelector(':scope > summary');
19
+ let isDisabled = summary.classList.contains('disabled');
16
20
  summary.classList.add('visually-hidden');
17
21
  let button = document.createElement('button');
18
22
  if (detail.hasAttribute('id')) {
@@ -26,6 +30,9 @@ export const createTabsLinks = function (tabsElement) {
26
30
  button.classList.add('link');
27
31
  button.setAttribute('data-index', index);
28
32
  button.setAttribute('tabindex', '-1');
33
+ if (isDisabled) {
34
+ button.classList.add('disabled');
35
+ }
29
36
  tabLinks.appendChild(button);
30
37
  });
31
38
  };
@@ -39,6 +46,8 @@ export const setTabsEventHandlers = function (tabsElement) {
39
46
  buttons.forEach((button) => {
40
47
  button.addEventListener("click", (e) => {
41
48
  e.preventDefault();
49
+ if (button.classList.contains('disabled'))
50
+ return false;
42
51
  buttons.forEach((buttonLoopItem) => {
43
52
  let buttonPressed = buttonLoopItem == button ? true : false;
44
53
  buttonLoopItem.setAttribute('aria-pressed', buttonPressed);