@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.
- 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 +35 -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 +543 -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 +128 -0
- package/assets/sass/components/table-basic.global.scss +355 -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 +48 -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 +655 -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,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
|
-
//
|
|
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
|
-
'
|
|
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
|
|
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'))
|
|
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 && !
|
|
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
|
-
|
|
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 (!
|
|
449
|
+
if (!component.hasAttribute('data-submit')) {
|
|
450
|
+
// TODO
|
|
134
451
|
sortTableByValues(table, sortBy, order);
|
|
135
452
|
}
|
|
136
453
|
}
|
|
137
454
|
});
|
|
138
455
|
};
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const
|
|
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
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
}
|
|
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
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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 (
|
|
222
|
-
|
|
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="${
|
|
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,
|
|
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
|
|
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
|
-
|
|
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 (
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
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
|
|
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 (
|
|
644
|
-
numberOfMatchedRows =
|
|
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
|
-
//
|
|
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;
|
|
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
|
-
|
|
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',
|
|
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
|
-
|
|
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);
|
|
1016
|
+
if (actionbar) {
|
|
1017
|
+
actionbar.addEventListener('change', (event) => {
|
|
1018
|
+
loadAjaxTable(component, table, form, pagination);
|
|
1019
|
+
});
|
|
780
1020
|
}
|
|
781
1021
|
};
|
|
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) {
|
|
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
|
-
|
|
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 =
|
|
871
|
-
?
|
|
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
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
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
|
-
|
|
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
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
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
|
+
*/
|