@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.
- package/assets/css/components/actionbar.component.css +1 -1
- package/assets/css/components/actionbar.component.css.map +1 -1
- package/assets/css/components/actionbar.global.css +1 -1
- package/assets/css/components/actionbar.global.css.map +1 -1
- package/assets/css/components/barchart.component.css +1 -1
- package/assets/css/components/barchart.component.css.map +1 -1
- package/assets/css/components/card.component.css +1 -1
- package/assets/css/components/card.component.css.map +1 -1
- package/assets/css/components/carousel.component.css +1 -1
- package/assets/css/components/carousel.component.css.map +1 -1
- package/assets/css/components/doughnutchart.component.css +1 -1
- package/assets/css/components/doughnutchart.component.css.map +1 -1
- package/assets/css/components/pagination.css +1 -1
- package/assets/css/components/pagination.css.map +1 -1
- package/assets/css/components/table-basic.component.css +1 -0
- package/assets/css/components/table-basic.component.css.map +1 -0
- package/assets/css/components/table-basic.global.css +1 -0
- package/assets/css/components/table-basic.global.css.map +1 -0
- package/assets/css/components/table.component.css +1 -1
- package/assets/css/components/table.component.css.map +1 -1
- package/assets/css/components/table.global.css +1 -1
- package/assets/css/components/table.global.css.map +1 -1
- package/assets/css/components/tabs.config.css +1 -0
- package/assets/css/components/tabs.config.css.map +1 -0
- package/assets/css/components/tabs.css +1 -1
- package/assets/css/components/tabs.css.map +1 -1
- package/assets/css/core.min.css +1 -1
- package/assets/css/core.min.css.map +1 -1
- package/assets/css/mobile-core.min.css +1 -1
- package/assets/css/mobile-core.min.css.map +1 -1
- package/assets/css/mobile.min.css +1 -1
- package/assets/css/mobile.min.css.map +1 -1
- package/assets/css/style.min.css +1 -1
- package/assets/css/style.min.css.map +1 -1
- package/assets/js/components/accordion/accordion.component.min.js +1 -1
- package/assets/js/components/actionbar/actionbar.component.min.js +4 -4
- package/assets/js/components/address-lookup/address-lookup.component.min.js +1 -1
- package/assets/js/components/applied-filters/applied-filters.component.min.js +1 -1
- package/assets/js/components/barchart/barchart.component.min.js +2 -2
- package/assets/js/components/barchart/barchart.component.min.js.map +1 -1
- package/assets/js/components/bento-grid/bento-grid.component.min.js +1 -1
- package/assets/js/components/card/card.component.min.js +2 -2
- package/assets/js/components/carousel/carousel.component.min.js +2 -2
- package/assets/js/components/collapsible-side/collapsible-side.component.min.js +1 -1
- package/assets/js/components/doughnutchart/doughnutchart.component.min.js +2 -2
- package/assets/js/components/doughnutchart/doughnutchart.component.min.js.map +1 -1
- package/assets/js/components/fileupload/fileupload.component.min.js +1 -1
- package/assets/js/components/filter-card/filter-card.component.min.js +1 -1
- package/assets/js/components/filterlist/filterlist.component.min.js +1 -1
- package/assets/js/components/header/header.component.min.js +1 -1
- package/assets/js/components/inline-edit/inline-edit.component.min.js +1 -1
- package/assets/js/components/marketing/marketing.component.min.js +1 -1
- package/assets/js/components/menu/menu.component.min.js +1 -1
- package/assets/js/components/multi-step/multi-step.component.min.js +1 -1
- package/assets/js/components/multiselect/multiselect.component.min.js +1 -1
- package/assets/js/components/nav/nav.component.min.js +1 -1
- package/assets/js/components/notification/notification.component.min.js +1 -1
- package/assets/js/components/pagination/pagination.component.js +11 -4
- package/assets/js/components/pagination/pagination.component.min.js +5 -5
- package/assets/js/components/pagination/pagination.component.min.js.map +1 -1
- package/assets/js/components/record-card/record-card.component.min.js +1 -1
- package/assets/js/components/search/search.component.min.js +1 -1
- package/assets/js/components/search/search.component.min.js.map +1 -1
- package/assets/js/components/slider/slider.component.min.js +1 -1
- package/assets/js/components/table/table.component.js +36 -198
- package/assets/js/components/table/table.component.min.js +13 -23
- package/assets/js/components/table/table.component.min.js.map +1 -1
- package/assets/js/components/table-ajax/table-ajax.component.js +46 -0
- package/assets/js/components/table-ajax/table-ajax.component.min.js +22 -0
- package/assets/js/components/table-ajax/table-ajax.component.min.js.map +1 -0
- package/assets/js/components/table-basic/table-basic.component.js +46 -0
- package/assets/js/components/table-basic/table-basic.component.min.js +22 -0
- package/assets/js/components/table-basic/table-basic.component.min.js.map +1 -0
- package/assets/js/components/table-no-submit/table-no-submit.component.js +77 -0
- package/assets/js/components/table-no-submit/table-no-submit.component.min.js +22 -0
- package/assets/js/components/table-no-submit/table-no-submit.component.min.js.map +1 -0
- package/assets/js/components/table-submit/table-submit.component.js +55 -0
- package/assets/js/components/table-submit/table-submit.component.min.js +22 -0
- package/assets/js/components/table-submit/table-submit.component.min.js.map +1 -0
- package/assets/js/components/tabs/tabs.component.js +2 -0
- package/assets/js/components/tabs/tabs.component.min.js +6 -4
- package/assets/js/components/tabs/tabs.component.min.js.map +1 -1
- package/assets/js/components/video-card/video-card.component.min.js +1 -1
- package/assets/js/modules/helpers.js +4 -0
- package/assets/js/modules/table.js +544 -294
- package/assets/js/modules/tabs.js +43 -13
- package/assets/js/scripts.bundle.js +3 -3
- package/assets/js/scripts.bundle.js.map +1 -1
- package/assets/js/scripts.bundle.min.js +2 -2
- package/assets/js/scripts.bundle.min.js.map +1 -1
- package/assets/js/scripts.js +31 -24
- package/assets/js/tests/table.spec.js +0 -31
- package/assets/sass/_components.scss +3 -0
- package/assets/sass/components/actionbar.component.scss +1 -0
- package/assets/sass/components/actionbar.global.scss +0 -70
- package/assets/sass/components/pagination.scss +2 -1
- package/assets/sass/components/table-basic.component.scss +132 -0
- package/assets/sass/components/table-basic.global.scss +365 -0
- package/assets/sass/components/table.component.scss +2 -133
- package/assets/sass/components/table.global.scss +175 -434
- package/assets/sass/components/tabs.config.scss +27 -0
- package/assets/sass/components/tabs.scss +33 -1
- package/assets/sass/elements/buttons--global.scss +2 -1
- package/assets/sass/elements/table.element.scss +9 -7
- package/assets/sass/foundations/root.scss +1 -1
- package/assets/ts/components/pagination/pagination.component.ts +17 -4
- package/assets/ts/components/table/table.component.ts +49 -243
- package/assets/ts/components/table-ajax/table-ajax.component.ts +64 -0
- package/assets/ts/components/table-basic/README.md +40 -0
- package/assets/ts/components/table-basic/table-basic.component.ts +56 -0
- package/assets/ts/components/table-no-submit/table-no-submit.component.ts +134 -0
- package/assets/ts/components/table-submit/table-submit.component.ts +64 -0
- package/assets/ts/components/tabs/tabs.component.ts +2 -0
- package/assets/ts/modules/helpers.ts +6 -0
- package/assets/ts/modules/table.ts +656 -328
- package/assets/ts/modules/tabs.ts +54 -12
- package/assets/ts/scripts.ts +5 -3
- package/assets/ts/tests/table.spec.ts +0 -38
- package/dist/components.es.js +138 -136
- package/dist/components.umd.js +108 -116
- package/package.json +1 -1
- package/src/components/Table/TableAjax.vue +34 -0
- package/src/components/Table/TableBasic.vue +34 -0
- package/src/components/Table/TableNoSubmit.vue +34 -0
- package/src/components/Table/TableSubmit.vue +34 -0
- 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
|
-
//
|
|
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
|
-
'
|
|
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
|
|
61
|
-
|
|
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 && !
|
|
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
|
-
|
|
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 (!
|
|
450
|
+
if (!component.hasAttribute('data-submit')) {
|
|
451
|
+
// TODO
|
|
134
452
|
sortTableByValues(table, sortBy, order);
|
|
135
453
|
}
|
|
136
454
|
}
|
|
137
455
|
});
|
|
138
456
|
};
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const
|
|
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
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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
|
|
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
|
-
|
|
197
|
-
|
|
198
|
-
|
|
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
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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 (
|
|
222
|
-
|
|
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="${
|
|
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,
|
|
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
|
|
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
|
-
|
|
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 (
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
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
|
|
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 (
|
|
644
|
-
numberOfMatchedRows =
|
|
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
|
-
//
|
|
689
|
-
export const
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
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
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
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
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
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
|
-
|
|
783
|
-
|
|
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
|
-
|
|
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 =
|
|
871
|
-
?
|
|
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
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
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
|
-
|
|
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
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
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
|
+
*/
|