@iamproperty/components 4.1.0-beta-2 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/css/components/accordion.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/address-lookup.css +1 -0
- package/assets/css/components/address-lookup.css.map +1 -0
- package/assets/css/components/admin-panel.css +1 -1
- package/assets/css/components/admin-panel.css.map +1 -1
- package/assets/css/components/dialog.css +1 -1
- package/assets/css/components/dialog.css.map +1 -1
- package/assets/css/components/fileupload.css +1 -1
- package/assets/css/components/fileupload.css.map +1 -1
- package/assets/css/components/forms.css +1 -1
- package/assets/css/components/forms.css.map +1 -1
- package/assets/css/components/header.css +1 -1
- package/assets/css/components/header.css.map +1 -1
- package/assets/css/components/lists.css +1 -1
- package/assets/css/components/lists.css.map +1 -1
- package/assets/css/components/nav-global.css +1 -1
- package/assets/css/components/nav-global.css.map +1 -1
- package/assets/css/components/nav.css +1 -1
- package/assets/css/components/nav.css.map +1 -1
- package/assets/css/components/nav.old.css +1 -1
- package/assets/css/components/nav.old.css.map +1 -1
- package/assets/css/components/notification.css +1 -1
- package/assets/css/components/notification.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/property-searchbar.css +1 -1
- package/assets/css/components/property-searchbar.css.map +1 -1
- package/assets/css/components/table.css +1 -1
- package/assets/css/components/table.css.map +1 -1
- package/assets/css/components/table.extras.css +1 -0
- package/assets/css/components/table.extras.css.map +1 -0
- package/assets/css/components/table.global.css +1 -0
- package/assets/css/components/table.global.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/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 +3 -3
- package/assets/js/components/actionbar/actionbar.component.min.js.map +1 -1
- package/assets/js/components/address-lookup/address-lookup.component.js +172 -0
- package/assets/js/components/address-lookup/address-lookup.component.min.js +36 -0
- package/assets/js/components/address-lookup/address-lookup.component.min.js.map +1 -0
- package/assets/js/components/applied-filters/applied-filters.component.min.js +2 -2
- package/assets/js/components/applied-filters/applied-filters.component.min.js.map +1 -1
- package/assets/js/components/card/card.component.min.js +1 -1
- package/assets/js/components/collapsible-side/collapsible-side.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 +2 -2
- package/assets/js/components/nav/nav.component.min.js +2 -2
- package/assets/js/components/notification/notification.component.min.js +4 -4
- package/assets/js/components/notification/notification.component.min.js.map +1 -1
- package/assets/js/components/pagination/pagination.component.js +152 -7
- package/assets/js/components/pagination/pagination.component.min.js +38 -12
- package/assets/js/components/pagination/pagination.component.min.js.map +1 -1
- package/assets/js/components/table/table.component.js +95 -69
- package/assets/js/components/table/table.component.min.js +9 -13
- package/assets/js/components/table/table.component.min.js.map +1 -1
- package/assets/js/components/tabs/tabs.component.js +3 -1
- package/assets/js/components/tabs/tabs.component.min.js +7 -5
- package/assets/js/components/tabs/tabs.component.min.js.map +1 -1
- package/assets/js/dynamic.min.js +5 -5
- package/assets/js/dynamic.min.js.map +1 -1
- package/assets/js/modules/applied-filters.js +3 -4
- package/assets/js/modules/dialogs.js +15 -3
- package/assets/js/modules/dynamicEvents.js +116 -0
- package/assets/js/modules/helpers.js +9 -0
- package/assets/js/modules/pagination.js +7 -10
- package/assets/js/modules/table.js +51 -52
- package/assets/js/modules/tabs.js +10 -1
- package/assets/js/scripts.bundle.js +53 -25
- 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/tests/table.spec.js +0 -57
- package/assets/sass/_components.scss +2 -0
- package/assets/sass/_corefiles.scss +6 -2
- package/assets/sass/_functions/variables.scss +5 -1
- package/assets/sass/components/actionbar-global.scss +11 -2
- package/assets/sass/components/address-lookup.scss +22 -0
- package/assets/sass/components/admin-panel.scss +4 -0
- package/assets/sass/components/dialog.scss +22 -13
- package/assets/sass/components/fileupload.scss +2 -0
- package/assets/sass/components/forms.scss +231 -71
- package/assets/sass/components/lists.scss +119 -1
- package/assets/sass/components/nav-global.scss +1 -0
- package/assets/sass/components/notification.scss +6 -1
- package/assets/sass/components/pagination.scss +192 -100
- package/assets/sass/components/table.extras.scss +650 -0
- package/assets/sass/components/table.global.scss +103 -0
- package/assets/sass/components/table.scss +41 -565
- package/assets/sass/components/tabs.scss +95 -32
- package/assets/sass/foundations/brand.scss +4 -0
- package/assets/sass/foundations/buttons.scss +14 -12
- package/assets/sass/foundations/links.scss +2 -1
- package/assets/sass/helpers/dynamic.scss +3 -0
- package/assets/sass/templates/form.scss +84 -0
- package/assets/svg/logo.svg +7 -0
- package/assets/ts/components/address-lookup/address-lookup.component.ts +215 -0
- package/assets/ts/components/pagination/README.md +11 -0
- package/assets/ts/components/pagination/pagination.component.ts +182 -8
- package/assets/ts/components/table/README.md +4 -2
- package/assets/ts/components/table/table.component.ts +134 -83
- package/assets/ts/components/tabs/README.md +6 -5
- package/assets/ts/components/tabs/tabs.component.ts +3 -1
- package/assets/ts/modules/applied-filters.ts +5 -8
- package/assets/ts/modules/dialogs.ts +19 -4
- package/assets/ts/modules/dynamicEvents.ts +145 -0
- package/assets/ts/modules/helpers.ts +16 -1
- package/assets/ts/modules/pagination.ts +7 -10
- package/assets/ts/modules/table.ts +70 -57
- package/assets/ts/modules/tabs.ts +21 -10
- package/assets/ts/tests/table.spec.ts +1 -61
- package/dist/components.es.js +1123 -1008
- package/dist/components.umd.js +165 -80
- package/dist/style.css +1 -1
- package/package.json +3 -2
- package/src/components/AddressLookup/AddressLookup.vue +27 -0
- package/src/components/Pagination/README.md +11 -0
- package/src/components/Table/README.md +4 -3
- package/src/components/Table/Table.vue +4 -0
- package/src/components/Tabs/README.md +10 -7
- package/src/components/Tabs/Tab.vue +7 -8
- package/src/components/Tabs/Tabs.vue +0 -1
- package/src/index.js +1 -0
- package/assets/js/tests/pagination.spec.js +0 -15
- package/assets/ts/tests/pagination.spec.ts +0 -21
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
|
|
3
|
+
// Create the event listeners
|
|
4
|
+
const createDynamicEvents = () => {
|
|
5
|
+
|
|
6
|
+
// Change event
|
|
7
|
+
document.addEventListener('change', (event) => {
|
|
8
|
+
if (event && event.target instanceof HTMLElement && event.target.closest('[data-change-events]'))
|
|
9
|
+
readMatches(event.target,event.target.closest('[data-change-events]').getAttribute('data-change-events'));
|
|
10
|
+
});
|
|
11
|
+
document.addEventListener('change', (event) => {
|
|
12
|
+
if (event && event.target instanceof HTMLElement && event.target.closest('[data-change-events]'))
|
|
13
|
+
readMatches(event.target,event.target.closest('[data-change-events]').getAttribute('data-change-events'));
|
|
14
|
+
});
|
|
15
|
+
document.addEventListener('keyup', (event) => {
|
|
16
|
+
if (event && event.target instanceof HTMLElement && event.target.closest('[data-change-events]'))
|
|
17
|
+
readMatches(event.target,event.target.closest('[data-change-events]').getAttribute('data-change-events'));
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// Click event
|
|
21
|
+
document.addEventListener('click', (event) => {
|
|
22
|
+
if (event && event.target instanceof HTMLElement && event.target.closest('[data-click-events]'))
|
|
23
|
+
readMatches(event.target,event.target.closest('[data-click-events]').getAttribute('data-click-events'));
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// Parse the JSON and trigger the events, this may be singular or multiple set of events
|
|
28
|
+
const readMatches = (element,events) => {
|
|
29
|
+
|
|
30
|
+
// an empty events will trigger looking up the dom chain for
|
|
31
|
+
if(!events){
|
|
32
|
+
events = element.parentNode.getAttribute('data-change-events');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// If still empty bail out
|
|
36
|
+
if(!events)
|
|
37
|
+
return false;
|
|
38
|
+
|
|
39
|
+
// Split out each event
|
|
40
|
+
Array.from(JSON.parse(events)).forEach((event, index) => {
|
|
41
|
+
checkMatch(element,event);
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const checkMatch = (element,event) => {
|
|
46
|
+
|
|
47
|
+
if("matches" in event){
|
|
48
|
+
if(event['matches'] == 'any')
|
|
49
|
+
runEvent(element,event,'if');
|
|
50
|
+
else if(element.value == event.matches)
|
|
51
|
+
runEvent(element,event,'if');
|
|
52
|
+
else
|
|
53
|
+
runEvent(element,event,'else');
|
|
54
|
+
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
else if("in-list" in event){
|
|
58
|
+
if(document.querySelector(`${event['in-list']} option[value="${element.value}"]`)){
|
|
59
|
+
let match = document.querySelector(`${event['in-list']} option[value="${element.value}"]`);
|
|
60
|
+
runEvent(element,event,'if',match);
|
|
61
|
+
}
|
|
62
|
+
else
|
|
63
|
+
runEvent(element,event,'else');
|
|
64
|
+
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
else if("event" in event){
|
|
68
|
+
runEvent(element,event,'event');
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const runEvent = (element,event,eventType,match) => {
|
|
73
|
+
|
|
74
|
+
if(eventType in event == false)
|
|
75
|
+
return false;
|
|
76
|
+
|
|
77
|
+
switch (event[eventType]){
|
|
78
|
+
case "hide":
|
|
79
|
+
|
|
80
|
+
let hideElement = document.querySelector(event['target'])
|
|
81
|
+
hideElement.classList.add('js-hide');
|
|
82
|
+
|
|
83
|
+
Array.from(hideElement.querySelectorAll('[data-required]')).forEach((input, index) => {
|
|
84
|
+
|
|
85
|
+
input.removeAttribute('required');
|
|
86
|
+
});
|
|
87
|
+
break;
|
|
88
|
+
case "show":
|
|
89
|
+
|
|
90
|
+
let showElement = document.querySelector(event['target'])
|
|
91
|
+
showElement.classList.remove('js-hide');
|
|
92
|
+
|
|
93
|
+
Array.from(showElement.querySelectorAll('[data-required]')).forEach((input, index) => {
|
|
94
|
+
|
|
95
|
+
if(!input.closest('.js-hide'))
|
|
96
|
+
input.setAttribute('required','true');
|
|
97
|
+
});
|
|
98
|
+
break;
|
|
99
|
+
case "populate-form":
|
|
100
|
+
populateForm(element,event,match);
|
|
101
|
+
break;
|
|
102
|
+
case "setAttribute":
|
|
103
|
+
document.querySelector(`${event['target']}`).setAttribute(event['attribute'],event['value']);
|
|
104
|
+
break;
|
|
105
|
+
case "removeAttribute":
|
|
106
|
+
document.querySelector(`${event['target']}`).removeAttribute(event['attribute']);
|
|
107
|
+
break;
|
|
108
|
+
case "updateValue":
|
|
109
|
+
document.querySelector(`${event['target']}`).value = event['value'] ? event['value'] : "";
|
|
110
|
+
|
|
111
|
+
let changeEvent = new Event('change');
|
|
112
|
+
document.querySelector(`${event['target']}`).dispatchEvent(changeEvent);
|
|
113
|
+
break;
|
|
114
|
+
default:
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const populateForm = function (element,event,match) {
|
|
120
|
+
|
|
121
|
+
let response = JSON.parse(match.getAttribute('data-values'));
|
|
122
|
+
let form = document.querySelector(event['target']);
|
|
123
|
+
|
|
124
|
+
Object.keys(response).forEach((field, index) => {
|
|
125
|
+
|
|
126
|
+
if(document.getElementById(field) && document.getElementById(field).tagName == "SPAN")
|
|
127
|
+
document.getElementById(field).innerHTML = response[field];
|
|
128
|
+
|
|
129
|
+
if(form.querySelector(`input[name="${field}"][type="radio"][value="${response[field]}"]`)){
|
|
130
|
+
|
|
131
|
+
Array.from(form.querySelectorAll(`input[name="${field}"][type="radio"]`)).forEach(function(input,index){
|
|
132
|
+
input.disabled = true;
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
form.querySelector(`input[name="${field}"][type="radio"][value="${response[field]}"]`).checked = true;
|
|
136
|
+
form.querySelector(`input[name="${field}"][type="radio"][value="${response[field]}"]`).disabled = false;
|
|
137
|
+
}
|
|
138
|
+
else if(form.querySelector(`input[name="${field}"]`)){
|
|
139
|
+
form.querySelector(`input[name="${field}"]`).value = response[field];
|
|
140
|
+
form.querySelector(`input[name="${field}"]`).setAttribute('readonly','true');
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export default createDynamicEvents;
|
|
@@ -25,7 +25,7 @@ export const addBodyClasses = (body) => {
|
|
|
25
25
|
* @param {HTMLElement} body Dom element, this doesn't have to be the body but it is recommended.
|
|
26
26
|
*/
|
|
27
27
|
export const addGlobalEvents = (body) => {
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
const checkElements = function(hash){
|
|
30
30
|
|
|
31
31
|
const label = document.querySelector(`label[for="${hash.replace('#','')}"]`);
|
|
@@ -60,6 +60,21 @@ export const addGlobalEvents = (body) => {
|
|
|
60
60
|
}
|
|
61
61
|
});
|
|
62
62
|
|
|
63
|
+
document.addEventListener("submit", (event) => {
|
|
64
|
+
|
|
65
|
+
if (event && event.target instanceof HTMLElement && event.target.matches('form')){
|
|
66
|
+
|
|
67
|
+
let form = event.target;
|
|
68
|
+
|
|
69
|
+
if(form.querySelector(':invalid')){
|
|
70
|
+
|
|
71
|
+
form.classList.add('was-validated');
|
|
72
|
+
event.preventDefault();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
});
|
|
77
|
+
|
|
63
78
|
return null
|
|
64
79
|
}
|
|
65
80
|
|
|
@@ -18,21 +18,18 @@ const createPaginationButttons = function(controller: any,pagination: any){
|
|
|
18
18
|
return false;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
let
|
|
21
|
+
let strOptions = '';
|
|
22
22
|
|
|
23
23
|
for (let i = 1; i <= numberPages; i++) {
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
strButtons += `<li class="page-item active" aria-current="page"><span class="page-link">${i}</span></li>`;
|
|
27
|
-
else
|
|
28
|
-
strButtons += `<li class="page-item"><a href="?page=${i}" class="page-link" data-page="${i}">${i}</a></li>`;
|
|
25
|
+
strOptions += `<option value="${i}" ${i == currentPage ? 'selected' : ''}>${i}</option>`;
|
|
29
26
|
}
|
|
30
27
|
|
|
31
|
-
pagination.innerHTML = `<
|
|
32
|
-
|
|
33
|
-
${
|
|
34
|
-
${currentPage == numberPages ?
|
|
35
|
-
</
|
|
28
|
+
pagination.innerHTML = `<div class="pagination mb-0 d-none d-sm-flex">
|
|
29
|
+
<div><select>${strOptions}</select></div>
|
|
30
|
+
<button class="prev" ${currentPage == 1 ?'disabled':''} data-page="${parseInt(currentPage)-1}">Previous</button>
|
|
31
|
+
<button class="next" ${currentPage == numberPages ?'disabled':''} data-page="${parseInt(currentPage)+1}">Next</button>
|
|
32
|
+
</div>`;
|
|
36
33
|
pagination.innerHTML += `<div class="d-sm-none text-center">
|
|
37
34
|
<span class="d-block pb-2">You've viewed ${showRows} of ${numberRows} results</span>
|
|
38
35
|
<a href="?show=${parseInt(showRows)+parseInt(addRows)}" class="btn btn-primary w-100 m-0" data-show="${parseInt(showRows)+parseInt(addRows)}">Load more results</a>
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
import { zeroPad, isNumeric, ucfirst } from "./helpers";
|
|
3
|
-
import createPaginationButttons from "./pagination";
|
|
4
3
|
|
|
5
4
|
// Basic functionality needed
|
|
6
5
|
export const addDataAttributes = (table) => {
|
|
@@ -60,44 +59,50 @@ export const getLargestLastColWidth = (table) => {
|
|
|
60
59
|
return largestWidth;
|
|
61
60
|
}
|
|
62
61
|
|
|
63
|
-
export const createMobileButton = (table) => {
|
|
62
|
+
export const createMobileButton = (table, wrapper) => {
|
|
64
63
|
|
|
65
|
-
|
|
64
|
+
|
|
65
|
+
if(wrapper.classList.contains('.table--fullwidth') && !wrapper.hasAttribute('data-expandable'))
|
|
66
66
|
return false;
|
|
67
67
|
|
|
68
|
-
if(table.querySelectorAll('thead tr th').length < 4)
|
|
68
|
+
if(table.querySelectorAll('thead tr th').length < 4 && !wrapper.hasAttribute('data-expandable'))
|
|
69
69
|
return false;
|
|
70
70
|
|
|
71
|
-
Array.from(table.querySelectorAll('tbody tr')).forEach((row, index) => {
|
|
72
|
-
let firstCol = row.querySelector(':scope > :is(td,th):first-child');
|
|
73
71
|
|
|
74
|
-
|
|
72
|
+
Array.from(table.querySelectorAll('thead tr')).forEach((row,index) => {
|
|
73
|
+
|
|
74
|
+
row.insertAdjacentHTML(
|
|
75
|
+
'afterbegin',
|
|
76
|
+
`<th class="th--fixed expand-button-heading"></th>`
|
|
77
|
+
);
|
|
78
|
+
});
|
|
75
79
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
80
|
+
Array.from(table.querySelectorAll('tbody tr')).forEach((row,index) => {
|
|
81
|
+
|
|
82
|
+
row.insertAdjacentHTML(
|
|
83
|
+
'afterbegin',
|
|
84
|
+
`<td class="td--fixed td--expand"><button class="btn btn-compact btn-secondary" data-expand-button>Expand</button></td>`
|
|
85
|
+
);
|
|
83
86
|
});
|
|
87
|
+
|
|
88
|
+
|
|
84
89
|
}
|
|
85
90
|
|
|
86
91
|
export const addTableEventListeners = (table) => {
|
|
87
92
|
|
|
88
93
|
table.addEventListener('click', (event) => {
|
|
89
94
|
|
|
90
|
-
if (event && event.target instanceof HTMLElement && event.target.closest('
|
|
95
|
+
if (event && event.target instanceof HTMLElement && event.target.closest('[data-expand-button]')){
|
|
91
96
|
|
|
92
|
-
let
|
|
93
|
-
let tableRow =
|
|
97
|
+
let button = event.target.closest('[data-expand-button]');
|
|
98
|
+
let tableRow = button.closest('tr');
|
|
94
99
|
|
|
95
100
|
if(tableRow.getAttribute('data-view') == "full")
|
|
96
101
|
tableRow.setAttribute('data-view','default');
|
|
97
102
|
else
|
|
98
103
|
tableRow.setAttribute('data-view','full');
|
|
99
104
|
|
|
100
|
-
|
|
105
|
+
button.blur();
|
|
101
106
|
};
|
|
102
107
|
});
|
|
103
108
|
}
|
|
@@ -185,7 +190,6 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
|
|
|
185
190
|
form.submit();
|
|
186
191
|
else {
|
|
187
192
|
filterTable(table, form, wrapper);
|
|
188
|
-
createPaginationButttons(wrapper,pagination);
|
|
189
193
|
populateDataQueries(table,form);
|
|
190
194
|
}
|
|
191
195
|
|
|
@@ -232,7 +236,6 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
|
|
|
232
236
|
if (event && event.target instanceof HTMLElement && event.target.closest('[data-filter][data-no-ajax]')){ // Allow for input fields to filter the current results without a new ajax call
|
|
233
237
|
|
|
234
238
|
filterTable(table, form, wrapper);
|
|
235
|
-
createPaginationButttons(wrapper,pagination);
|
|
236
239
|
populateDataQueries(table,form);
|
|
237
240
|
}
|
|
238
241
|
else if (event && event.target instanceof HTMLElement && event.target.closest('[data-filter]') && event.target.closest('form .dialog__wrapper > dialog')){
|
|
@@ -276,7 +279,7 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
|
|
|
276
279
|
}
|
|
277
280
|
|
|
278
281
|
if (event && event.target instanceof HTMLElement && event.target.closest('[data-clear]')){
|
|
279
|
-
|
|
282
|
+
|
|
280
283
|
form.classList.add('processing');
|
|
281
284
|
// Make sure any applied filters have been removed
|
|
282
285
|
Array.from(form.querySelectorAll('.applied-filters')).forEach((filters,index) => {
|
|
@@ -300,7 +303,17 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
|
|
|
300
303
|
case "checkbox":
|
|
301
304
|
if (frm_elements[i].checked)
|
|
302
305
|
{
|
|
303
|
-
frm_elements[i]
|
|
306
|
+
let input = frm_elements[i];
|
|
307
|
+
let id = input.getAttribute('id');
|
|
308
|
+
let label = document.querySelector(`[for="${id}"`);
|
|
309
|
+
|
|
310
|
+
if(label.querySelector('iam-card')){
|
|
311
|
+
let card = label.querySelector('iam-card');
|
|
312
|
+
let clickEvent = new Event('click');
|
|
313
|
+
card.dispatchEvent(clickEvent);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
input.checked = false;
|
|
304
317
|
}
|
|
305
318
|
break;
|
|
306
319
|
case "select-one":
|
|
@@ -313,11 +326,6 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
|
|
|
313
326
|
}
|
|
314
327
|
}
|
|
315
328
|
|
|
316
|
-
Array.from(form.querySelectorAll('label iam-card')).forEach((card,index) => {
|
|
317
|
-
let clickEvent = new Event('click');
|
|
318
|
-
card.dispatchEvent(clickEvent);
|
|
319
|
-
});
|
|
320
|
-
|
|
321
329
|
form.classList.remove('processing');
|
|
322
330
|
|
|
323
331
|
if(!form.hasAttribute('data-submit'))
|
|
@@ -666,10 +674,9 @@ export const filterTable = (table, form, wrapper) => {
|
|
|
666
674
|
});
|
|
667
675
|
|
|
668
676
|
if(wrapper){
|
|
669
|
-
wrapper.setAttribute('data-page',page);
|
|
670
|
-
wrapper.setAttribute('data-pages',Math.ceil(matched/showRows));
|
|
671
677
|
wrapper.setAttribute('data-total',matched);
|
|
672
678
|
wrapper.setAttribute('data-show',showRows);
|
|
679
|
+
wrapper.setAttribute('data-page',page);
|
|
673
680
|
}
|
|
674
681
|
|
|
675
682
|
}
|
|
@@ -742,40 +749,40 @@ export const populateDataQueries = (table,form,wrapper) => {
|
|
|
742
749
|
// Pagination
|
|
743
750
|
export const addPaginationEventListeners = function(table, form, pagination, wrapper){
|
|
744
751
|
|
|
745
|
-
pagination.addEventListener('
|
|
752
|
+
pagination.addEventListener('update-page', (event) => {
|
|
746
753
|
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
event.preventDefault();
|
|
754
|
+
let paginationInput = form.querySelector('[data-pagination]');
|
|
755
|
+
let newPage = event.detail.page;
|
|
750
756
|
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
wrapper.setAttribute('data-page', newPage);
|
|
755
|
-
form.dispatchEvent(new Event("paginate"));
|
|
757
|
+
// Set the filter value
|
|
758
|
+
paginationInput.value = newPage;
|
|
759
|
+
form.dispatchEvent(new Event("paginate"));
|
|
756
760
|
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
761
|
+
// Reset the data attribute
|
|
762
|
+
wrapper.setAttribute('data-page',newPage);
|
|
763
|
+
|
|
764
|
+
if(table.hasAttribute('data-show-history')){
|
|
765
|
+
|
|
766
|
+
const url = new URL(location);
|
|
767
|
+
url.searchParams.set("page", newPage);
|
|
768
|
+
history.pushState({'type':'pagination','form':form.getAttribute('id'),'page':newPage}, "", url)
|
|
769
|
+
}
|
|
763
770
|
|
|
764
|
-
|
|
771
|
+
// scroll back to the top of the table
|
|
772
|
+
if(!wrapper.hasAttribute('data-no-scroll')){
|
|
765
773
|
const yOffset = -250;
|
|
766
774
|
const y = table.getBoundingClientRect().top + window.pageYOffset + yOffset;
|
|
767
775
|
window.scrollTo({top: y, behavior: 'smooth'});
|
|
768
776
|
}
|
|
777
|
+
});
|
|
769
778
|
|
|
770
|
-
|
|
779
|
+
pagination.addEventListener('update-show', (event) => {
|
|
771
780
|
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
form.dispatchEvent(new Event("submit"));
|
|
778
|
-
}
|
|
781
|
+
let showInput = form.querySelector('[data-show]');
|
|
782
|
+
let showRows = event.detail.show;
|
|
783
|
+
showInput.value = showRows;
|
|
784
|
+
wrapper.setAttribute('data-show', showRows);
|
|
785
|
+
form.dispatchEvent(new Event("submit"));
|
|
779
786
|
});
|
|
780
787
|
}
|
|
781
788
|
|
|
@@ -839,7 +846,7 @@ export const exportAsCSV = function(table){
|
|
|
839
846
|
export const makeTableFunctional = function(table, form, pagination, wrapper){
|
|
840
847
|
|
|
841
848
|
addDataAttributes(table);
|
|
842
|
-
createMobileButton(table);
|
|
849
|
+
createMobileButton(table, wrapper);
|
|
843
850
|
populateDataQueries(table, form, wrapper);
|
|
844
851
|
|
|
845
852
|
// Work out the largest width of the CTA's in the last column
|
|
@@ -941,6 +948,10 @@ export const loadAjaxTable = async function (table, form, pagination, wrapper){
|
|
|
941
948
|
window.controller[ajaxURL] = new AbortController();
|
|
942
949
|
const { signal } = controller[ajaxURL];
|
|
943
950
|
|
|
951
|
+
// Set loading on the pagination
|
|
952
|
+
pagination.setAttribute('data-loading','true');
|
|
953
|
+
form.classList.add('processing');
|
|
954
|
+
|
|
944
955
|
try {
|
|
945
956
|
await fetch(ajaxURL+'?'+queryString, {
|
|
946
957
|
signal: signal,
|
|
@@ -958,7 +969,7 @@ export const loadAjaxTable = async function (table, form, pagination, wrapper){
|
|
|
958
969
|
let totalNumberSchema = form.hasAttribute('data-schema-total') ? form.getAttribute('data-schema-total') : 'meta.total';
|
|
959
970
|
let currentPageSchema = form.hasAttribute('data-schema-page') ? form.getAttribute('data-schema-page') : 'meta.current_page';
|
|
960
971
|
|
|
961
|
-
let totalNumber = resolvePath(response, totalNumberSchema,
|
|
972
|
+
let totalNumber = resolvePath(response, totalNumberSchema, 15);
|
|
962
973
|
let currentPage = resolvePath(response, currentPageSchema, 1);
|
|
963
974
|
let data = resolvePath(response, schema);
|
|
964
975
|
let emptyMsg = wrapper.hasAttribute('data-empty-msg') ? wrapper.getAttribute('data-empty-msg') : "No results found";
|
|
@@ -1032,11 +1043,9 @@ export const loadAjaxTable = async function (table, form, pagination, wrapper){
|
|
|
1032
1043
|
// Add data to the pagination
|
|
1033
1044
|
wrapper.setAttribute('data-total', parseInt(totalNumber));
|
|
1034
1045
|
wrapper.setAttribute('data-page', parseInt(currentPage));
|
|
1035
|
-
wrapper.setAttribute('data-pages', Math.ceil(wrapper.getAttribute('data-total') / wrapper.getAttribute('data-show')));
|
|
1036
1046
|
|
|
1037
1047
|
|
|
1038
1048
|
makeTableFunctional(table, form, pagination, wrapper);
|
|
1039
|
-
createPaginationButttons(wrapper, pagination);
|
|
1040
1049
|
|
|
1041
1050
|
Array.from(form.querySelectorAll('[data-ajax-query]')).forEach((queryElement, index) => {
|
|
1042
1051
|
|
|
@@ -1064,6 +1073,10 @@ export const loadAjaxTable = async function (table, form, pagination, wrapper){
|
|
|
1064
1073
|
else {
|
|
1065
1074
|
tbody.innerHTML = '<tr><td colspan="100%"><span>Error loading table</span></td></tr>';
|
|
1066
1075
|
}
|
|
1076
|
+
|
|
1077
|
+
// Remove loading on the pagination
|
|
1078
|
+
pagination.removeAttribute('data-loading');
|
|
1079
|
+
form.classList.remove('processing');
|
|
1067
1080
|
});
|
|
1068
1081
|
} catch (error) {
|
|
1069
1082
|
console.log(error);
|
|
@@ -12,23 +12,29 @@ export const createTabsLinks = function(tabsElement: Element) {
|
|
|
12
12
|
tabLinks = document.createElement('div');
|
|
13
13
|
tabLinks.classList.add('tabs__links');
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
let tabLinksWrapper = document.createElement('div');
|
|
16
|
+
tabLinksWrapper.classList.add('tabs__links__wrapper');
|
|
17
|
+
|
|
18
|
+
tabLinksWrapper.prepend(tabLinks);
|
|
19
|
+
tabsElement.prepend(tabLinksWrapper);
|
|
16
20
|
}
|
|
17
21
|
|
|
18
22
|
// Create the tab buttons from the summary titles
|
|
19
23
|
details.forEach((detail, index) => {
|
|
20
24
|
|
|
21
25
|
let summary = detail.querySelector(':scope > summary');
|
|
26
|
+
let isDisabled = summary.classList.contains('disabled')
|
|
27
|
+
|
|
22
28
|
summary.classList.add('visually-hidden');
|
|
23
29
|
|
|
24
30
|
let button = document.createElement('button');
|
|
25
|
-
|
|
26
|
-
|
|
31
|
+
|
|
32
|
+
if (detail.hasAttribute('id')) {
|
|
27
33
|
button = document.createElement('a');
|
|
28
34
|
button.setAttribute('href',`#${detail.getAttribute('id')}`);
|
|
29
35
|
}
|
|
30
36
|
|
|
31
|
-
if(detail.hasAttribute('open')){
|
|
37
|
+
if (detail.hasAttribute('open')) {
|
|
32
38
|
button.setAttribute('aria-pressed',true);
|
|
33
39
|
}
|
|
34
40
|
|
|
@@ -37,6 +43,10 @@ export const createTabsLinks = function(tabsElement: Element) {
|
|
|
37
43
|
button.setAttribute('data-index',index);
|
|
38
44
|
button.setAttribute('tabindex','-1');
|
|
39
45
|
|
|
46
|
+
if (isDisabled) {
|
|
47
|
+
button.classList.add('disabled')
|
|
48
|
+
}
|
|
49
|
+
|
|
40
50
|
tabLinks.appendChild(button);
|
|
41
51
|
});
|
|
42
52
|
|
|
@@ -55,15 +65,17 @@ export const setTabsEventHandlers = function(tabsElement: Element){
|
|
|
55
65
|
buttons.forEach((button) => {
|
|
56
66
|
|
|
57
67
|
button.addEventListener("click", (e) => {
|
|
58
|
-
|
|
59
68
|
e.preventDefault();
|
|
60
|
-
buttons.forEach((buttonLoopItem) => {
|
|
61
69
|
|
|
70
|
+
if (button.classList.contains('disabled'))
|
|
71
|
+
return false
|
|
72
|
+
|
|
73
|
+
buttons.forEach((buttonLoopItem) => {
|
|
62
74
|
let buttonPressed = buttonLoopItem == button ? true : false;
|
|
63
75
|
buttonLoopItem.setAttribute('aria-pressed', buttonPressed);
|
|
64
76
|
});
|
|
77
|
+
|
|
65
78
|
details.forEach((detail, detailsIndex) => {
|
|
66
|
-
|
|
67
79
|
let detailsOpen = button.getAttribute('data-index') == detailsIndex ? true : false;
|
|
68
80
|
|
|
69
81
|
if(detailsOpen)
|
|
@@ -90,15 +102,15 @@ export const setTabsEventHandlers = function(tabsElement: Element){
|
|
|
90
102
|
|
|
91
103
|
// Maintain the focus on the summary element but visually highlight the tab button
|
|
92
104
|
summary.addEventListener("focus", (e) => {
|
|
93
|
-
|
|
94
105
|
buttons.forEach((button) => {
|
|
95
106
|
|
|
96
107
|
button.classList.remove('focus');
|
|
97
108
|
});
|
|
109
|
+
|
|
98
110
|
buttons[index].classList.add('focus');
|
|
99
111
|
});
|
|
100
|
-
summary.addEventListener("click", (e) => {
|
|
101
112
|
|
|
113
|
+
summary.addEventListener("click", (e) => {
|
|
102
114
|
e.preventDefault();
|
|
103
115
|
buttons[index].click();
|
|
104
116
|
});
|
|
@@ -128,7 +140,6 @@ export const openFirstTab = function(tabsElement: Element){
|
|
|
128
140
|
}
|
|
129
141
|
|
|
130
142
|
const tabs = function(tabsElement: Element){
|
|
131
|
-
|
|
132
143
|
createTabsLinks(tabsElement);
|
|
133
144
|
setTabsEventHandlers(tabsElement);
|
|
134
145
|
openFirstTab(tabsElement);
|
|
@@ -69,50 +69,6 @@ describe('addDataAttributes', () => {
|
|
|
69
69
|
|
|
70
70
|
});
|
|
71
71
|
|
|
72
|
-
/* TODO: This unit test doesn't work as puppeteer seems to have an issue with query selector all
|
|
73
|
-
describe('getLargestLastColWidth', () => {
|
|
74
|
-
|
|
75
|
-
test('should return the width of the largest last column content', async() => {
|
|
76
|
-
|
|
77
|
-
const browser = await puppeteer.launch({});
|
|
78
|
-
try {
|
|
79
|
-
const page = await browser.newPage();
|
|
80
|
-
await page.exposeFunction("getLargestLastColWidth", tableModule.getLargestLastColWidth);
|
|
81
|
-
await page.setContent(`<table id="table">${basicTable}</table>`);
|
|
82
|
-
await page.waitForSelector('#table tr');
|
|
83
|
-
|
|
84
|
-
const largestWidth = await page.evaluate(`getLargestLastColWidth(document.querySelector("#table"))`);
|
|
85
|
-
|
|
86
|
-
//const links = await page.$$eval('#table', e=>getLargestLastColWidth(e))
|
|
87
|
-
console.log(await largestWidth)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
} catch (e) {
|
|
91
|
-
console.error(e);
|
|
92
|
-
} finally {
|
|
93
|
-
await browser.close();
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
});
|
|
100
|
-
*/
|
|
101
|
-
|
|
102
|
-
describe('createMobileButton', () => {
|
|
103
|
-
|
|
104
|
-
const table = document.createElement('table');
|
|
105
|
-
table.innerHTML = basicTable;
|
|
106
|
-
|
|
107
|
-
tableModule.createMobileButton(table);
|
|
108
|
-
|
|
109
|
-
test('should add a button to the first cell in a column', () => {
|
|
110
|
-
|
|
111
|
-
expect(table.querySelector('tbody td:nth-child(1) button').textContent).toEqual('Cell 1');
|
|
112
|
-
expect(table.querySelector('tbody td:nth-child(1) span').textContent).toEqual('Cell 1');
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
|
|
116
72
|
describe('createSearchDataList', () => {
|
|
117
73
|
|
|
118
74
|
const table = document.createElement('table');
|
|
@@ -162,6 +118,7 @@ describe('sortTable', () => {
|
|
|
162
118
|
|
|
163
119
|
});
|
|
164
120
|
|
|
121
|
+
|
|
165
122
|
describe('filterTable', () => {
|
|
166
123
|
|
|
167
124
|
const table = document.createElement('table');
|
|
@@ -177,25 +134,8 @@ describe('filterTable', () => {
|
|
|
177
134
|
expect(table.querySelectorAll('tbody tr.filtered--matched').length).toEqual(1);
|
|
178
135
|
});
|
|
179
136
|
});
|
|
180
|
-
/*
|
|
181
|
-
describe('populateDataQueries', () => {
|
|
182
137
|
|
|
183
|
-
const table = document.createElement('table');
|
|
184
|
-
table.innerHTML = basicTable;
|
|
185
|
-
const form = document.createElement('form');
|
|
186
|
-
form.innerHTML += `<div><input name="heading" value="Low" data-filter="Heading 2" /><span data-query="total"></span><span data-query="Heading 2 == Low"></span></div>`;
|
|
187
|
-
|
|
188
|
-
tableModule.addDataAttributes(table);
|
|
189
|
-
tableModule.filterTable(table, form, document.createElement('div'));
|
|
190
|
-
tableModule.populateDataQueries(table, form);
|
|
191
138
|
|
|
192
|
-
test('should populate elements with the data-query attribute with the result of the corresponding query', () => {
|
|
193
|
-
|
|
194
|
-
//expect(form.querySelector('[data-query="total"]').textContent).toEqual('4');
|
|
195
|
-
//expect(form.querySelector('[data-query="Heading 2 == Low"]').textContent).toEqual('2');
|
|
196
|
-
});
|
|
197
|
-
});
|
|
198
|
-
*/
|
|
199
139
|
describe('formatCell', () => {
|
|
200
140
|
|
|
201
141
|
test('should format the text correctly', () => {
|