@iamproperty/components 2.7.8 → 2.8.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/.DS_Store +0 -0
- package/assets/css/core.min.css +1 -1
- package/assets/css/core.min.css.map +1 -1
- package/assets/css/email.min.css +1 -1
- package/assets/css/email.min.css.map +1 -1
- package/assets/css/error.min.css +1 -1
- package/assets/css/error.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/main.js +0 -11
- package/assets/js/modules/helpers.js +1 -23
- package/assets/js/scripts.bundle.js +279 -192
- 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/sass/components/tabs.scss +5 -18
- package/assets/sass/elements/panel.scss +1 -1
- package/assets/sass/foundations/brand.scss +2 -1
- package/assets/sass/foundations/reboot.scss +0 -1
- package/assets/svg/logo.svg +15 -9
- package/dist/components.common.js +27 -41
- package/dist/components.common.js.map +1 -1
- package/dist/components.css +1 -1
- package/dist/components.css.map +1 -1
- package/dist/components.umd.js +27 -41
- package/dist/components.umd.js.map +1 -1
- package/dist/components.umd.min.js +1 -1
- package/dist/components.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/src/.DS_Store +0 -0
- package/src/components/Tabs/Tabs.vue +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Bootstrap
|
|
2
|
+
* Bootstrap v3.2.0
|
|
3
3
|
* Copyright 2011-2022 [object Object]
|
|
4
4
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
5
5
|
*/
|
|
@@ -8,29 +8,28 @@
|
|
|
8
8
|
factory();
|
|
9
9
|
})((function () { 'use strict';
|
|
10
10
|
|
|
11
|
-
/**
|
|
12
|
-
* Global helper functions to help maintain and enhance framework elements.
|
|
13
|
-
* @module Helpers
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
11
|
/**
|
|
17
12
|
* Add global classes used by the CSS and later JavaScript.
|
|
18
13
|
* @param {HTMLElement} body Dom element, this doesn't have to be the body but it is recommended.
|
|
14
|
+
* @return {void}
|
|
19
15
|
*/
|
|
20
16
|
var addBodyClasses = body => {
|
|
21
17
|
body.classList.add("js-enabled");
|
|
22
|
-
|
|
23
18
|
if (navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > 0) {
|
|
24
19
|
body.classList.add("ie");
|
|
25
20
|
}
|
|
26
|
-
|
|
27
21
|
return null;
|
|
28
22
|
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Global helper functions to help maintain and enhance framework elements.
|
|
26
|
+
* @module Helpers
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
29
|
/**
|
|
30
30
|
* Add global events.
|
|
31
31
|
* @param {HTMLElement} body Dom element, this doesn't have to be the body but it is recommended.
|
|
32
32
|
*/
|
|
33
|
-
|
|
34
33
|
var addGlobalEvents = body => {
|
|
35
34
|
window.addEventListener('hashchange', function () {
|
|
36
35
|
var hash = location.hash.replace('#', '');
|
|
@@ -40,11 +39,11 @@
|
|
|
40
39
|
}, false);
|
|
41
40
|
return null;
|
|
42
41
|
};
|
|
42
|
+
|
|
43
43
|
/**
|
|
44
|
-
* Check if an element contains certain elements that needs enhancing with the JavaScript helpers, it is recommended to do this on the page body after the dom is loaded. Elements that are loaded via ajax should also run this function.
|
|
44
|
+
* Check if an element contains certain elements that needs enhancing with the JavaScript helpers, it is recommended to do this on the page body after the dom is loaded. Elements that are loaded via ajax should also run this function.
|
|
45
45
|
* @param {HTMLElement} element Dom element, this doesn't have to be the body but it is recommended.
|
|
46
46
|
*/
|
|
47
|
-
|
|
48
47
|
var checkElements = element => {
|
|
49
48
|
// Tables
|
|
50
49
|
Array.from(element.querySelectorAll('table')).forEach((table, index) => {
|
|
@@ -52,22 +51,22 @@
|
|
|
52
51
|
tableWrap(table);
|
|
53
52
|
});
|
|
54
53
|
};
|
|
54
|
+
|
|
55
55
|
/**
|
|
56
56
|
* Wrap tables with a table wrapper div to help maintain its responsive design.
|
|
57
57
|
* @param {HTMLElement} table Dom table element
|
|
58
58
|
*/
|
|
59
|
-
|
|
60
59
|
var tableWrap = table => {
|
|
61
60
|
if (!table.parentNode.classList.contains('table__wrapper')) {
|
|
62
61
|
var tableHTML = table.outerHTML;
|
|
63
62
|
table.outerHTML = "<div class=\"table__wrapper\">".concat(tableHTML, "</div>");
|
|
64
63
|
}
|
|
65
64
|
};
|
|
65
|
+
|
|
66
66
|
/**
|
|
67
67
|
* Creates data attributes to be used by the CSS for mobile views.
|
|
68
68
|
* @param {HTMLElement} table Dom table element
|
|
69
69
|
*/
|
|
70
|
-
|
|
71
70
|
var tableStacked = table => {
|
|
72
71
|
var colHeadings = Array.from(table.querySelectorAll('thead th'));
|
|
73
72
|
var colRows = Array.from(table.querySelectorAll('tbody tr'));
|
|
@@ -75,7 +74,6 @@
|
|
|
75
74
|
var cells = Array.from(row.querySelectorAll('th, td'));
|
|
76
75
|
cells.forEach((cell, cellIndex) => {
|
|
77
76
|
var heading = colHeadings[cellIndex];
|
|
78
|
-
|
|
79
77
|
if (typeof heading != "undefined") {
|
|
80
78
|
var tempDiv = document.createElement("div");
|
|
81
79
|
tempDiv.innerHTML = heading.innerHTML;
|
|
@@ -86,11 +84,12 @@
|
|
|
86
84
|
});
|
|
87
85
|
};
|
|
88
86
|
var isNumeric = function isNumeric(str) {
|
|
89
|
-
if (typeof str != "string") return false; // we only process strings!
|
|
90
|
-
|
|
91
|
-
|
|
87
|
+
if (typeof str != "string") return false; // we only process strings!
|
|
88
|
+
return !isNaN(str) &&
|
|
89
|
+
// use type coercion to parse the _entirety_ of the string (`parseFloat` alone does not do this)...
|
|
92
90
|
!isNaN(parseFloat(str)); // ...and ensure strings of whitespace fail
|
|
93
91
|
};
|
|
92
|
+
|
|
94
93
|
var zeroPad = (num, places) => String(num).padStart(places, '0');
|
|
95
94
|
|
|
96
95
|
var navbar = element => {
|
|
@@ -102,13 +101,15 @@
|
|
|
102
101
|
if (window.matchMedia('(min-width: 62em)').matches) detail.removeAttribute('open');
|
|
103
102
|
}, false);
|
|
104
103
|
});
|
|
105
|
-
|
|
106
|
-
var
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
104
|
+
if ('IntersectionObserver' in window) {
|
|
105
|
+
var observer = new IntersectionObserver(_ref => {
|
|
106
|
+
var [e] = _ref;
|
|
107
|
+
return e.target.classList.toggle("is-stuck", e.intersectionRatio < 1);
|
|
108
|
+
}, {
|
|
109
|
+
threshold: [1]
|
|
110
|
+
});
|
|
111
|
+
observer.observe(element);
|
|
112
|
+
}
|
|
112
113
|
};
|
|
113
114
|
|
|
114
115
|
function table(tableElement) {
|
|
@@ -120,10 +121,10 @@
|
|
|
120
121
|
var filteredEvent = new Event('filtered');
|
|
121
122
|
var reorderedEvent = new Event('reordered');
|
|
122
123
|
var randID = 'table_' + Math.random().toString(36).substr(2, 9); // Random to make sure IDs created are unique
|
|
123
|
-
|
|
124
124
|
var draggedRow;
|
|
125
|
-
tableElement.setAttribute('id', randID);
|
|
125
|
+
tableElement.setAttribute('id', randID);
|
|
126
126
|
|
|
127
|
+
// #region Sortable
|
|
127
128
|
var sortTable = function sortTable(sortBy, sort) {
|
|
128
129
|
// Create an array from the table rows, the index created is then used to sort the array
|
|
129
130
|
var tableArr = [];
|
|
@@ -135,37 +136,45 @@
|
|
|
135
136
|
row: tableRow
|
|
136
137
|
};
|
|
137
138
|
tableArr.push(dataRow);
|
|
138
|
-
});
|
|
139
|
+
});
|
|
139
140
|
|
|
140
|
-
|
|
141
|
+
// Sort array
|
|
142
|
+
tableArr.sort((a, b) => a.index > b.index ? 1 : -1);
|
|
141
143
|
|
|
142
|
-
|
|
144
|
+
// Reverse if descending
|
|
145
|
+
if (sort == "descending") tableArr = tableArr.reverse();
|
|
143
146
|
|
|
147
|
+
// Create a string to return and populate the tbody
|
|
144
148
|
var strTbody = '';
|
|
145
149
|
tableArr.forEach((tableRow, index) => {
|
|
146
150
|
strTbody += tableRow.row.outerHTML;
|
|
147
151
|
});
|
|
148
|
-
tbody.innerHTML = strTbody;
|
|
152
|
+
tbody.innerHTML = strTbody;
|
|
149
153
|
|
|
154
|
+
// Dispatch the sortable event
|
|
150
155
|
tableElement.dispatchEvent(sortedEvent);
|
|
151
|
-
};
|
|
152
|
-
|
|
156
|
+
};
|
|
153
157
|
|
|
158
|
+
// Declare event handlers
|
|
154
159
|
tableElement.addEventListener('click', function (e) {
|
|
155
160
|
for (var target = e.target; target && target != this; target = target.parentNode) {
|
|
156
161
|
if (target.matches('[data-sortable]')) {
|
|
157
162
|
// Get current sort order
|
|
158
|
-
var sort = target.getAttribute('aria-sort') == "ascending" ? "descending" : "ascending";
|
|
163
|
+
var sort = target.getAttribute('aria-sort') == "ascending" ? "descending" : "ascending";
|
|
159
164
|
|
|
165
|
+
// unset sort attributes
|
|
160
166
|
Array.from(tableElement.querySelectorAll('[data-sortable]')).forEach((col, index) => {
|
|
161
167
|
col.setAttribute('aria-sort', 'none');
|
|
162
|
-
});
|
|
168
|
+
});
|
|
163
169
|
|
|
164
|
-
|
|
170
|
+
// Set the sort order attribute
|
|
171
|
+
target.setAttribute('aria-sort', sort);
|
|
165
172
|
|
|
173
|
+
// Save the sort options on the table element so that it can be re-sorted later
|
|
166
174
|
tableElement.setAttribute('data-sort', sort);
|
|
167
|
-
tableElement.setAttribute('data-sortBy', target.textContent);
|
|
175
|
+
tableElement.setAttribute('data-sortBy', target.textContent);
|
|
168
176
|
|
|
177
|
+
// Sort the table
|
|
169
178
|
sortTable(target.textContent, sort);
|
|
170
179
|
Array.from(tableElement.querySelectorAll('tr[draggable]')).forEach((tableRow, index) => {
|
|
171
180
|
tableRow.removeAttribute('draggable');
|
|
@@ -173,8 +182,9 @@
|
|
|
173
182
|
break;
|
|
174
183
|
}
|
|
175
184
|
}
|
|
176
|
-
}, false);
|
|
185
|
+
}, false);
|
|
177
186
|
|
|
187
|
+
// On page load check if the table should be pre-sorted, if so trigger a click
|
|
178
188
|
if (tableElement.getAttribute('data-sortBy')) {
|
|
179
189
|
var sort = tableElement.getAttribute('data-sort') == "ascending" ? "descending" : "ascending";
|
|
180
190
|
Array.from(tableElement.querySelectorAll('[data-sortable]')).forEach((col, index) => {
|
|
@@ -183,36 +193,39 @@
|
|
|
183
193
|
col.click();
|
|
184
194
|
}
|
|
185
195
|
});
|
|
186
|
-
}
|
|
187
|
-
// #region Filters
|
|
196
|
+
}
|
|
188
197
|
|
|
198
|
+
// #endregion Sortable
|
|
189
199
|
|
|
200
|
+
// #region Filters
|
|
190
201
|
var createFilterForm = function createFilterForm(count) {
|
|
191
202
|
// Create wrapper div
|
|
192
203
|
var form = document.createElement("div");
|
|
193
204
|
form.classList.add('table__filters');
|
|
194
205
|
form.classList.add('row');
|
|
195
206
|
form.classList.add('pt-1');
|
|
196
|
-
form.classList.add('pb-3');
|
|
207
|
+
form.classList.add('pb-3');
|
|
197
208
|
|
|
198
|
-
|
|
209
|
+
// Create the filter options array
|
|
210
|
+
var filterColumns = Array.from(tableElement.querySelectorAll('th[data-filterable]'));
|
|
199
211
|
|
|
212
|
+
// Populate a list of searchable terms from the cells of the columns that could be used as a filter
|
|
200
213
|
var searchableTerms = {};
|
|
201
214
|
filterColumns.forEach((columnHeading, index) => {
|
|
202
215
|
Array.from(tableElement.querySelectorAll('td[data-label="' + columnHeading.textContent + '"]')).forEach((label, index) => {
|
|
203
216
|
searchableTerms[label.textContent] = label.textContent;
|
|
204
217
|
});
|
|
205
|
-
});
|
|
218
|
+
});
|
|
206
219
|
|
|
220
|
+
// Create the form
|
|
207
221
|
var filterTitle = filterColumns.length == 1 ? "Filter by " + filterColumns[0].textContent : "Filter"; // Update title if only one filter is chosen
|
|
208
|
-
|
|
209
222
|
var checkboxClass = filterColumns.length == 1 ? "d-none" : "d-sm-flex"; // Hide controls when only one filter is chosen
|
|
210
223
|
|
|
211
|
-
form.innerHTML = "<div class=\"col-sm-6 col-md-4 pb-3\">\n <div class=\"form-control__wrapper form-control-inline mb-0\">\n <label for=\"".concat(randID, "_filter\" class=\"form-label\">").concat(filterTitle, ":</label>\n <input type=\"search\" name=\"").concat(randID, "_filter\" id=\"").concat(randID, "_filter\" class=\"form-control form-control-sm\" placeholder=\"\" list=\"").concat(randID, "_list\" />\n </div>\n <datalist id=\"").concat(randID, "_list\">\n ").concat(Object.keys(searchableTerms).map(term => "<option value=\"".concat(term, "\"></option>")).join(""), "\n </datalist>\n</div>\n<div class=\"col-md-8 align-items-center pb-3 ").concat(checkboxClass, "\">\n ").concat("<span class=\"pe-3 text-nowrap h5 mb-0\">Filter by: </span>" + filterColumns.map(column => "<div class=\"form-check pe-3 mt-0 mb-0\"><input class=\"form-check-input\" type=\"checkbox\" id=\"".concat(randID, "_").concat(column.textContent.replace(' ', '_').toLowerCase(), "\" checked=\"checked\" /><label class=\"form-check-label text-nowrap\" for=\"").concat(randID, "_").concat(column.textContent.replace(' ', '_').toLowerCase(), "\">").concat(column.textContent, "</label></div>")).join(""), "\n</div>");
|
|
224
|
+
form.innerHTML = "<div class=\"col-sm-6 col-md-4 pb-3\">\n <div class=\"form-control__wrapper form-control-inline mb-0\">\n <label for=\"".concat(randID, "_filter\" class=\"form-label\">").concat(filterTitle, ":</label>\n <input type=\"search\" name=\"").concat(randID, "_filter\" id=\"").concat(randID, "_filter\" class=\"form-control form-control-sm\" placeholder=\"\" list=\"").concat(randID, "_list\" />\n </div>\n <datalist id=\"").concat(randID, "_list\">\n ").concat(Object.keys(searchableTerms).map(term => "<option value=\"".concat(term, "\"></option>")).join(""), "\n </datalist>\n</div>\n<div class=\"col-md-8 align-items-center pb-3 ").concat(checkboxClass, "\">\n ").concat("<span class=\"pe-3 text-nowrap h5 mb-0\">Filter by: </span>" + filterColumns.map(column => "<div class=\"form-check pe-3 mt-0 mb-0\"><input class=\"form-check-input\" type=\"checkbox\" id=\"".concat(randID, "_").concat(column.textContent.replace(' ', '_').toLowerCase(), "\" checked=\"checked\" /><label class=\"form-check-label text-nowrap\" for=\"").concat(randID, "_").concat(column.textContent.replace(' ', '_').toLowerCase(), "\">").concat(column.textContent, "</label></div>")).join(""), "\n</div>");
|
|
212
225
|
|
|
226
|
+
// Add before the actual table
|
|
213
227
|
tableElement.prepend(form);
|
|
214
228
|
};
|
|
215
|
-
|
|
216
229
|
var filterTable = function filterTable(searchTerm) {
|
|
217
230
|
// Create an array of rows that match the search term
|
|
218
231
|
var tableArr = [];
|
|
@@ -221,48 +234,53 @@
|
|
|
221
234
|
var rowSearchString = '';
|
|
222
235
|
Array.from(tableElement.querySelectorAll('[type="checkbox"]:checked + label')).forEach((label, index) => {
|
|
223
236
|
rowSearchString += tableRow.querySelector('td[data-label="' + label.textContent + '"]').textContent + ' | ';
|
|
224
|
-
});
|
|
237
|
+
});
|
|
225
238
|
|
|
239
|
+
// Check if the table row search string contains the search term
|
|
226
240
|
if (rowSearchString.indexOf(searchTerm) >= 0) {
|
|
227
241
|
var dataRow = {
|
|
228
242
|
row: tableRow
|
|
229
243
|
};
|
|
230
244
|
tableArr.push(dataRow);
|
|
231
245
|
}
|
|
232
|
-
});
|
|
246
|
+
});
|
|
233
247
|
|
|
248
|
+
// Create a string to return and populate the tbody
|
|
234
249
|
var strTbody = '';
|
|
235
250
|
tableArr.forEach((tableRow, index) => {
|
|
236
251
|
strTbody += tableRow.row.outerHTML;
|
|
237
252
|
});
|
|
238
|
-
tbody.innerHTML = strTbody;
|
|
253
|
+
tbody.innerHTML = strTbody;
|
|
239
254
|
|
|
255
|
+
// Dispatch the filter event.
|
|
240
256
|
tableElement.dispatchEvent(filteredEvent);
|
|
241
257
|
};
|
|
242
|
-
|
|
243
258
|
var createFilterList = function createFilterList() {
|
|
244
259
|
// Check which options are checked
|
|
245
260
|
var filterOptions = [];
|
|
246
261
|
Array.from(tableElement.querySelectorAll('[type="checkbox"]:checked + label')).forEach((label, index) => {
|
|
247
262
|
filterOptions.push(label.textContent);
|
|
248
|
-
});
|
|
263
|
+
});
|
|
249
264
|
|
|
265
|
+
// Build up the list of searchable terms
|
|
250
266
|
var searchableTerms = [];
|
|
251
267
|
filterOptions.forEach((option, index) => {
|
|
252
268
|
Array.from(tableElement.querySelectorAll('td[data-label="' + option + '"]')).forEach((label, index) => {
|
|
253
269
|
searchableTerms[label.textContent] = label.textContent;
|
|
254
270
|
});
|
|
255
|
-
});
|
|
271
|
+
});
|
|
256
272
|
|
|
273
|
+
// Rebuild the list
|
|
257
274
|
var dataList = tableElement.querySelector('datalist');
|
|
258
275
|
dataList.innerHTML = Object.keys(searchableTerms).map(term => "<option value=\"".concat(term, "\"></option>")).join("");
|
|
259
|
-
};
|
|
260
|
-
|
|
276
|
+
};
|
|
261
277
|
|
|
278
|
+
// On page load check if filters are needed
|
|
262
279
|
if (Array.from(tableElement.querySelectorAll('[data-filterable]')).length) {
|
|
263
280
|
// Create the filter options
|
|
264
|
-
createFilterForm(tableElement, Array.from(tableElement.querySelectorAll('[data-filterable]')).length);
|
|
281
|
+
createFilterForm(tableElement, Array.from(tableElement.querySelectorAll('[data-filterable]')).length);
|
|
265
282
|
|
|
283
|
+
// Add event handlers for the filter options
|
|
266
284
|
tableElement.addEventListener('keyup', function (e) {
|
|
267
285
|
for (var target = e.target; target && target != this; target = target.parentNode) {
|
|
268
286
|
if (target.matches('input[type="search"]')) {
|
|
@@ -288,31 +306,28 @@
|
|
|
288
306
|
}
|
|
289
307
|
}
|
|
290
308
|
});
|
|
291
|
-
}
|
|
292
|
-
// #
|
|
293
|
-
|
|
309
|
+
}
|
|
310
|
+
// #endregion Filters
|
|
294
311
|
|
|
312
|
+
// #region Pagination
|
|
295
313
|
var paginateRows = function paginateRows(show, page) {
|
|
296
314
|
// Create some inline CSS to control what is viewed on the table, unline the filters we are just hiding the rable rows not removing them from the DOM.
|
|
297
315
|
var style = document.getElementById(randID + '_style');
|
|
298
|
-
|
|
299
316
|
if (style == null) {
|
|
300
317
|
style = document.createElement("style");
|
|
301
318
|
style.setAttribute('id', randID + '_style');
|
|
302
319
|
}
|
|
303
|
-
|
|
304
320
|
var startShowing = show * (page - 1) + 1;
|
|
305
321
|
var stopShowing = show * page;
|
|
306
322
|
style.innerHTML = "\n #".concat(randID, " tbody tr {\n display: none;\n }\n #").concat(randID, " tbody tr:nth-child(").concat(startShowing, "),\n #").concat(randID, " tbody tr:nth-child(").concat(startShowing, ") ~ tr{\n display: block;\n }\n @media screen and (min-width: 36em) {\n #").concat(randID, " tbody tr:nth-child(").concat(startShowing, "),\n #").concat(randID, " tbody tr:nth-child(").concat(startShowing, ") ~ tr{\n display: table-row;\n }\n }\n #").concat(randID, " tbody tr:nth-child(").concat(stopShowing, ") ~ tr{\n display: none;\n }\n ");
|
|
307
323
|
tableElement.append(style);
|
|
308
|
-
};
|
|
309
|
-
|
|
324
|
+
};
|
|
310
325
|
|
|
326
|
+
// On page load check if the table should be paginated
|
|
311
327
|
if (tableElement.getAttribute('data-show')) {
|
|
312
328
|
var show = parseInt(tableElement.getAttribute('data-show'));
|
|
313
329
|
var page = parseInt(tableElement.getAttribute('data-page')) ? parseInt(tableElement.getAttribute('data-page')) : 1;
|
|
314
330
|
var totalRows = tableElement.querySelectorAll('tbody tr').length;
|
|
315
|
-
|
|
316
331
|
if (show < totalRows) {
|
|
317
332
|
paginateRows(show, page);
|
|
318
333
|
createPaginationForm(randID, tableElement, show, page, totalRows);
|
|
@@ -343,18 +358,18 @@
|
|
|
343
358
|
}
|
|
344
359
|
});
|
|
345
360
|
}
|
|
346
|
-
}
|
|
361
|
+
}
|
|
362
|
+
// #endregion Pagination
|
|
363
|
+
|
|
347
364
|
// #region Reorderable
|
|
348
365
|
// Set the row thats being dragged and copy the row
|
|
349
|
-
|
|
350
|
-
|
|
351
366
|
function setDraggedRow(e) {
|
|
352
367
|
e.dataTransfer.setData("text/plain", e.target.id);
|
|
353
368
|
draggedRow = e.target;
|
|
354
369
|
e.target.classList.add('tr--dragging');
|
|
355
|
-
}
|
|
356
|
-
|
|
370
|
+
}
|
|
357
371
|
|
|
372
|
+
// Create the order column and event handler for rows
|
|
358
373
|
var setReorderRows = function setReorderRows() {
|
|
359
374
|
Array.from(tbody.querySelectorAll('tr')).forEach((tableRow, index) => {
|
|
360
375
|
// Create column if not already created
|
|
@@ -363,36 +378,38 @@
|
|
|
363
378
|
orderColumn.innerHTML = index + 1;
|
|
364
379
|
orderColumn.setAttribute('data-label', 'Order');
|
|
365
380
|
tableRow.prepend(orderColumn);
|
|
366
|
-
}
|
|
367
|
-
|
|
381
|
+
}
|
|
368
382
|
|
|
383
|
+
// Make draggable
|
|
369
384
|
tableRow.setAttribute('id', randID + '_row_' + (index + 1));
|
|
370
385
|
tableRow.setAttribute('data-order', index + 1);
|
|
371
386
|
tableRow.setAttribute('draggable', 'true');
|
|
372
387
|
tableRow.addEventListener("dragstart", setDraggedRow);
|
|
373
388
|
});
|
|
374
389
|
};
|
|
375
|
-
|
|
376
|
-
if (tableElement.getAttribute('data-reorder')) {
|
|
390
|
+
if (tableElement.getAttribute('data-reorder') && tableElement.getAttribute('data-reorder') != "false") {
|
|
377
391
|
// Add column heading
|
|
378
392
|
var orderHeading = document.createElement('th');
|
|
379
393
|
orderHeading.innerHTML = 'Order';
|
|
380
394
|
orderHeading.title = 'Click here to enable re-ordering via drag and drop';
|
|
381
395
|
orderHeading.classList.add('table-order-reset');
|
|
382
396
|
thead.querySelector('tr').prepend(orderHeading);
|
|
383
|
-
setReorderRows();
|
|
397
|
+
setReorderRows();
|
|
384
398
|
|
|
399
|
+
// Reset order button
|
|
385
400
|
tableElement.addEventListener('click', function (e) {
|
|
386
401
|
for (var target = e.target; target && target != this; target = target.parentNode) {
|
|
387
402
|
if (target.matches('.table-order-reset')) {
|
|
388
403
|
// unset sort attributes
|
|
389
404
|
Array.from(tableElement.querySelectorAll('[data-sortable]')).forEach((col, index) => {
|
|
390
405
|
col.setAttribute('aria-sort', 'none');
|
|
391
|
-
});
|
|
406
|
+
});
|
|
392
407
|
|
|
408
|
+
// Save the sort options on the table element so that it can be re-sorted later
|
|
393
409
|
tableElement.removeAttribute('data-sort');
|
|
394
|
-
tableElement.removeAttribute('data-sortBy');
|
|
410
|
+
tableElement.removeAttribute('data-sortBy');
|
|
395
411
|
|
|
412
|
+
// Sort the table
|
|
396
413
|
sortTable('Order', 'ascending');
|
|
397
414
|
Array.from(tableElement.querySelectorAll('tbody tr')).forEach((tableRow, index) => {
|
|
398
415
|
tableRow.setAttribute('draggable', 'true');
|
|
@@ -409,7 +426,6 @@
|
|
|
409
426
|
// prevent default to allow drop
|
|
410
427
|
e.preventDefault();
|
|
411
428
|
e.dataTransfer.dropEffect = "move";
|
|
412
|
-
|
|
413
429
|
for (var target = e.target; target && target != this; target = target.parentNode) {
|
|
414
430
|
if (target.matches('[data-reorder] tbody tr')) {
|
|
415
431
|
target.classList.add('tr--dropable');
|
|
@@ -419,7 +435,6 @@
|
|
|
419
435
|
document.addEventListener("dragleave", function (e) {
|
|
420
436
|
// prevent default to allow drop
|
|
421
437
|
e.preventDefault();
|
|
422
|
-
|
|
423
438
|
for (var target = e.target; target && target != this; target = target.parentNode) {
|
|
424
439
|
if (target.matches('[data-reorder] tbody tr')) {
|
|
425
440
|
target.classList.remove('tr--dropable');
|
|
@@ -428,13 +443,13 @@
|
|
|
428
443
|
}, false);
|
|
429
444
|
document.addEventListener("drop", function (e) {
|
|
430
445
|
e.preventDefault();
|
|
431
|
-
|
|
432
446
|
for (var target = e.target; target && target != this; target = target.parentNode) {
|
|
433
447
|
if (target.matches('[data-reorder] tbody tr')) {
|
|
434
448
|
if (target.parentNode != null && draggedRow.parentNode != null && target != draggedRow) {
|
|
435
449
|
draggedRow.parentNode.removeChild(draggedRow);
|
|
436
|
-
if (draggedRow.getAttribute('data-order') > target.getAttribute('data-order')) target.parentNode.insertBefore(draggedRow, target);else target.parentNode.insertBefore(draggedRow, target.nextElementSibling);
|
|
450
|
+
if (draggedRow.getAttribute('data-order') > target.getAttribute('data-order')) target.parentNode.insertBefore(draggedRow, target);else target.parentNode.insertBefore(draggedRow, target.nextElementSibling);
|
|
437
451
|
|
|
452
|
+
// Re label the rows
|
|
438
453
|
Array.from(tbody.querySelectorAll('tr')).forEach((tableRowOrder, index) => {
|
|
439
454
|
tableRowOrder.classList.remove('tr--dragging');
|
|
440
455
|
tableRowOrder.classList.remove('tr--dropable');
|
|
@@ -443,32 +458,27 @@
|
|
|
443
458
|
});
|
|
444
459
|
tableElement.dispatchEvent(reorderedEvent);
|
|
445
460
|
}
|
|
446
|
-
|
|
447
461
|
break;
|
|
448
462
|
}
|
|
449
463
|
}
|
|
450
464
|
}, false);
|
|
451
|
-
}
|
|
452
|
-
//
|
|
453
|
-
|
|
465
|
+
}
|
|
466
|
+
// #endregion Reorderable
|
|
454
467
|
|
|
468
|
+
// Watch for the filterable event and re-sort the tbody
|
|
455
469
|
tableElement.addEventListener('filtered', function (e) {
|
|
456
470
|
if (tableElement.getAttribute('data-sortBy') && tableElement.getAttribute('data-sort')) sortTable(tableElement.getAttribute('data-sortBy'), tableElement.getAttribute('data-sort'));
|
|
457
|
-
|
|
458
471
|
if (tableElement.getAttribute('data-show')) {
|
|
459
472
|
var _show = parseInt(tableElement.getAttribute('data-show'));
|
|
460
|
-
|
|
461
473
|
var _totalRows = tableElement.querySelectorAll('tbody tr').length;
|
|
462
474
|
var tablePagination = tableElement.querySelector('.table__pagination');
|
|
463
475
|
if (tablePagination != null) tablePagination.remove();
|
|
464
|
-
|
|
465
476
|
if (_show < _totalRows) {
|
|
466
477
|
paginateRows(_show, 1);
|
|
467
478
|
createPaginationForm(randID, tableElement, _show, 1, _totalRows);
|
|
468
479
|
createPaginationButttons(randID, tableElement, _show, 1, _totalRows);
|
|
469
480
|
}
|
|
470
481
|
}
|
|
471
|
-
|
|
472
482
|
if (tableElement.getAttribute('data-reorder')) {
|
|
473
483
|
setReorderRows();
|
|
474
484
|
}
|
|
@@ -488,43 +498,41 @@
|
|
|
488
498
|
table(newTable);
|
|
489
499
|
}, false);
|
|
490
500
|
}
|
|
491
|
-
|
|
492
501
|
var createPaginationForm = function createPaginationForm(randID, tableElement, show, page, totalRows) {
|
|
493
502
|
var form = document.createElement("div");
|
|
494
503
|
form.classList.add('table__pagination');
|
|
495
504
|
form.classList.add('row');
|
|
496
505
|
form.classList.add('pt-3');
|
|
497
|
-
form.classList.add('pb-3');
|
|
506
|
+
form.classList.add('pb-3');
|
|
498
507
|
|
|
499
|
-
|
|
508
|
+
// Create the form and create a container div to hold the pagination buttons
|
|
509
|
+
form.innerHTML = "<div class=\"col mw-fit-content mb-3\">\n<div class=\"form-control__wrapper form-control-inline mb-0\">\n <label for=\"".concat(randID, "_showing\" class=\"form-label\">Showing:</label>\n <input type=\"number\" name=\"").concat(randID, "_showing\" id=\"").concat(randID, "_showing\" class=\"form-control form-control-sm showing-input-field\" placeholder=\"\" list=\"").concat(randID, "_pagination\" value=\"").concat(show, "\" min=\"1\" max=\"").concat(totalRows, "\" />\n</div>\n<datalist id=\"").concat(randID, "_pagination\">\n<option value=\"5\">5</option>\n").concat(totalRows > 10 ? "<option value=\"10\">10</option>" : '', "\n").concat(totalRows > 20 ? "<option value=\"20\">20</option>" : '', "\n<option value=\"").concat(totalRows, "\">").concat(totalRows, "</option>\n</datalist>\n</div>\n<div class=\"col mw-fit-content me-auto d-flex align-items-center mb-3\"><span class=\"label\">per page</span></div>\n<div class=\"col mw-fit-content d-sm-flex justify-content-end align-items-center\" id=\"").concat(randID, "_paginationBtns\"></div>");
|
|
500
510
|
|
|
511
|
+
// Add after the actual table
|
|
501
512
|
tableElement.append(form);
|
|
502
513
|
};
|
|
503
514
|
var createPaginationButttons = function createPaginationButttons(randID, tableElement, show, page, totalRows) {
|
|
504
515
|
var paginationButtonsWrapper = document.getElementById(randID + '_paginationBtns');
|
|
505
516
|
if (paginationButtonsWrapper == null) return false;
|
|
506
517
|
var numberPages = Math.ceil(totalRows / show);
|
|
507
|
-
|
|
508
518
|
if (numberPages == 1) {
|
|
509
519
|
// Remore the buttons or dont display any if we dont need them
|
|
510
520
|
paginationButtonsWrapper.innerHTML = '';
|
|
511
521
|
} else if (numberPages < 5) {
|
|
512
522
|
// If less than 5 pages (which fits comfortably on mobile) we display buttons
|
|
513
|
-
var strButtons = '';
|
|
514
523
|
|
|
524
|
+
var strButtons = '';
|
|
515
525
|
for (var i = 1; i <= numberPages; i++) {
|
|
516
526
|
if (i == page) strButtons += "<li class=\"page-item active\" aria-current=\"page\"><span class=\"page-link\">".concat(i, "</span></li>");else strButtons += "<li class=\"page-item\"><button class=\"page-link\" data-page=\"".concat(i, "\">").concat(i, "</button></li>");
|
|
517
527
|
}
|
|
518
|
-
|
|
519
528
|
paginationButtonsWrapper.innerHTML = "<span class=\"pe-2 mb-3\">Page: </span><ul class=\"pagination mb-3\">\n ".concat(page == 1 ? "<li class=\"page-item disabled\"><span class=\"page-link\">Previous</span></li>" : "<li class=\"page-item\"><button class=\"page-link\" data-page=\"".concat(parseInt(page) - 1, "\">Previous</button></li>"), "\n ").concat(strButtons, "\n ").concat(page == numberPages ? "<li class=\"page-item disabled\"><span class=\"page-link\">Next</span></li>" : "<li class=\"page-item\"><button class=\"page-link\" data-page=\"".concat(parseInt(page) + 1, "\">Next</button></li>"), "\n </ul>");
|
|
520
529
|
} else {
|
|
521
530
|
// If more than 5 lets show a select field instead so that we dont have loads and loads of buttons
|
|
522
|
-
var strOptions = '';
|
|
523
531
|
|
|
532
|
+
var strOptions = '';
|
|
524
533
|
for (var _i = 1; _i <= numberPages; _i++) {
|
|
525
534
|
if (_i == page) strOptions += "<option value=\"".concat(_i, "\" selected>Page ").concat(_i, "</option>");else strOptions += "<option value=\"".concat(_i, "\">Page ").concat(_i, "</option>");
|
|
526
535
|
}
|
|
527
|
-
|
|
528
536
|
paginationButtonsWrapper.innerHTML = "\n<div class=\"form-control__wrapper page-number mb-2\">\n<select class=\"form-select\">\n".concat(strOptions, "\n</select>\n</div>\n ");
|
|
529
537
|
}
|
|
530
538
|
};
|
|
@@ -532,8 +540,8 @@
|
|
|
532
540
|
function accordion(accordionElement) {
|
|
533
541
|
// Fetch all the details element.
|
|
534
542
|
if (!accordionElement.classList.contains('accordion--keep-open')) {
|
|
535
|
-
var details = accordionElement.querySelectorAll(":scope > details");
|
|
536
|
-
|
|
543
|
+
var details = accordionElement.querySelectorAll(":scope > details");
|
|
544
|
+
// Add the onclick listeners.
|
|
537
545
|
details.forEach(targetDetail => {
|
|
538
546
|
targetDetail.addEventListener("click", () => {
|
|
539
547
|
// Close all the details that are not targetDetail.
|
|
@@ -545,17 +553,18 @@
|
|
|
545
553
|
});
|
|
546
554
|
});
|
|
547
555
|
}
|
|
548
|
-
|
|
549
556
|
if (window.location.hash && document.querySelector(window.location.hash + ':not([open]) summary')) {
|
|
550
557
|
var detail = document.querySelector(window.location.hash + ' summary');
|
|
551
|
-
detail
|
|
558
|
+
if (detail instanceof HTMLElement) {
|
|
559
|
+
detail.click();
|
|
560
|
+
}
|
|
552
561
|
}
|
|
553
|
-
|
|
554
562
|
window.addEventListener('hashchange', function () {
|
|
555
563
|
if (window.location.hash && document.querySelector(window.location.hash + ' summary')) {
|
|
556
564
|
var _detail = document.querySelector(window.location.hash + ' summary');
|
|
557
|
-
|
|
558
|
-
|
|
565
|
+
if (_detail instanceof HTMLElement) {
|
|
566
|
+
_detail.click();
|
|
567
|
+
}
|
|
559
568
|
}
|
|
560
569
|
});
|
|
561
570
|
}
|
|
@@ -563,14 +572,15 @@
|
|
|
563
572
|
function testimonial(testimonialElement) {
|
|
564
573
|
var scrollTimeout;
|
|
565
574
|
var imagesCarousel = testimonialElement.querySelector('.testimonial__images');
|
|
566
|
-
var itemCount = imagesCarousel.querySelectorAll('img').length;
|
|
575
|
+
var itemCount = imagesCarousel.querySelectorAll('img').length;
|
|
567
576
|
|
|
577
|
+
// If we only have 1 item lets not bother doing anything else
|
|
568
578
|
if (itemCount == 1) {
|
|
569
579
|
return false;
|
|
570
580
|
}
|
|
581
|
+
testimonialElement.classList.add('testimonial--multi');
|
|
571
582
|
|
|
572
|
-
|
|
573
|
-
|
|
583
|
+
// Set where the buttons go to
|
|
574
584
|
var setButtons = function setButtons(scrollTo) {
|
|
575
585
|
var nextButton = testimonialElement.querySelector('.btn-next');
|
|
576
586
|
var prevButton = testimonialElement.querySelector('.btn-prev');
|
|
@@ -579,9 +589,9 @@
|
|
|
579
589
|
nextButton.removeAttribute('disabled');
|
|
580
590
|
prevButton.removeAttribute('disabled');
|
|
581
591
|
if (scrollTo == 1) prevButton.setAttribute('disabled', true);else if (scrollTo == itemCount) nextButton.setAttribute('disabled', true);
|
|
582
|
-
};
|
|
583
|
-
|
|
592
|
+
};
|
|
584
593
|
|
|
594
|
+
// On scroll we need to make sure the buttons get corrected and the next testimonial is shown
|
|
585
595
|
imagesCarousel.addEventListener('scroll', function (e) {
|
|
586
596
|
clearTimeout(scrollTimeout);
|
|
587
597
|
scrollTimeout = setTimeout(function () {
|
|
@@ -589,14 +599,16 @@
|
|
|
589
599
|
var scrollHeight = imagesCarousel.scrollHeight;
|
|
590
600
|
var scrollLeft = imagesCarousel.scrollLeft;
|
|
591
601
|
var scrollDown = imagesCarousel.scrollTop;
|
|
592
|
-
var scrollTo = Math.round(scrollLeft / scrollWidth * itemCount) + 1;
|
|
602
|
+
var scrollTo = Math.round(scrollLeft / scrollWidth * itemCount) + 1;
|
|
593
603
|
|
|
604
|
+
// Change in scroll direction
|
|
594
605
|
if (scrollLeft == 0 && scrollDown != 0) scrollTo = Math.round(scrollDown / scrollHeight * itemCount) + 1;
|
|
595
606
|
testimonialElement.setAttribute('data-show', scrollTo);
|
|
596
607
|
setButtons(scrollTo);
|
|
597
608
|
}, 300);
|
|
598
|
-
}, false);
|
|
609
|
+
}, false);
|
|
599
610
|
|
|
611
|
+
// when the buttons are used we need to make sure the carousel scrolls to the correct place
|
|
600
612
|
testimonialElement.addEventListener('click', function (e) {
|
|
601
613
|
for (var target = e.target; target && target != this; target = target.parentNode) {
|
|
602
614
|
if (target.matches('[data-go]')) {
|
|
@@ -605,8 +617,9 @@
|
|
|
605
617
|
var scrollLeft = 0;
|
|
606
618
|
var scrollWidth = imagesCarousel.scrollWidth;
|
|
607
619
|
var scrollHeight = imagesCarousel.scrollHeight;
|
|
608
|
-
if (scrollWidth > scrollHeight) scrollLeft = Math.floor(scrollWidth * ((scrollTo - 1) / itemCount));else scrollDown = Math.floor(scrollHeight * ((scrollTo - 1) / itemCount));
|
|
620
|
+
if (scrollWidth > scrollHeight) scrollLeft = Math.floor(scrollWidth * ((scrollTo - 1) / itemCount));else scrollDown = Math.floor(scrollHeight * ((scrollTo - 1) / itemCount));
|
|
609
621
|
|
|
622
|
+
// Trigger the scroll
|
|
610
623
|
imagesCarousel.scroll({
|
|
611
624
|
top: scrollDown,
|
|
612
625
|
left: scrollLeft,
|
|
@@ -625,8 +638,9 @@
|
|
|
625
638
|
carouselElement.getAttribute('data-cols');
|
|
626
639
|
var smCols = carouselElement.getAttribute('data-sm-cols');
|
|
627
640
|
var mdCols = carouselElement.getAttribute('data-md-cols');
|
|
628
|
-
carouselElement.querySelector('.carousel__controls a').classList.add('active');
|
|
641
|
+
carouselElement.querySelector('.carousel__controls a').classList.add('active');
|
|
629
642
|
|
|
643
|
+
// On scroll we need to make sure the buttons get corrected and the next testimonial is shown
|
|
630
644
|
carouselInner.addEventListener('scroll', function (e) {
|
|
631
645
|
clearTimeout(scrollTimeout);
|
|
632
646
|
scrollTimeout = setTimeout(function () {
|
|
@@ -638,14 +652,17 @@
|
|
|
638
652
|
Array.from(carouselElement.querySelectorAll('.carousel__controls a')).forEach((link, index) => {
|
|
639
653
|
link.classList.remove('active');
|
|
640
654
|
});
|
|
641
|
-
carouselElement.querySelector('.control-' + targetSlide).classList.add('active');
|
|
655
|
+
carouselElement.querySelector('.control-' + targetSlide).classList.add('active');
|
|
642
656
|
|
|
643
|
-
|
|
657
|
+
// Disable the previous button
|
|
658
|
+
if (targetSlide == 1) carouselElement.querySelector('.btn-prev').setAttribute('disabled', 'disabled');else carouselElement.querySelector('.btn-prev').removeAttribute('disabled');
|
|
644
659
|
|
|
660
|
+
// Disable the next button if the last item is in view
|
|
645
661
|
if (carouselInner.scrollLeft + scrollArea > lastItemOffset) carouselElement.querySelector('.btn-next').setAttribute('disabled', 'disabled');else carouselElement.querySelector('.btn-next').removeAttribute('disabled');
|
|
646
662
|
}, 100);
|
|
647
|
-
}, false);
|
|
663
|
+
}, false);
|
|
648
664
|
|
|
665
|
+
// when the buttons are used we need to make sure the carousel scrolls to the correct place
|
|
649
666
|
carouselElement.addEventListener('click', function (e) {
|
|
650
667
|
for (var target = e.target; target && target != this; target = target.parentNode) {
|
|
651
668
|
if (target.matches('.carousel__controls a')) {
|
|
@@ -677,8 +694,9 @@
|
|
|
677
694
|
break;
|
|
678
695
|
}
|
|
679
696
|
}
|
|
680
|
-
}, false);
|
|
697
|
+
}, false);
|
|
681
698
|
|
|
699
|
+
// Add responsive hide button classes
|
|
682
700
|
if (itemCount == 1) carouselElement.classList.add('hide-btns');
|
|
683
701
|
if (smCols >= itemCount) carouselElement.classList.add('hide-sm-btns');
|
|
684
702
|
if (mdCols >= itemCount) carouselElement.classList.add('hide-md-btns');
|
|
@@ -689,15 +707,17 @@
|
|
|
689
707
|
function inputRange(inputWrapper) {
|
|
690
708
|
inputWrapper.addEventListener('change', function (e) {
|
|
691
709
|
var min = parseInt(inputWrapper.querySelector('[data-min] select,[data-min] input').value);
|
|
692
|
-
var max = parseInt(inputWrapper.querySelector('[data-max] select,[data-max] input').value);
|
|
710
|
+
var max = parseInt(inputWrapper.querySelector('[data-max] select,[data-max] input').value);
|
|
693
711
|
|
|
712
|
+
// Set attributes for input fields
|
|
694
713
|
Array.from(inputWrapper.querySelectorAll('[data-min] input')).forEach((input, index) => {
|
|
695
714
|
input.setAttribute('max', max);
|
|
696
715
|
});
|
|
697
716
|
Array.from(inputWrapper.querySelectorAll('[data-max] input')).forEach((input, index) => {
|
|
698
717
|
input.setAttribute('min', min);
|
|
699
|
-
});
|
|
718
|
+
});
|
|
700
719
|
|
|
720
|
+
// Hide select options if they are higher or lower than the min and max values
|
|
701
721
|
Array.from(inputWrapper.querySelectorAll('[data-min] select option')).forEach((option, index) => {
|
|
702
722
|
if (parseInt(option.getAttribute('value')) > max) option.classList.add('d-none');else option.classList.remove('d-none');
|
|
703
723
|
});
|
|
@@ -706,16 +726,19 @@
|
|
|
706
726
|
});
|
|
707
727
|
}, false);
|
|
708
728
|
}
|
|
709
|
-
|
|
710
729
|
function inputRedirect(inputWrapper) {
|
|
711
730
|
inputWrapper.addEventListener('change', function (e) {
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
731
|
+
if (inputWrapper.matches('[data-value-if]')) {
|
|
732
|
+
var url = inputWrapper.getAttribute('data-redirect');
|
|
733
|
+
var desiredValue = inputWrapper.getAttribute('data-value-if');
|
|
734
|
+
if (inputWrapper.value == desiredValue) document.location.href = url;
|
|
735
|
+
} else {
|
|
736
|
+
if (typeof inputWrapper.value != "undefined") document.location.href = inputWrapper.value;
|
|
737
|
+
}
|
|
715
738
|
}, false);
|
|
716
|
-
}
|
|
717
|
-
|
|
739
|
+
}
|
|
718
740
|
|
|
741
|
+
//
|
|
719
742
|
function multipleFileUploads(wrapper) {
|
|
720
743
|
var fileTenplate = wrapper.querySelector('.row');
|
|
721
744
|
var clone = fileTenplate.cloneNode(true);
|
|
@@ -724,14 +747,15 @@
|
|
|
724
747
|
for (var target = e.target; target && target != this; target = target.parentNode) {
|
|
725
748
|
if (target.matches('[data-add]')) {
|
|
726
749
|
// Add a new row upload file input fields
|
|
750
|
+
|
|
727
751
|
var tempClone = clone.cloneNode(true);
|
|
728
752
|
wrapper.insertBefore(tempClone, target);
|
|
729
753
|
if (addButton.matches('[data-maxfiles]') && Array.from(wrapper.querySelectorAll(':scope > .row')).length >= addButton.dataset.maxfiles) addButton.setAttribute('disabled', 'disabled');
|
|
730
754
|
break;
|
|
731
755
|
}
|
|
732
|
-
|
|
733
756
|
if (target.matches('[data-delete]')) {
|
|
734
757
|
// Delete the current row
|
|
758
|
+
|
|
735
759
|
var row = target.closest('.row');
|
|
736
760
|
row.remove();
|
|
737
761
|
if (addButton.matches('[data-maxfiles]') && Array.from(wrapper.querySelectorAll(':scope > .row')).length < addButton.dataset.maxfiles) addButton.removeAttribute('disabled');
|
|
@@ -739,36 +763,36 @@
|
|
|
739
763
|
}
|
|
740
764
|
}
|
|
741
765
|
}, false);
|
|
742
|
-
}
|
|
743
|
-
|
|
766
|
+
}
|
|
744
767
|
|
|
768
|
+
// Acts as an overall initialise function to trigger other functions.
|
|
745
769
|
function form(formElement) {
|
|
746
770
|
// Check for input range groups
|
|
747
771
|
Array.from(formElement.querySelectorAll('[data-input-range]')).forEach((arrayElement, index) => {
|
|
748
772
|
inputRange(arrayElement);
|
|
749
773
|
});
|
|
750
|
-
Array.from(formElement.querySelectorAll('[data-redirect]
|
|
774
|
+
Array.from(formElement.querySelectorAll('[data-redirect]')).forEach((arrayElement, index) => {
|
|
751
775
|
inputRedirect(arrayElement);
|
|
752
776
|
});
|
|
753
777
|
Array.from(formElement.querySelectorAll('.multiple-file-uploads')).forEach((arrayElement, index) => {
|
|
754
778
|
multipleFileUploads(arrayElement);
|
|
755
|
-
});
|
|
779
|
+
});
|
|
756
780
|
|
|
781
|
+
// Check the file size of a file when uploaded in case it exceeds the max file size set
|
|
757
782
|
formElement.addEventListener('change', function (e) {
|
|
758
783
|
for (var target = e.target; target && target != this; target = target.parentNode) {
|
|
759
784
|
if (target.matches('[type="file"][data-filesize]') && target.files && target.files[0]) {
|
|
760
785
|
var maxAllowedSize = target.dataset.filesize;
|
|
761
|
-
|
|
762
786
|
if (target.files[0].size > maxAllowedSize) {
|
|
763
787
|
target.value = '';
|
|
764
788
|
alert('File too large');
|
|
765
789
|
}
|
|
766
|
-
|
|
767
790
|
break;
|
|
768
791
|
}
|
|
769
792
|
}
|
|
770
|
-
}, false);
|
|
793
|
+
}, false);
|
|
771
794
|
|
|
795
|
+
// When a form is updated we may want to update some of the existing input fields; setting active fields when some data is selected.
|
|
772
796
|
formElement.addEventListener('change', function (e) {
|
|
773
797
|
// Remove disabled attribute when a pre-selected input field equals a certain value
|
|
774
798
|
Array.from(formElement.querySelectorAll('select[data-activeif][data-equals],input[data-activeif][data-equals]')).forEach((arrayElement, index) => {
|
|
@@ -776,15 +800,15 @@
|
|
|
776
800
|
var selector = arrayElement.dataset.activeif;
|
|
777
801
|
var value = arrayElement.dataset.equals;
|
|
778
802
|
var testElement = group.querySelector("select[data-id=\"".concat(selector, "\"],input[data-id=\"").concat(selector, "\"]"));
|
|
779
|
-
|
|
780
803
|
if (testElement.value == value) {
|
|
781
804
|
arrayElement.removeAttribute('disabled');
|
|
782
805
|
} else {
|
|
783
806
|
arrayElement.setAttribute('disabled', 'disabled');
|
|
784
807
|
arrayElement.value = '';
|
|
785
808
|
}
|
|
786
|
-
});
|
|
809
|
+
});
|
|
787
810
|
|
|
811
|
+
// Show this input wrapper when a pre-selected input field equals a certain value
|
|
788
812
|
Array.from(formElement.querySelectorAll('.form-control__wrapper[data-displayif][data-equals]')).forEach((arrayElement, index) => {
|
|
789
813
|
var group = arrayElement.closest('[data-group]') ? arrayElement.closest('[data-group]') : formElement;
|
|
790
814
|
var selector = arrayElement.dataset.activeif;
|
|
@@ -799,10 +823,11 @@
|
|
|
799
823
|
* Integrate YouTube videos as a way of hosting videos without the overhead and worry surrounding hosting vides. i.e. file sizes, performance and accessibility.
|
|
800
824
|
*/
|
|
801
825
|
class youtubeVideo {
|
|
802
|
-
/** @param {
|
|
826
|
+
/** @param {Element} embed dom element */
|
|
803
827
|
constructor(embed) {
|
|
804
|
-
var createEmbed = this.createEmbed;
|
|
828
|
+
var createEmbed = this.createEmbed;
|
|
805
829
|
|
|
830
|
+
// If the scripts is already loaded then lets just create the embed
|
|
806
831
|
if (document.body.classList.contains('youtubeLoaded')) {
|
|
807
832
|
embed.addEventListener('click', function (e) {
|
|
808
833
|
// loop parent nodes from the target to the delegation node
|
|
@@ -818,17 +843,15 @@
|
|
|
818
843
|
this.loadScripts(embed, this.createEmbed);
|
|
819
844
|
}
|
|
820
845
|
}
|
|
846
|
+
|
|
821
847
|
/**
|
|
822
848
|
* Load the YouTube scripts before trying to create the embed
|
|
823
849
|
* @param {HTMLElement} embed dom element
|
|
824
850
|
* @param {Function} createEmbed function to create the embed after script loaded.
|
|
825
851
|
*/
|
|
826
|
-
|
|
827
|
-
|
|
828
852
|
loadScripts(embed, createEmbed) {
|
|
829
853
|
return new Promise((resolve, reject) => {
|
|
830
854
|
var image = new Image();
|
|
831
|
-
|
|
832
855
|
image.onload = function () {
|
|
833
856
|
// This code loads the IFrame Player API code asynchronously.
|
|
834
857
|
var tag = document.createElement('script');
|
|
@@ -836,8 +859,9 @@
|
|
|
836
859
|
var firstScriptTag = document.getElementsByTagName('script')[0];
|
|
837
860
|
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
|
|
838
861
|
document.body.classList.add('youtubeLoaded');
|
|
839
|
-
resolve(true);
|
|
862
|
+
resolve(true);
|
|
840
863
|
|
|
864
|
+
// script has loaded, you can now use it safely
|
|
841
865
|
tag.onload = () => {
|
|
842
866
|
embed.addEventListener('click', function (e) {
|
|
843
867
|
// loop parent nodes from the target to the delegation node
|
|
@@ -851,33 +875,31 @@
|
|
|
851
875
|
}, false);
|
|
852
876
|
};
|
|
853
877
|
};
|
|
854
|
-
|
|
855
878
|
image.onerror = function () {
|
|
856
879
|
reject(false);
|
|
857
880
|
};
|
|
858
|
-
|
|
859
881
|
image.src = "https://youtube.com/favicon.ico";
|
|
860
882
|
});
|
|
861
883
|
}
|
|
884
|
+
|
|
862
885
|
/**
|
|
863
886
|
* Create the YouTube embed after the user has clicked on it.
|
|
864
887
|
* @param {HTMLElement} embed dom element
|
|
865
888
|
*/
|
|
866
|
-
|
|
867
|
-
|
|
868
889
|
createEmbed(embed, target) {
|
|
869
890
|
// If there is more than one video lets make sure there is only one playing at a time.
|
|
870
891
|
if (typeof window.player != "undefined" && typeof window.player.pauseVideo == "function") window.player.pauseVideo();
|
|
871
892
|
var video_id = target.getAttribute('data-id');
|
|
872
|
-
var link_id = target.getAttribute('id');
|
|
893
|
+
var link_id = target.getAttribute('id');
|
|
873
894
|
|
|
895
|
+
// create an id to pass t the script if one isn't present
|
|
874
896
|
if (typeof link_id == 'undefined' || link_id == null) {
|
|
875
897
|
var randLetter = String.fromCharCode(65 + Math.floor(Math.random() * 26));
|
|
876
898
|
link_id = randLetter + Date.now();
|
|
877
899
|
target.setAttribute('id', link_id);
|
|
878
|
-
}
|
|
879
|
-
|
|
900
|
+
}
|
|
880
901
|
|
|
902
|
+
// This function creates an <iframe> (and YouTube player) after the API code downloads.
|
|
881
903
|
function onYouTubeIframeAPIReady() {
|
|
882
904
|
window.player = new YT.Player(link_id, {
|
|
883
905
|
height: '100%',
|
|
@@ -895,18 +917,17 @@
|
|
|
895
917
|
}
|
|
896
918
|
});
|
|
897
919
|
}
|
|
920
|
+
onYouTubeIframeAPIReady();
|
|
898
921
|
|
|
899
|
-
|
|
900
|
-
|
|
922
|
+
// The API will call this function when the video player is ready.
|
|
901
923
|
function onPlayerReady(event) {
|
|
902
924
|
// Play the video straight away
|
|
903
925
|
event.target.playVideo();
|
|
904
|
-
}
|
|
905
|
-
// The function indicates that when playing a video (state=1)
|
|
906
|
-
|
|
926
|
+
}
|
|
907
927
|
|
|
928
|
+
// The API calls this function when the player's state changes.
|
|
929
|
+
// The function indicates that when playing a video (state=1)
|
|
908
930
|
var done = false;
|
|
909
|
-
|
|
910
931
|
function onPlayerStateChange(event) {
|
|
911
932
|
if (event.data == YT.PlayerState.PLAYING && !done) {
|
|
912
933
|
var link = document.getElementById(link_id);
|
|
@@ -915,53 +936,119 @@
|
|
|
915
936
|
}
|
|
916
937
|
}
|
|
917
938
|
}
|
|
918
|
-
|
|
919
939
|
}
|
|
920
940
|
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
}); // Advanced tables
|
|
932
|
-
|
|
933
|
-
Array.from(document.querySelectorAll('.table__wrapper')).forEach((arrayElement, index) => {
|
|
934
|
-
table(arrayElement);
|
|
935
|
-
}); // Accordions
|
|
936
|
-
|
|
937
|
-
Array.from(document.querySelectorAll('.accordion')).forEach((arrayElement, index) => {
|
|
938
|
-
accordion(arrayElement);
|
|
939
|
-
}); // Testimonial
|
|
941
|
+
var modal = element => {
|
|
942
|
+
var links = element.querySelectorAll('.modal__outer a, .modal__outer button');
|
|
943
|
+
var firstLink = links[0];
|
|
944
|
+
var lastLink = links[links.length - 1];
|
|
945
|
+
var modalID = element.getAttribute('id');
|
|
946
|
+
var closeModal = function closeModal() {
|
|
947
|
+
var button = document.querySelector('[href="' + window.location.hash + '"]');
|
|
948
|
+
button.focus();
|
|
949
|
+
window.location.hash = "close";
|
|
950
|
+
history.replaceState("", document.title, window.location.pathname + window.location.search);
|
|
940
951
|
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
}
|
|
944
|
-
|
|
945
|
-
Array.from(document.querySelectorAll('.carousel')).forEach((arrayElement, index) => {
|
|
946
|
-
carousel(arrayElement);
|
|
947
|
-
}); // Form
|
|
948
|
-
|
|
949
|
-
Array.from(document.querySelectorAll('form')).forEach((arrayElement, index) => {
|
|
950
|
-
form(arrayElement);
|
|
951
|
-
}); // Modal
|
|
952
|
+
// If there is more than one video lets make sure there is only one playing at a time.
|
|
953
|
+
if (typeof window.player != "undefined" && typeof window.player.pauseVideo == "function") window.player.pauseVideo();
|
|
954
|
+
};
|
|
952
955
|
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
+
// Trap the tab focus inside
|
|
957
|
+
element.addEventListener('keydown', function (e) {
|
|
958
|
+
if (e.key === "Tab" && e.shiftKey && document.activeElement == firstLink) {
|
|
959
|
+
e.preventDefault();
|
|
960
|
+
lastLink.focus();
|
|
961
|
+
} else if (e.key === "Tab" && !e.shiftKey && document.activeElement == lastLink) {
|
|
962
|
+
e.preventDefault();
|
|
963
|
+
firstLink.focus();
|
|
964
|
+
}
|
|
965
|
+
});
|
|
956
966
|
|
|
957
|
-
|
|
958
|
-
|
|
967
|
+
// ESC will close the open modal
|
|
968
|
+
document.addEventListener("keydown", function (e) {
|
|
969
|
+
if (e.key === "Escape" && document.querySelector('.modal:target')) closeModal();
|
|
959
970
|
});
|
|
960
|
-
|
|
961
|
-
var
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
971
|
+
element.addEventListener('click', function (e) {
|
|
972
|
+
for (var target = e.target; target && target != this; target = target.parentNode) {
|
|
973
|
+
// Close links will close the model by default but we want to remove the hash link also
|
|
974
|
+
if (target.matches('[href="#close"]')) {
|
|
975
|
+
e.preventDefault();
|
|
976
|
+
closeModal();
|
|
977
|
+
break;
|
|
978
|
+
}
|
|
979
|
+
// Dock the modal to the right or left to make the content behind readable
|
|
980
|
+
else if (target.matches('.modal__dock--right')) {
|
|
981
|
+
e.preventDefault();
|
|
982
|
+
if (!element.classList.contains('modal--left')) element.classList.add('modal--right');
|
|
983
|
+
element.classList.remove('modal--left');
|
|
984
|
+
break;
|
|
985
|
+
} else if (target.matches('.modal__dock--left')) {
|
|
986
|
+
e.preventDefault();
|
|
987
|
+
if (!element.classList.contains('modal--right')) element.classList.add('modal--left');
|
|
988
|
+
element.classList.remove('modal--right');
|
|
989
|
+
break;
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
});
|
|
993
|
+
function locationHashChanged() {
|
|
994
|
+
if (location.hash === '#' + modalID) {
|
|
995
|
+
console.log("Modal is now open");
|
|
996
|
+
var videoButton = document.querySelector('.modal:target .modal__inner > .youtube-embed:first-child:last-child a');
|
|
997
|
+
console.log(videoButton);
|
|
998
|
+
if (videoButton) {
|
|
999
|
+
videoButton.click();
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
window.onhashchange = locationHashChanged;
|
|
1004
|
+
};
|
|
1005
|
+
|
|
1006
|
+
// @ts-nocheck
|
|
1007
|
+
// Attach classes to dom elements
|
|
1008
|
+
document.addEventListener("DOMContentLoaded", function () {
|
|
1009
|
+
addBodyClasses(document.body);
|
|
1010
|
+
addGlobalEvents();
|
|
1011
|
+
checkElements(document.body);
|
|
1012
|
+
console.log('test.js');
|
|
1013
|
+
// ANav
|
|
1014
|
+
Array.from(document.querySelectorAll('.nav')).forEach(function (arrayElement) {
|
|
1015
|
+
navbar(arrayElement);
|
|
1016
|
+
});
|
|
1017
|
+
// Advanced tables
|
|
1018
|
+
Array.from(document.querySelectorAll('.table__wrapper')).forEach(function (arrayElement) {
|
|
1019
|
+
table(arrayElement);
|
|
1020
|
+
});
|
|
1021
|
+
// Accordions
|
|
1022
|
+
Array.from(document.querySelectorAll('.accordion')).forEach(function (arrayElement) {
|
|
1023
|
+
accordion(arrayElement);
|
|
1024
|
+
});
|
|
1025
|
+
// Testimonial
|
|
1026
|
+
Array.from(document.querySelectorAll('.testimonial')).forEach(function (arrayElement) {
|
|
1027
|
+
testimonial(arrayElement);
|
|
1028
|
+
});
|
|
1029
|
+
// Carousel
|
|
1030
|
+
Array.from(document.querySelectorAll('.carousel')).forEach(function (arrayElement) {
|
|
1031
|
+
carousel(arrayElement);
|
|
1032
|
+
});
|
|
1033
|
+
// Form
|
|
1034
|
+
Array.from(document.querySelectorAll('form')).forEach(function (arrayElement) {
|
|
1035
|
+
form(arrayElement);
|
|
1036
|
+
});
|
|
1037
|
+
// Modal
|
|
1038
|
+
Array.from(document.querySelectorAll('.modal')).forEach(function (arrayElement) {
|
|
1039
|
+
modal(arrayElement);
|
|
1040
|
+
});
|
|
1041
|
+
// YouTube videos
|
|
1042
|
+
Array.from(document.querySelectorAll('.youtube-embed')).forEach(function (arrayElement) {
|
|
1043
|
+
new youtubeVideo(arrayElement);
|
|
1044
|
+
});
|
|
1045
|
+
window.addEventListener('hashchange', function () {
|
|
1046
|
+
var hash = location.hash.replace('#', '');
|
|
1047
|
+
var label = document.querySelector("label[for=\"".concat(hash, "\"]"));
|
|
1048
|
+
if (label instanceof HTMLElement) {
|
|
1049
|
+
label.click();
|
|
1050
|
+
}
|
|
1051
|
+
}, false);
|
|
965
1052
|
});
|
|
966
1053
|
|
|
967
1054
|
}));
|