@iamproperty/components 3.7.0 → 3.7.2
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/table.css +1 -1
- package/assets/css/components/table.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/card/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/table/table.component.js +8 -1
- package/assets/js/components/table/table.component.min.js +13 -13
- package/assets/js/components/table/table.component.min.js.map +1 -1
- package/assets/js/components/tabs/tabs.component.min.js +1 -1
- package/assets/js/dynamic.min.js +2 -2
- package/assets/js/dynamic.min.js.map +1 -1
- package/assets/js/modules/applied-filters.js +1 -1
- package/assets/js/modules/dialogs.js +12 -1
- package/assets/js/modules/table.js +202 -65
- package/assets/js/scripts.bundle.js +21 -21
- 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 +19 -13
- package/assets/sass/components/table.scss +125 -75
- package/assets/sass/foundations/reboot.scss +7 -3
- package/assets/ts/components/table/table.component.ts +12 -1
- package/assets/ts/modules/applied-filters.ts +1 -1
- package/assets/ts/modules/dialogs.ts +16 -5
- package/assets/ts/modules/table.ts +244 -69
- package/assets/ts/tests/table.spec.ts +6 -6
- package/dist/components.es.js +904 -839
- package/dist/components.umd.js +21 -21
- package/package.json +1 -1
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
1
10
|
// @ts-nocheck
|
|
2
11
|
import { zeroPad, isNumeric, ucfirst } from "./helpers.js";
|
|
3
12
|
import createPaginationButttons from "./pagination.js";
|
|
@@ -7,7 +16,7 @@ export const addDataAttributes = (table) => {
|
|
|
7
16
|
const colRows = Array.from(table.querySelectorAll('tbody tr'));
|
|
8
17
|
colRows.forEach((row, index) => {
|
|
9
18
|
const cells = Array.from(row.querySelectorAll('th, td'));
|
|
10
|
-
const statuses = ['
|
|
19
|
+
const statuses = ['0', 'low', 'medium', 'high', 'unknown', 'n/a', 'pending', 'verified', 'incomplete', 'completed', 'requires approval'];
|
|
11
20
|
cells.forEach((cell, cellIndex) => {
|
|
12
21
|
const heading = colHeadings[cellIndex];
|
|
13
22
|
if (typeof heading != "undefined") {
|
|
@@ -19,10 +28,10 @@ export const addDataAttributes = (table) => {
|
|
|
19
28
|
cell.setAttribute('class', heading.getAttribute('data-td-class'));
|
|
20
29
|
if (heading.hasAttribute('data-format')) {
|
|
21
30
|
cell.setAttribute('data-format', heading.getAttribute('data-format'));
|
|
22
|
-
cell.innerHTML = formatCell('
|
|
31
|
+
cell.innerHTML = formatCell(heading.getAttribute('data-format'), cell.textContent.trim()); //Make sure date format is consistent
|
|
23
32
|
}
|
|
24
|
-
if (statuses.includes(cell.textContent.trim())) {
|
|
25
|
-
cell.setAttribute('data-content', cell.textContent.trim());
|
|
33
|
+
if (statuses.includes(cell.textContent.trim().toLowerCase())) {
|
|
34
|
+
cell.setAttribute('data-content', cell.textContent.trim().toLowerCase());
|
|
26
35
|
}
|
|
27
36
|
}
|
|
28
37
|
});
|
|
@@ -100,9 +109,16 @@ export const createSearchDataList = (table, form) => {
|
|
|
100
109
|
export const addFilterEventListeners = (table, form, pagination, wrapper, savedTableBody) => {
|
|
101
110
|
var timer;
|
|
102
111
|
// Check what conditions are set on the table to see what the form actions are
|
|
103
|
-
let formSubmit = function () {
|
|
104
|
-
if (form.hasAttribute('data-ajax'))
|
|
112
|
+
let formSubmit = function (paginate = false) {
|
|
113
|
+
if (form.hasAttribute('data-ajax')) {
|
|
114
|
+
// Default back to page 1
|
|
115
|
+
if (!paginate) {
|
|
116
|
+
let paginationInput = form.querySelector('[data-pagination]');
|
|
117
|
+
paginationInput.value = 1;
|
|
118
|
+
wrapper.setAttribute('data-page', 1);
|
|
119
|
+
}
|
|
105
120
|
loadAjaxTable(table, form, pagination, wrapper);
|
|
121
|
+
}
|
|
106
122
|
else if (form.hasAttribute('data-submit'))
|
|
107
123
|
form.submit();
|
|
108
124
|
else {
|
|
@@ -139,6 +155,9 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
|
|
|
139
155
|
if (event && event.target instanceof HTMLElement && event.target.closest('[data-show]')) {
|
|
140
156
|
formSubmit();
|
|
141
157
|
}
|
|
158
|
+
if (event && event.target instanceof HTMLElement && event.target.closest('[data-mimic]')) {
|
|
159
|
+
formSubmit();
|
|
160
|
+
}
|
|
142
161
|
});
|
|
143
162
|
form.addEventListener('click', (event) => {
|
|
144
163
|
clearTimeout(timer);
|
|
@@ -168,6 +187,58 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
|
|
|
168
187
|
form.addEventListener('force', (event) => {
|
|
169
188
|
formSubmit();
|
|
170
189
|
});
|
|
190
|
+
form.addEventListener('paginate', (event) => {
|
|
191
|
+
formSubmit(true);
|
|
192
|
+
});
|
|
193
|
+
// Mmimic fields
|
|
194
|
+
let forms = [];
|
|
195
|
+
let fields = [];
|
|
196
|
+
// Collect the forms that we need to add an event listener for.
|
|
197
|
+
Array.from(form.querySelectorAll('[data-mimic]')).forEach((input, index) => {
|
|
198
|
+
let mimicField = input.getAttribute('data-mimic');
|
|
199
|
+
Array.from(document.querySelectorAll(`[name="${mimicField}"]`)).forEach((mimicInput, index) => {
|
|
200
|
+
let parentForm = mimicInput.closest('form');
|
|
201
|
+
if (!forms.includes(parentForm))
|
|
202
|
+
forms.push(parentForm);
|
|
203
|
+
if (!fields.includes(mimicField))
|
|
204
|
+
fields.push(mimicField);
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
// For each form add change listener
|
|
208
|
+
forms.forEach((parentForm, index) => {
|
|
209
|
+
const updateMimicInput = function () {
|
|
210
|
+
let mimickedAlready = [];
|
|
211
|
+
let formData = new FormData(parentForm);
|
|
212
|
+
let i = 1;
|
|
213
|
+
for (const [key, value] of formData) {
|
|
214
|
+
if (document.querySelector(`[data-mimic="${key}"]`) && !mimickedAlready.includes(key)) {
|
|
215
|
+
mimickedAlready.push(key);
|
|
216
|
+
document.querySelector(`[data-mimic="${key}"]`).value = value;
|
|
217
|
+
}
|
|
218
|
+
else if (document.querySelector(`[data-mimic="${key}"]`))
|
|
219
|
+
document.querySelector(`[data-mimic="${key}"]`).value += "," + value;
|
|
220
|
+
i++;
|
|
221
|
+
}
|
|
222
|
+
for (const value of mimickedAlready) {
|
|
223
|
+
const event = new Event("force");
|
|
224
|
+
form.dispatchEvent(event);
|
|
225
|
+
}
|
|
226
|
+
// Check for empties
|
|
227
|
+
for (const field of fields) {
|
|
228
|
+
if (!formData.has(field) && parentForm.querySelector(`[name="${field}"]`)) {
|
|
229
|
+
document.querySelector(`[data-mimic="${field}"]`).value = "";
|
|
230
|
+
const event = new Event("force");
|
|
231
|
+
form.dispatchEvent(event);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
parentForm.addEventListener('force', (event) => {
|
|
236
|
+
updateMimicInput();
|
|
237
|
+
});
|
|
238
|
+
parentForm.addEventListener('change', (event) => {
|
|
239
|
+
updateMimicInput();
|
|
240
|
+
});
|
|
241
|
+
});
|
|
171
242
|
};
|
|
172
243
|
export const sortTable = (table, form, savedTableBody) => {
|
|
173
244
|
if (form.getAttribute('data-ajax')) {
|
|
@@ -248,10 +319,11 @@ export const filterTable = (table, form, wrapper) => {
|
|
|
248
319
|
filters[filterInput.getAttribute('data-filter')].push(value);
|
|
249
320
|
}
|
|
250
321
|
}
|
|
251
|
-
else if (filterInput.value) {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
322
|
+
else if (filterInput && filterInput.value) {
|
|
323
|
+
let dataFilter = filterInput.getAttribute('data-filter');
|
|
324
|
+
if (!filters[dataFilter])
|
|
325
|
+
filters[dataFilter] = new Array();
|
|
326
|
+
filters[dataFilter].push(filterInput.value);
|
|
255
327
|
}
|
|
256
328
|
});
|
|
257
329
|
// Add search columns too
|
|
@@ -364,13 +436,16 @@ export const filterTable = (table, form, wrapper) => {
|
|
|
364
436
|
wrapper.setAttribute('data-show', showRows);
|
|
365
437
|
}
|
|
366
438
|
};
|
|
367
|
-
export const populateDataQueries = (table, form) => {
|
|
439
|
+
export const populateDataQueries = (table, form, wrapper) => {
|
|
368
440
|
const dataQueries = Array.from(form.querySelectorAll('[data-query]'));
|
|
369
441
|
dataQueries.forEach((queryElement, index) => {
|
|
370
442
|
let query = queryElement.getAttribute('data-query');
|
|
371
443
|
let numberOfMatchedRows;
|
|
372
444
|
if (query == 'total') {
|
|
373
|
-
|
|
445
|
+
if (wrapper.hasAttribute('data-total'))
|
|
446
|
+
numberOfMatchedRows = wrapper.getAttribute('data-total');
|
|
447
|
+
else
|
|
448
|
+
numberOfMatchedRows = table.classList.contains('table--filtered') ? table.querySelectorAll('tbody tr').length : table.querySelectorAll('tbody tr').length;
|
|
374
449
|
}
|
|
375
450
|
else if (!query.includes(' == ') && query.includes(' & ')) {
|
|
376
451
|
let queries = query.split(' & ');
|
|
@@ -416,7 +491,7 @@ export const addPaginationEventListeners = function (table, form, pagination, wr
|
|
|
416
491
|
let newPage = event.target.closest('[data-page]').getAttribute('data-page');
|
|
417
492
|
paginationInput.value = newPage;
|
|
418
493
|
wrapper.setAttribute('data-page', newPage);
|
|
419
|
-
form.dispatchEvent(new Event("
|
|
494
|
+
form.dispatchEvent(new Event("paginate"));
|
|
420
495
|
if (table.hasAttribute('data-show-history')) {
|
|
421
496
|
const url = new URL(location);
|
|
422
497
|
url.searchParams.set("page", newPage);
|
|
@@ -477,9 +552,9 @@ export const exportAsCSV = function (table) {
|
|
|
477
552
|
};
|
|
478
553
|
// After table is loaded
|
|
479
554
|
export const makeTableFunctional = function (table, form, pagination, wrapper) {
|
|
480
|
-
createMobileButton(table);
|
|
481
555
|
addDataAttributes(table);
|
|
482
|
-
|
|
556
|
+
createMobileButton(table);
|
|
557
|
+
populateDataQueries(table, form, wrapper);
|
|
483
558
|
// Work out the largest width of the CTA's in the last column
|
|
484
559
|
if (wrapper && wrapper.classList.contains('table--cta')) {
|
|
485
560
|
const largestWidth = getLargestLastColWidth(table);
|
|
@@ -487,65 +562,127 @@ export const makeTableFunctional = function (table, form, pagination, wrapper) {
|
|
|
487
562
|
}
|
|
488
563
|
};
|
|
489
564
|
export const loadAjaxTable = function (table, form, pagination, wrapper) {
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
565
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
566
|
+
const resolvePath = (object, path, defaultValue) => path.split(/[\.\[\]\'\"]/).filter(p => p).reduce((o, p) => o ? o[p] : defaultValue, object);
|
|
567
|
+
let formData = new FormData(form);
|
|
568
|
+
let queryString = new URLSearchParams(formData).toString();
|
|
569
|
+
let columns = table.querySelectorAll('thead tr th');
|
|
570
|
+
let tbody = table.querySelector('tbody');
|
|
571
|
+
let ajaxURL = form.getAttribute('data-ajax');
|
|
572
|
+
wrapper.classList.add('table--loading');
|
|
573
|
+
// Setup controller vars if not already set
|
|
574
|
+
if (!window.controller)
|
|
575
|
+
window.controller = [];
|
|
576
|
+
// Abort if controller already present for this url
|
|
577
|
+
if (window.controller[ajaxURL])
|
|
578
|
+
window.controller[ajaxURL].abort();
|
|
579
|
+
// Create a new controller so it can be aborted if new fetch made
|
|
580
|
+
window.controller[ajaxURL] = new AbortController();
|
|
581
|
+
const { signal } = controller[ajaxURL];
|
|
582
|
+
try {
|
|
583
|
+
yield fetch(ajaxURL + '?' + queryString, {
|
|
584
|
+
signal: signal,
|
|
585
|
+
method: 'get',
|
|
586
|
+
credentials: 'same-origin',
|
|
587
|
+
headers: new Headers({
|
|
588
|
+
'Content-Type': 'application/json',
|
|
589
|
+
Accept: 'application/json',
|
|
590
|
+
'X-Requested-With': 'XMLHttpRequest'
|
|
591
|
+
})
|
|
592
|
+
})
|
|
593
|
+
.then((response) => response.json()).then((response) => {
|
|
594
|
+
let schema = form.hasAttribute('data-schema') ? form.getAttribute('data-schema') : 'data';
|
|
595
|
+
let totalNumberSchema = form.hasAttribute('data-schema-total') ? form.getAttribute('data-schema-total') : 'meta.total';
|
|
596
|
+
let currentPageSchema = form.hasAttribute('data-schema-page') ? form.getAttribute('data-schema-page') : 'meta.current_page';
|
|
597
|
+
let totalNumber = resolvePath(response, totalNumberSchema, 1);
|
|
598
|
+
let currentPage = resolvePath(response, currentPageSchema, 1);
|
|
599
|
+
let data = resolvePath(response, schema);
|
|
600
|
+
let emptyMsg = wrapper.hasAttribute('data-empty-msg') ? wrapper.getAttribute('data-empty-msg') : "No results found";
|
|
601
|
+
if (data) {
|
|
602
|
+
tbody.innerHTML = '';
|
|
603
|
+
data.forEach((row, index) => {
|
|
604
|
+
var table_row = document.createElement('tr');
|
|
605
|
+
columns.forEach((col, index) => {
|
|
606
|
+
let cellOutput = '';
|
|
607
|
+
var table_cell = document.createElement('td');
|
|
608
|
+
// Add some data to help with the mobile layout design
|
|
609
|
+
table_cell.setAttribute('data-label', col.innerText);
|
|
610
|
+
if (col.getAttribute('data-output')) {
|
|
611
|
+
var cellTemplate = col.getAttribute('data-output');
|
|
612
|
+
// Use a regex to replace {var} with actual values from the json data
|
|
613
|
+
cellOutput = cellTemplate.replace(new RegExp(/{(.*?)}/, "gm"), function (matched) { return resolvePath(row, matched.replace('{', '').replace('}', '')); });
|
|
614
|
+
}
|
|
615
|
+
// If an output array is defined then the content is going to made of of multiple values from an array
|
|
616
|
+
if (col.hasAttribute('data-output-array')) {
|
|
617
|
+
var cellTemplate = col.getAttribute('data-output');
|
|
618
|
+
let arrValue = resolvePath(row, cellTemplate.replace('{', '').replace('}', ''));
|
|
619
|
+
cellOutput = "";
|
|
620
|
+
arrValue.forEach((rowValue, i) => {
|
|
621
|
+
let cellTemplateValue = col.getAttribute('data-output-array');
|
|
622
|
+
let cellOutputValue = "";
|
|
623
|
+
// If we need to transform some of the data
|
|
624
|
+
if (col.hasAttribute('data-output-array-property') && col.hasAttribute('data-output-array-transform')) {
|
|
625
|
+
const propertyValue = resolvePath(rowValue, col.getAttribute('data-output-array-property'));
|
|
626
|
+
const transforms = JSON.parse(col.getAttribute('data-output-array-transform'));
|
|
627
|
+
const transformValue = transforms[propertyValue];
|
|
628
|
+
cellOutputValue = cellTemplateValue.replace(`{${col.getAttribute('data-output-array-property')}}`, transformValue);
|
|
629
|
+
}
|
|
630
|
+
cellOutputValue = cellOutputValue.replace(new RegExp(/{(.*?)}/, "gm"), function (matched) { return resolvePath(rowValue, matched.replace('{', '').replace('}', '')); });
|
|
631
|
+
cellOutput += cellOutputValue;
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
if (col.hasAttribute('data-transform')) {
|
|
635
|
+
const transforms = JSON.parse(col.getAttribute('data-transform'));
|
|
636
|
+
cellOutput = transforms[cellOutput];
|
|
637
|
+
if (!cellOutput && col.hasAttribute('data-default'))
|
|
638
|
+
cellOutput = col.getAttribute('data-default');
|
|
639
|
+
}
|
|
640
|
+
table_cell.innerHTML = cellOutput;
|
|
641
|
+
table_row.appendChild(table_cell);
|
|
642
|
+
});
|
|
643
|
+
tbody.appendChild(table_row);
|
|
644
|
+
});
|
|
645
|
+
createSearchDataList(table, form);
|
|
646
|
+
// Add data to the pagination
|
|
647
|
+
wrapper.setAttribute('data-total', parseInt(totalNumber));
|
|
648
|
+
wrapper.setAttribute('data-page', parseInt(currentPage));
|
|
649
|
+
wrapper.setAttribute('data-pages', Math.ceil(wrapper.getAttribute('data-total') / wrapper.getAttribute('data-show')));
|
|
650
|
+
makeTableFunctional(table, form, pagination, wrapper);
|
|
651
|
+
createPaginationButttons(wrapper, pagination);
|
|
652
|
+
if (parseInt(totalNumber) == 0) {
|
|
653
|
+
tbody.innerHTML = `<tr><td colspan="100%"><span>${emptyMsg}</span></td></tr>`;
|
|
516
654
|
}
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
655
|
+
wrapper.classList.remove('table--loading');
|
|
656
|
+
window.dataLayer = window.dataLayer || [];
|
|
657
|
+
window.dataLayer.push({
|
|
658
|
+
"event": "Ajax table loaded",
|
|
659
|
+
"url": ajaxURL,
|
|
660
|
+
"formData": queryString
|
|
661
|
+
});
|
|
662
|
+
}
|
|
663
|
+
else {
|
|
664
|
+
tbody.innerHTML = '<tr><td colspan="100%"><span>Error loading table</span></td></tr>';
|
|
665
|
+
}
|
|
666
|
+
// Pass post data back to the page
|
|
667
|
+
if (form.hasAttribute('data-ajax-post')) {
|
|
668
|
+
const http = new XMLHttpRequest();
|
|
669
|
+
http.open('GET', `${window.location.href}?ajax=true&${queryString}`);
|
|
670
|
+
http.send();
|
|
671
|
+
}
|
|
524
672
|
});
|
|
525
|
-
createSearchDataList(table, form);
|
|
526
|
-
// Add data to the pagination
|
|
527
|
-
makeTableFunctional(table, form, pagination, wrapper);
|
|
528
|
-
wrapper.setAttribute('data-total', (response.meta.total ? response.meta.total : 1));
|
|
529
|
-
wrapper.setAttribute('data-page', (response.meta.current_page ? response.meta.current_page : 1));
|
|
530
|
-
wrapper.setAttribute('data-pages', Math.ceil(wrapper.getAttribute('data-total') / wrapper.getAttribute('data-show')));
|
|
531
|
-
createPaginationButttons(wrapper, pagination);
|
|
532
|
-
if (response.data.length == 0) {
|
|
533
|
-
tbody.innerHTML = '<tr><td colspan="100%"><span class="h4 m-0">No results found</span></td></tr>';
|
|
534
|
-
}
|
|
535
673
|
}
|
|
536
|
-
|
|
537
|
-
|
|
674
|
+
catch (error) {
|
|
675
|
+
console.log(error);
|
|
538
676
|
}
|
|
539
677
|
});
|
|
540
678
|
};
|
|
541
679
|
export const formatCell = (format, cellOutput) => {
|
|
542
680
|
switch (format) {
|
|
681
|
+
case 'datetime':
|
|
682
|
+
return new Date(cellOutput).toLocaleDateString('en-gb', { weekday: 'short', year: "2-digit", month: "long", day: "numeric", }) + " " + new Date(cellOutput).toLocaleTimeString("en-gb", { hour: "2-digit", minute: "2-digit" });
|
|
543
683
|
case 'date':
|
|
544
|
-
|
|
545
|
-
break;
|
|
684
|
+
return new Date(cellOutput).toLocaleDateString('en-gb', { year: "2-digit", month: "long", day: "numeric" });
|
|
546
685
|
case 'capitalise':
|
|
547
|
-
cellOutput = ucfirst(cellOutput);
|
|
548
|
-
break;
|
|
686
|
+
return cellOutput = ucfirst(cellOutput);
|
|
549
687
|
}
|
|
550
|
-
return cellOutput;
|
|
551
688
|
};
|