@iamproperty/components 3.2.0 → 3.4.5

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.
Files changed (96) hide show
  1. package/README.md +30 -66
  2. package/assets/css/core.min.css.map +1 -1
  3. package/assets/css/style.min.css.map +1 -1
  4. package/assets/js/main.js +9 -9
  5. package/assets/js/modules/accordion.js +1 -0
  6. package/assets/js/modules/alert.js +37 -53
  7. package/assets/js/modules/carousel.js +74 -100
  8. package/assets/js/modules/chart.js +142 -209
  9. package/assets/js/modules/drawer.js +9 -15
  10. package/assets/js/modules/file-upload.js +30 -45
  11. package/assets/js/modules/form.js +111 -157
  12. package/assets/js/modules/helpers.js +64 -93
  13. package/assets/js/modules/modal.js +67 -88
  14. package/assets/js/modules/nav.js +17 -27
  15. package/assets/js/modules/orderablelist.js +84 -115
  16. package/assets/js/modules/table.js +387 -521
  17. package/assets/js/modules/testimonial.js +61 -80
  18. package/assets/js/modules/youtubevideo.js +104 -135
  19. package/assets/js/scripts.bundle.js +870 -936
  20. package/assets/js/scripts.bundle.js.map +1 -1
  21. package/assets/js/scripts.bundle.min.js +3 -3
  22. package/assets/js/scripts.bundle.min.js.map +1 -1
  23. package/assets/sass/_corefiles.scss +9 -9
  24. package/assets/sass/_forms.scss +1 -1
  25. package/assets/sass/_tests/{sass.spec.js → colours.spec.js} +2 -2
  26. package/assets/sass/_tests/func.spec.js +9 -0
  27. package/assets/sass/_tests/mixins.spec.js +9 -0
  28. package/assets/sass/_tests/typography.spec.js +9 -0
  29. package/assets/ts/main.ts +9 -9
  30. package/assets/ts/modules/accordion.ts +1 -0
  31. package/assets/ts/modules/alert.ts +58 -0
  32. package/assets/ts/modules/carousel.ts +103 -0
  33. package/assets/ts/modules/chart.ts +219 -0
  34. package/assets/ts/modules/drawer.ts +17 -0
  35. package/assets/ts/modules/file-upload.ts +49 -0
  36. package/assets/ts/modules/form.ts +169 -0
  37. package/assets/ts/modules/helpers.ts +120 -0
  38. package/assets/ts/modules/modal.ts +91 -0
  39. package/assets/ts/modules/nav.ts +29 -0
  40. package/assets/ts/modules/orderablelist.ts +123 -0
  41. package/assets/ts/modules/table.ts +586 -0
  42. package/assets/ts/modules/testimonial.ts +84 -0
  43. package/assets/ts/modules/youtubevideo.ts +146 -0
  44. package/dist/components.es.js +671 -750
  45. package/dist/components.umd.js +13 -13
  46. package/dist/style.css +1 -1
  47. package/package.json +54 -38
  48. package/src/components/Accordion/Accordion.vue +1 -1
  49. package/src/components/Alert/Alert.vue +1 -1
  50. package/src/{elements → components}/Card/Card.vue +1 -1
  51. package/src/components/CardDeck/CardDeck.spec.js +1 -1
  52. package/src/components/CardDeck/CardDeck.vue +1 -1
  53. package/src/components/Carousel/Carousel.vue +2 -2
  54. package/src/components/Chart/Chart.vue +2 -2
  55. package/src/{elements → components}/FileUploads/FileUploads.vue +1 -1
  56. package/src/components/Modal/Modal.vue +1 -1
  57. package/src/components/Nav/Nav.vue +2 -2
  58. package/src/components/NoteFeed/NoteFeed.vue +2 -2
  59. package/src/components/PropertySearchbar/PropertySearchbar.vue +1 -1
  60. package/src/{elements → components}/Table/Table.vue +1 -1
  61. package/src/components/Testimonial/Testimonial.vue +1 -1
  62. package/src/foundations/YoutubeVideo/YoutubeVideo.vue +1 -1
  63. package/src/index.js +4 -5
  64. package/assets/.DS_Store +0 -0
  65. package/assets/css/email.min.css +0 -1
  66. package/assets/css/email.min.css.map +0 -1
  67. package/assets/css/error.min.css +0 -1
  68. package/assets/css/error.min.css.map +0 -1
  69. package/assets/sass/components/drawer.scss +0 -47
  70. package/assets/ts/main.js +0 -57
  71. package/assets/ts/main.js.map +0 -1
  72. package/assets/ts/modules/accordion.js +0 -33
  73. package/assets/ts/modules/accordion.js.map +0 -1
  74. package/src/.DS_Store +0 -0
  75. package/src/components/Accordion/Accordion.screenshot.vue +0 -57
  76. package/src/components/Accordion/__screenshots__/win32/laptop/Accordion.png +0 -0
  77. package/src/components/Accordion/__screenshots__/win32/mobile/Accordion.png +0 -0
  78. package/src/components/Accordion/__screenshots__/win32/tablet/Accordion.png +0 -0
  79. package/src/components/Drawer/Drawer.vue +0 -53
  80. package/src/components/Drawer/README.md +0 -23
  81. /package/assets/sass/{elements → components}/buttons.scss +0 -0
  82. /package/assets/sass/{elements → components}/card.scss +0 -0
  83. /package/assets/sass/{elements → components}/container.scss +0 -0
  84. /package/assets/sass/{elements → components}/forms.scss +0 -0
  85. /package/assets/sass/{elements → components}/links.scss +0 -0
  86. /package/assets/sass/{elements → components}/lists.scss +0 -0
  87. /package/assets/sass/{elements → components}/panel.scss +0 -0
  88. /package/assets/sass/{elements → components}/tables.scss +0 -0
  89. /package/assets/sass/{elements → components}/tooltips.scss +0 -0
  90. /package/assets/sass/{elements → foundations}/type.scss +0 -0
  91. /package/src/{elements → components}/Card/README.md +0 -0
  92. /package/src/{elements → components}/FileUploads/README.md +0 -0
  93. /package/src/{elements → components}/Input/Input.vue +0 -0
  94. /package/src/{elements → components}/Input/README.md +0 -0
  95. /package/src/{elements → components}/Table/README.md +0 -0
  96. /package/src/{elements → components}/Table/Table.spec.js +0 -0
@@ -1,132 +1,101 @@
1
- import { zeroPad, isNumeric } from "./helpers";
2
-
1
+ // @ts-nocheck
2
+ import { zeroPad, isNumeric } from "./helpers.js";
3
3
  function table(tableElement) {
4
-
5
- if(typeof tableElement != "object")
6
- return false;
7
-
8
- const thead = tableElement.querySelector('thead');
9
- const tbody = tableElement.querySelector('tbody');
10
- const storedData = tbody.cloneNode(true);
11
- const sortedEvent = new Event('sorted');
12
- const filteredEvent = new Event('filtered');
13
- const reorderedEvent = new Event('reordered');
14
- const randID = 'table_'+Math.random().toString(36).substr(2, 9); // Random to make sure IDs created are unique
15
- let draggedRow;
16
-
17
- tableElement.setAttribute('id',randID)
18
-
19
- // #region Sortable
20
- const sortTable = function(sortBy,sort){
21
-
22
- // Create an array from the table rows, the index created is then used to sort the array
23
- let tableArr = [];
24
- Array.from(tbody.querySelectorAll('tr')).forEach((tableRow, index) => {
25
-
26
- let rowIndex = tableRow.querySelector('td[data-label="'+sortBy+'"], th[data-label="'+sortBy+'"]').textContent;
27
-
28
- if(isNumeric(rowIndex))
29
- rowIndex = zeroPad(rowIndex,10)
30
-
31
- const dataRow = {
32
- index: rowIndex,
33
- row: tableRow
34
- }
35
- tableArr.push(dataRow);
36
- });
37
-
38
- // Sort array
39
- tableArr.sort((a, b) => (a.index > b.index) ? 1 : -1)
40
-
41
- // Reverse if descending
42
- if(sort == "descending")
43
- tableArr = tableArr.reverse();
44
-
45
- // Create a string to return and populate the tbody
46
- let strTbody = '';
47
- tableArr.forEach((tableRow, index) => {
48
- strTbody += tableRow.row.outerHTML;
49
- });
50
- tbody.innerHTML = strTbody;
51
-
52
- // Dispatch the sortable event
53
- tableElement.dispatchEvent(sortedEvent);
54
- }
55
-
56
- // Declare event handlers
57
- tableElement.addEventListener('click', function(e){
58
- for (var target = e.target; target && target != this; target = target.parentNode) {
59
- if (target.matches('[data-sortable]')) {
60
-
61
- // Get current sort order
62
- let sort = target.getAttribute('aria-sort') == "ascending" ? "descending" : "ascending";
63
-
64
- // unset sort attributes
65
- Array.from(tableElement.querySelectorAll('[data-sortable]')).forEach((col, index) => {
66
- col.setAttribute('aria-sort','none');
4
+ if (typeof tableElement != "object")
5
+ return false;
6
+ const thead = tableElement.querySelector('thead');
7
+ const tbody = tableElement.querySelector('tbody');
8
+ const storedData = tbody.cloneNode(true);
9
+ const sortedEvent = new Event('sorted');
10
+ const filteredEvent = new Event('filtered');
11
+ const reorderedEvent = new Event('reordered');
12
+ const randID = 'table_' + Math.random().toString(36).substr(2, 9); // Random to make sure IDs created are unique
13
+ let draggedRow;
14
+ tableElement.setAttribute('id', randID);
15
+ // #region Sortable
16
+ const sortTable = function (sortBy, sort) {
17
+ // Create an array from the table rows, the index created is then used to sort the array
18
+ let tableArr = [];
19
+ Array.from(tbody.querySelectorAll('tr')).forEach((tableRow, index) => {
20
+ let rowIndex = tableRow.querySelector('td[data-label="' + sortBy + '"], th[data-label="' + sortBy + '"]').textContent;
21
+ if (isNumeric(rowIndex))
22
+ rowIndex = zeroPad(rowIndex, 10);
23
+ const dataRow = {
24
+ index: rowIndex,
25
+ row: tableRow
26
+ };
27
+ tableArr.push(dataRow);
67
28
  });
68
-
69
- // Set the sort order attribute
70
- target.setAttribute('aria-sort', sort);
71
-
72
- // Save the sort options on the table element so that it can be re-sorted later
73
- tableElement.setAttribute('data-sort', sort);
74
- tableElement.setAttribute('data-sortBy', target.textContent);
75
-
76
- // Sort the table
77
- sortTable(target.textContent, sort);
78
-
79
- Array.from(tableElement.querySelectorAll('tr[draggable]')).forEach((tableRow, index) => {
80
-
81
- tableRow.removeAttribute('draggable');
29
+ // Sort array
30
+ tableArr.sort((a, b) => (a.index > b.index) ? 1 : -1);
31
+ // Reverse if descending
32
+ if (sort == "descending")
33
+ tableArr = tableArr.reverse();
34
+ // Create a string to return and populate the tbody
35
+ let strTbody = '';
36
+ tableArr.forEach((tableRow, index) => {
37
+ strTbody += tableRow.row.outerHTML;
38
+ });
39
+ tbody.innerHTML = strTbody;
40
+ // Dispatch the sortable event
41
+ tableElement.dispatchEvent(sortedEvent);
42
+ };
43
+ // Declare event handlers
44
+ tableElement.addEventListener('click', function (e) {
45
+ for (var target = e.target; target && target != this; target = target.parentNode) {
46
+ if (target.matches('[data-sortable]')) {
47
+ // Get current sort order
48
+ let sort = target.getAttribute('aria-sort') == "ascending" ? "descending" : "ascending";
49
+ // unset sort attributes
50
+ Array.from(tableElement.querySelectorAll('[data-sortable]')).forEach((col, index) => {
51
+ col.setAttribute('aria-sort', 'none');
52
+ });
53
+ // Set the sort order attribute
54
+ target.setAttribute('aria-sort', sort);
55
+ // Save the sort options on the table element so that it can be re-sorted later
56
+ tableElement.setAttribute('data-sort', sort);
57
+ tableElement.setAttribute('data-sortBy', target.textContent);
58
+ // Sort the table
59
+ sortTable(target.textContent, sort);
60
+ Array.from(tableElement.querySelectorAll('tr[draggable]')).forEach((tableRow, index) => {
61
+ tableRow.removeAttribute('draggable');
62
+ });
63
+ break;
64
+ }
65
+ }
66
+ }, false);
67
+ // On page load check if the table should be pre-sorted, if so trigger a click
68
+ if (tableElement.getAttribute('data-sortBy')) {
69
+ let sort = tableElement.getAttribute('data-sort') == "ascending" ? "descending" : "ascending";
70
+ Array.from(tableElement.querySelectorAll('[data-sortable]')).forEach((col, index) => {
71
+ if (col.textContent == tableElement.getAttribute('data-sortBy')) {
72
+ col.setAttribute('aria-sort', sort);
73
+ col.click();
74
+ }
82
75
  });
83
- break;
84
- }
85
76
  }
86
- }, false);
87
-
88
- // On page load check if the table should be pre-sorted, if so trigger a click
89
- if(tableElement.getAttribute('data-sortBy')){
90
-
91
- let sort = tableElement.getAttribute('data-sort') == "ascending" ? "descending" : "ascending";
92
-
93
- Array.from(tableElement.querySelectorAll('[data-sortable]')).forEach((col, index) => {
94
- if(col.textContent == tableElement.getAttribute('data-sortBy')){
95
- col.setAttribute('aria-sort',sort)
96
- col.click();
97
- }
98
- });
99
- }
100
-
101
- // #endregion Sortable
102
-
103
- // #region Filters
104
- const createFilterForm = function(count){
105
-
106
- // Create wrapper div
107
- const form = document.createElement("div");
108
- form.classList.add('table__filters');
109
- form.classList.add('row');
110
- form.classList.add('pt-1');
111
- form.classList.add('pb-3');
112
-
113
- // Create the filter options array
114
- const filterColumns = Array.from(tableElement.querySelectorAll('th[data-filterable]'));
115
-
116
- // Populate a list of searchable terms from the cells of the columns that could be used as a filter
117
- let searchableTerms = {};
118
- filterColumns.forEach((columnHeading, index) => {
119
- Array.from(tableElement.querySelectorAll('td[data-label="'+columnHeading.textContent+'"]')).forEach((label, index) => {
120
-
121
- searchableTerms[label.textContent] = label.textContent;
122
- });
123
- });
124
-
125
- // Create the form
126
- const filterTitle = filterColumns.length == 1 ? "Filter by "+filterColumns[0].textContent : "Filter"; // Update title if only one filter is chosen
127
- const checkboxClass = filterColumns.length == 1 ? "d-none" : "d-sm-flex"; // Hide controls when only one filter is chosen
128
-
129
- form.innerHTML = `<div class="col-sm-6 col-md-4 pb-3">
77
+ // #endregion Sortable
78
+ // #region Filters
79
+ const createFilterForm = function (count) {
80
+ // Create wrapper div
81
+ const form = document.createElement("div");
82
+ form.classList.add('table__filters');
83
+ form.classList.add('row');
84
+ form.classList.add('pt-1');
85
+ form.classList.add('pb-3');
86
+ // Create the filter options array
87
+ const filterColumns = Array.from(tableElement.querySelectorAll('th[data-filterable]'));
88
+ // Populate a list of searchable terms from the cells of the columns that could be used as a filter
89
+ let searchableTerms = {};
90
+ filterColumns.forEach((columnHeading, index) => {
91
+ Array.from(tableElement.querySelectorAll('td[data-label="' + columnHeading.textContent + '"]')).forEach((label, index) => {
92
+ searchableTerms[label.textContent] = label.textContent;
93
+ });
94
+ });
95
+ // Create the form
96
+ const filterTitle = filterColumns.length == 1 ? "Filter by " + filterColumns[0].textContent : "Filter"; // Update title if only one filter is chosen
97
+ const checkboxClass = filterColumns.length == 1 ? "d-none" : "d-sm-flex"; // Hide controls when only one filter is chosen
98
+ form.innerHTML = `<div class="col-sm-6 col-md-4 pb-3">
130
99
  <div class="form-control__wrapper form-control-inline mb-0">
131
100
  <label for="${randID}_filter" class="form-label">${filterTitle}:</label>
132
101
  <input type="search" name="${randID}_filter" id="${randID}_filter" class="form-control form-control-sm" placeholder="" list="${randID}_list" />
@@ -136,120 +105,95 @@ function table(tableElement) {
136
105
  </datalist>
137
106
  </div>
138
107
  <div class="col-md-8 align-items-center pb-3 ${checkboxClass}">
139
- ${`<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="${randID}_${column.textContent.replace(' ','_').toLowerCase()}" checked="checked" /><label class="form-check-label text-nowrap" for="${randID}_${column.textContent.replace(' ','_').toLowerCase()}">${column.textContent}</label></div>`).join("")}
108
+ ${`<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="${randID}_${column.textContent.replace(' ', '_').toLowerCase()}" checked="checked" /><label class="form-check-label text-nowrap" for="${randID}_${column.textContent.replace(' ', '_').toLowerCase()}">${column.textContent}</label></div>`).join("")}
140
109
  </div>`;
141
-
142
- // Add before the actual table
143
- tableElement.prepend(form)
144
- }
145
-
146
- const filterTable = function(searchTerm){
147
-
148
- // Create an array of rows that match the search term
149
- let tableArr = [];
150
- Array.from(storedData.querySelectorAll('tr')).forEach((tableRow, index) => {
151
-
152
- // We want one long search string per row including each filterable table cell
153
- let rowSearchString = '';
154
- Array.from(tableElement.querySelectorAll('[type="checkbox"]:checked + label')).forEach((label, index) => {
155
- rowSearchString += tableRow.querySelector('td[data-label="'+label.textContent+'"]').textContent+' | ';
156
- });
157
-
158
- // Check if the table row search string contains the search term
159
- if(rowSearchString.indexOf(searchTerm) >= 0){
160
-
161
- const dataRow = { row: tableRow }
162
- tableArr.push(dataRow);
163
- }
164
- });
165
-
166
- // Create a string to return and populate the tbody
167
- let strTbody = '';
168
- tableArr.forEach((tableRow, index) => {
169
- strTbody += tableRow.row.outerHTML;
170
- });
171
- tbody.innerHTML = strTbody;
172
-
173
- // Dispatch the filter event.
174
- tableElement.dispatchEvent(filteredEvent);
175
- }
176
-
177
- const createFilterList = function(){
178
-
179
- // Check which options are checked
180
- let filterOptions = [];
181
- Array.from(tableElement.querySelectorAll('[type="checkbox"]:checked + label')).forEach((label, index) => {
182
- filterOptions.push(label.textContent);
183
- });
184
-
185
- // Build up the list of searchable terms
186
- let searchableTerms = [];
187
- filterOptions.forEach((option, index) => {
188
- Array.from(tableElement.querySelectorAll('td[data-label="'+option+'"]')).forEach((label, index) => {
189
- searchableTerms[label.textContent] = label.textContent;
190
- });
191
- });
192
-
193
- // Rebuild the list
194
- let dataList = tableElement.querySelector('datalist');
195
- dataList.innerHTML = Object.keys(searchableTerms).map(term => `<option value="${term}"></option>`).join("");
196
- }
197
-
198
- // On page load check if filters are needed
199
- if(Array.from(tableElement.querySelectorAll('[data-filterable]')).length){
200
-
201
- // Create the filter options
202
- createFilterForm(tableElement,Array.from(tableElement.querySelectorAll('[data-filterable]')).length);
203
-
204
- // Add event handlers for the filter options
205
- tableElement.addEventListener('keyup', function(e){
206
- for (var target = e.target; target && target != this; target = target.parentNode) {
207
- if (target.matches('input[type="search"]')) {
208
-
209
- const searchTerm = target.value;
210
- filterTable(searchTerm)
211
- }
212
- }
213
- });
214
-
215
- tableElement.addEventListener('change', function(e){
216
- for (var target = e.target; target && target != this; target = target.parentNode) {
217
- if (target.matches('input[type="search"]')) {
218
-
219
- const searchTerm = target.value;
220
- filterTable(searchTerm)
221
- }
222
- }
223
- });
224
-
225
- tableElement.addEventListener('change', function(e){
226
- for (var target = e.target; target && target != this; target = target.parentNode) {
227
- if (target.matches('input[type="checkbox"]')) {
228
-
229
- const searchTerm = tableElement.querySelector('input[type="search"]').value;
230
- filterTable(searchTerm)
231
- createFilterList()
232
- }
233
- }
234
- });
235
- }
236
- // #endregion Filters
237
-
238
- // #region Pagination
239
- const paginateRows = function(show, page){
240
-
241
- // 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.
242
- let style = document.getElementById(randID+'_style');
243
-
244
- if(style == null){
245
- style = document.createElement("style");
246
- style.setAttribute('id',randID+'_style')
110
+ // Add before the actual table
111
+ tableElement.prepend(form);
112
+ };
113
+ const filterTable = function (searchTerm) {
114
+ // Create an array of rows that match the search term
115
+ let tableArr = [];
116
+ Array.from(storedData.querySelectorAll('tr')).forEach((tableRow, index) => {
117
+ // We want one long search string per row including each filterable table cell
118
+ let rowSearchString = '';
119
+ Array.from(tableElement.querySelectorAll('[type="checkbox"]:checked + label')).forEach((label, index) => {
120
+ rowSearchString += tableRow.querySelector('td[data-label="' + label.textContent + '"]').textContent + ' | ';
121
+ });
122
+ // Check if the table row search string contains the search term
123
+ if (rowSearchString.indexOf(searchTerm) >= 0) {
124
+ const dataRow = { row: tableRow };
125
+ tableArr.push(dataRow);
126
+ }
127
+ });
128
+ // Create a string to return and populate the tbody
129
+ let strTbody = '';
130
+ tableArr.forEach((tableRow, index) => {
131
+ strTbody += tableRow.row.outerHTML;
132
+ });
133
+ tbody.innerHTML = strTbody;
134
+ // Dispatch the filter event.
135
+ tableElement.dispatchEvent(filteredEvent);
136
+ };
137
+ const createFilterList = function () {
138
+ // Check which options are checked
139
+ let filterOptions = [];
140
+ Array.from(tableElement.querySelectorAll('[type="checkbox"]:checked + label')).forEach((label, index) => {
141
+ filterOptions.push(label.textContent);
142
+ });
143
+ // Build up the list of searchable terms
144
+ let searchableTerms = [];
145
+ filterOptions.forEach((option, index) => {
146
+ Array.from(tableElement.querySelectorAll('td[data-label="' + option + '"]')).forEach((label, index) => {
147
+ searchableTerms[label.textContent] = label.textContent;
148
+ });
149
+ });
150
+ // Rebuild the list
151
+ let dataList = tableElement.querySelector('datalist');
152
+ dataList.innerHTML = Object.keys(searchableTerms).map(term => `<option value="${term}"></option>`).join("");
153
+ };
154
+ // On page load check if filters are needed
155
+ if (Array.from(tableElement.querySelectorAll('[data-filterable]')).length) {
156
+ // Create the filter options
157
+ createFilterForm(tableElement, Array.from(tableElement.querySelectorAll('[data-filterable]')).length);
158
+ // Add event handlers for the filter options
159
+ tableElement.addEventListener('keyup', function (e) {
160
+ for (var target = e.target; target && target != this; target = target.parentNode) {
161
+ if (target.matches('input[type="search"]')) {
162
+ const searchTerm = target.value;
163
+ filterTable(searchTerm);
164
+ }
165
+ }
166
+ });
167
+ tableElement.addEventListener('change', function (e) {
168
+ for (var target = e.target; target && target != this; target = target.parentNode) {
169
+ if (target.matches('input[type="search"]')) {
170
+ const searchTerm = target.value;
171
+ filterTable(searchTerm);
172
+ }
173
+ }
174
+ });
175
+ tableElement.addEventListener('change', function (e) {
176
+ for (var target = e.target; target && target != this; target = target.parentNode) {
177
+ if (target.matches('input[type="checkbox"]')) {
178
+ const searchTerm = tableElement.querySelector('input[type="search"]').value;
179
+ filterTable(searchTerm);
180
+ createFilterList();
181
+ }
182
+ }
183
+ });
247
184
  }
248
-
249
- const startShowing = (show*(page-1))+1;
250
- const stopShowing = show*(page);
251
-
252
- style.innerHTML = `
185
+ // #endregion Filters
186
+ // #region Pagination
187
+ const paginateRows = function (show, page) {
188
+ // 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.
189
+ let style = document.getElementById(randID + '_style');
190
+ if (style == null) {
191
+ style = document.createElement("style");
192
+ style.setAttribute('id', randID + '_style');
193
+ }
194
+ const startShowing = (show * (page - 1)) + 1;
195
+ const stopShowing = show * (page);
196
+ style.innerHTML = `
253
197
  #${randID} tbody tr {
254
198
  display: none;
255
199
  }
@@ -267,250 +211,188 @@ function table(tableElement) {
267
211
  display: none;
268
212
  }
269
213
  `;
270
-
271
- tableElement.append(style);
272
- }
273
-
274
- // On page load check if the table should be paginated
275
- if(tableElement.getAttribute('data-show')){
276
-
277
- const show = parseInt(tableElement.getAttribute('data-show'));
278
- const page = parseInt(tableElement.getAttribute('data-page')) ? parseInt(tableElement.getAttribute('data-page')) : 1;
279
- const totalRows = tableElement.querySelectorAll('tbody tr').length;
280
-
281
- if(show < totalRows){
282
- paginateRows(show,page);
283
- createPaginationForm(randID,tableElement,show,page,totalRows);
284
- createPaginationButttons(randID,tableElement,show,page,totalRows);
285
-
286
- tableElement.addEventListener('change', function(e){
287
- for (var target = e.target; target && target != this; target = target.parentNode) {
288
- if (target.matches('.table__pagination input[type="number"]')) {
289
-
290
- paginateRows(target.value,page);
291
- createPaginationButttons(randID,tableElement,target.value,page,totalRows);
292
- tableElement.setAttribute('data-show',target.value)
293
- }
294
- }
295
- });
296
-
297
- tableElement.addEventListener('click', function(e){
298
- for (var target = e.target; target && target != this; target = target.parentNode) {
299
- if (target.matches('.page-item:not(.active):not(.disabled) .page-link')) {
300
-
301
- paginateRows(tableElement.getAttribute('data-show'),target.getAttribute('data-page'));
302
- createPaginationButttons(randID,tableElement,tableElement.getAttribute('data-show'),target.getAttribute('data-page'),totalRows);
303
- }
304
- }
305
- }, false);
306
-
307
- tableElement.addEventListener('change', function(e){
308
- for (var target = e.target; target && target != this; target = target.parentNode) {
309
- if (target.matches('.table__pagination select')) {
310
-
311
- paginateRows(tableElement.getAttribute('data-show'),target.value);
312
- createPaginationButttons(randID,tableElement,tableElement.getAttribute('data-show'),target.value,totalRows);
313
- }
214
+ tableElement.append(style);
215
+ };
216
+ // On page load check if the table should be paginated
217
+ if (tableElement.getAttribute('data-show')) {
218
+ const show = parseInt(tableElement.getAttribute('data-show'));
219
+ const page = parseInt(tableElement.getAttribute('data-page')) ? parseInt(tableElement.getAttribute('data-page')) : 1;
220
+ const totalRows = tableElement.querySelectorAll('tbody tr').length;
221
+ if (show < totalRows) {
222
+ paginateRows(show, page);
223
+ createPaginationForm(randID, tableElement, show, page, totalRows);
224
+ createPaginationButttons(randID, tableElement, show, page, totalRows);
225
+ tableElement.addEventListener('change', function (e) {
226
+ for (var target = e.target; target && target != this; target = target.parentNode) {
227
+ if (target.matches('.table__pagination input[type="number"]')) {
228
+ paginateRows(target.value, page);
229
+ createPaginationButttons(randID, tableElement, target.value, page, totalRows);
230
+ tableElement.setAttribute('data-show', target.value);
231
+ }
232
+ }
233
+ });
234
+ tableElement.addEventListener('click', function (e) {
235
+ for (var target = e.target; target && target != this; target = target.parentNode) {
236
+ if (target.matches('.page-item:not(.active):not(.disabled) .page-link')) {
237
+ paginateRows(tableElement.getAttribute('data-show'), target.getAttribute('data-page'));
238
+ createPaginationButttons(randID, tableElement, tableElement.getAttribute('data-show'), target.getAttribute('data-page'), totalRows);
239
+ }
240
+ }
241
+ }, false);
242
+ tableElement.addEventListener('change', function (e) {
243
+ for (var target = e.target; target && target != this; target = target.parentNode) {
244
+ if (target.matches('.table__pagination select')) {
245
+ paginateRows(tableElement.getAttribute('data-show'), target.value);
246
+ createPaginationButttons(randID, tableElement, tableElement.getAttribute('data-show'), target.value, totalRows);
247
+ }
248
+ }
249
+ });
314
250
  }
315
- });
316
251
  }
317
- }
318
- // #endregion Pagination
319
-
320
- // #region Reorderable
321
- // Set the row thats being dragged and copy the row
322
- function setDraggedRow(e) {
323
- e.dataTransfer.setData("text/plain", e.target.id);
324
- draggedRow = e.target;
325
- e.target.classList.add('tr--dragging');
326
- }
327
-
328
- // Create the order column and event handler for rows
329
- const setReorderRows = function(){
330
-
331
- Array.from(tbody.querySelectorAll('tr')).forEach((tableRow, index) => {
332
-
333
- // Create column if not already created
334
- if(tableRow.querySelector('[data-label="Order"]') == null){
335
-
336
- const orderColumn = document.createElement('th');
337
- orderColumn.innerHTML = index + 1;
338
- orderColumn.setAttribute('data-label','Order');
339
- tableRow.prepend(orderColumn);
340
- }
341
-
342
- // Make draggable
343
- tableRow.setAttribute('id',randID+'_row_'+(index+1));
344
- tableRow.setAttribute('data-order',index+1);
345
- tableRow.setAttribute('draggable','true');
346
- tableRow.addEventListener("dragstart", setDraggedRow);
347
- });
348
- }
349
-
350
- if(tableElement.getAttribute('data-reorder') && tableElement.getAttribute('data-reorder') != "false"){
351
-
352
- // Add column heading
353
- const orderHeading = document.createElement('th');
354
- orderHeading.innerHTML = 'Order';
355
- orderHeading.title = 'Click here to enable re-ordering via drag and drop';
356
- orderHeading.classList.add('table-order-reset');
357
- thead.querySelector('tr').prepend(orderHeading);
358
-
359
- setReorderRows();
360
-
361
- // Reset order button
362
- tableElement.addEventListener('click', function(e){
363
- for (var target = e.target; target && target != this; target = target.parentNode) {
364
- if (target.matches('.table-order-reset')) {
365
-
366
- // unset sort attributes
367
- Array.from(tableElement.querySelectorAll('[data-sortable]')).forEach((col, index) => {
368
- col.setAttribute('aria-sort','none');
369
- });
370
-
371
- // Save the sort options on the table element so that it can be re-sorted later
372
- tableElement.removeAttribute('data-sort');
373
- tableElement.removeAttribute('data-sortBy');
374
-
375
- // Sort the table
376
- sortTable('Order', 'ascending');
377
-
378
- Array.from(tableElement.querySelectorAll('tbody tr')).forEach((tableRow, index) => {
379
-
380
- tableRow.setAttribute('draggable','true');
381
- });
382
-
383
- break;
252
+ // #endregion Pagination
253
+ // #region Reorderable
254
+ // Set the row thats being dragged and copy the row
255
+ function setDraggedRow(e) {
256
+ e.dataTransfer.setData("text/plain", e.target.id);
257
+ draggedRow = e.target;
258
+ e.target.classList.add('tr--dragging');
259
+ }
260
+ // Create the order column and event handler for rows
261
+ const setReorderRows = function () {
262
+ Array.from(tbody.querySelectorAll('tr')).forEach((tableRow, index) => {
263
+ // Create column if not already created
264
+ if (tableRow.querySelector('[data-label="Order"]') == null) {
265
+ const orderColumn = document.createElement('th');
266
+ orderColumn.innerHTML = index + 1;
267
+ orderColumn.setAttribute('data-label', 'Order');
268
+ tableRow.prepend(orderColumn);
269
+ }
270
+ // Make draggable
271
+ tableRow.setAttribute('id', randID + '_row_' + (index + 1));
272
+ tableRow.setAttribute('data-order', index + 1);
273
+ tableRow.setAttribute('draggable', 'true');
274
+ tableRow.addEventListener("dragstart", setDraggedRow);
275
+ });
276
+ };
277
+ if (tableElement.getAttribute('data-reorder') && tableElement.getAttribute('data-reorder') != "false") {
278
+ // Add column heading
279
+ const orderHeading = document.createElement('th');
280
+ orderHeading.innerHTML = 'Order';
281
+ orderHeading.title = 'Click here to enable re-ordering via drag and drop';
282
+ orderHeading.classList.add('table-order-reset');
283
+ thead.querySelector('tr').prepend(orderHeading);
284
+ setReorderRows();
285
+ // Reset order button
286
+ tableElement.addEventListener('click', function (e) {
287
+ for (var target = e.target; target && target != this; target = target.parentNode) {
288
+ if (target.matches('.table-order-reset')) {
289
+ // unset sort attributes
290
+ Array.from(tableElement.querySelectorAll('[data-sortable]')).forEach((col, index) => {
291
+ col.setAttribute('aria-sort', 'none');
292
+ });
293
+ // Save the sort options on the table element so that it can be re-sorted later
294
+ tableElement.removeAttribute('data-sort');
295
+ tableElement.removeAttribute('data-sortBy');
296
+ // Sort the table
297
+ sortTable('Order', 'ascending');
298
+ Array.from(tableElement.querySelectorAll('tbody tr')).forEach((tableRow, index) => {
299
+ tableRow.setAttribute('draggable', 'true');
300
+ });
301
+ break;
302
+ }
303
+ }
304
+ }, false);
305
+ document.addEventListener("dragover", function (e) {
306
+ // prevent default to allow drop
307
+ e.preventDefault();
308
+ }, false);
309
+ document.addEventListener("dragenter", function (e) {
310
+ // prevent default to allow drop
311
+ e.preventDefault();
312
+ e.dataTransfer.dropEffect = "move";
313
+ for (var target = e.target; target && target != this; target = target.parentNode) {
314
+ if (target.matches('[data-reorder] tbody tr')) {
315
+ target.classList.add('tr--dropable');
316
+ }
317
+ }
318
+ }, false);
319
+ document.addEventListener("dragleave", function (e) {
320
+ // prevent default to allow drop
321
+ e.preventDefault();
322
+ for (var target = e.target; target && target != this; target = target.parentNode) {
323
+ if (target.matches('[data-reorder] tbody tr')) {
324
+ target.classList.remove('tr--dropable');
325
+ }
326
+ }
327
+ }, false);
328
+ document.addEventListener("drop", function (e) {
329
+ e.preventDefault();
330
+ for (var target = e.target; target && target != this; target = target.parentNode) {
331
+ if (target.matches('[data-reorder] tbody tr')) {
332
+ if (target.parentNode != null && draggedRow.parentNode != null && target != draggedRow) {
333
+ draggedRow.parentNode.removeChild(draggedRow);
334
+ if (draggedRow.getAttribute('data-order') > target.getAttribute('data-order'))
335
+ target.parentNode.insertBefore(draggedRow, target);
336
+ else
337
+ target.parentNode.insertBefore(draggedRow, target.nextElementSibling);
338
+ // Re label the rows
339
+ Array.from(tbody.querySelectorAll('tr')).forEach((tableRowOrder, index) => {
340
+ tableRowOrder.classList.remove('tr--dragging');
341
+ tableRowOrder.classList.remove('tr--dropable');
342
+ tableRowOrder.querySelector('th').innerHTML = index + 1;
343
+ tableRowOrder.setAttribute('data-order', index + 1);
344
+ });
345
+ tableElement.dispatchEvent(reorderedEvent);
346
+ }
347
+ break;
348
+ }
349
+ }
350
+ }, false);
351
+ }
352
+ // #endregion Reorderable
353
+ // Watch for the filterable event and re-sort the tbody
354
+ tableElement.addEventListener('filtered', function (e) {
355
+ if (tableElement.getAttribute('data-sortBy') && tableElement.getAttribute('data-sort'))
356
+ sortTable(tableElement.getAttribute('data-sortBy'), tableElement.getAttribute('data-sort'));
357
+ if (tableElement.getAttribute('data-show')) {
358
+ const show = parseInt(tableElement.getAttribute('data-show'));
359
+ const totalRows = tableElement.querySelectorAll('tbody tr').length;
360
+ const tablePagination = tableElement.querySelector('.table__pagination');
361
+ if (tablePagination != null)
362
+ tablePagination.remove();
363
+ if (show < totalRows) {
364
+ paginateRows(show, 1);
365
+ createPaginationForm(randID, tableElement, show, 1, totalRows);
366
+ createPaginationButttons(randID, tableElement, show, 1, totalRows);
367
+ }
384
368
  }
385
- }
386
- }, false);
387
-
388
-
389
- document.addEventListener("dragover", function( e ) {
390
- // prevent default to allow drop
391
- e.preventDefault();
392
- }, false);
393
-
394
- document.addEventListener("dragenter", function( e ) {
395
- // prevent default to allow drop
396
- e.preventDefault();
397
- e.dataTransfer.dropEffect = "move";
398
-
399
- for (var target = e.target; target && target != this; target = target.parentNode) {
400
- if (target.matches('[data-reorder] tbody tr')) {
401
-
402
- target.classList.add('tr--dropable')
369
+ if (tableElement.getAttribute('data-reorder')) {
370
+ setReorderRows();
403
371
  }
404
- }
405
372
  }, false);
406
-
407
- document.addEventListener("dragleave", function( e ) {
408
- // prevent default to allow drop
409
- e.preventDefault();
410
- for (var target = e.target; target && target != this; target = target.parentNode) {
411
- if (target.matches('[data-reorder] tbody tr')) {
412
-
413
- target.classList.remove('tr--dropable')
373
+ tableElement.addEventListener('sorted', function (e) {
374
+ if (tableElement.getAttribute('data-reorder')) {
375
+ setReorderRows();
414
376
  }
415
- }
416
377
  }, false);
417
-
418
- document.addEventListener("drop", function(e) {
419
-
420
- e.preventDefault();
421
-
422
- for (var target = e.target; target && target != this; target = target.parentNode) {
423
- if (target.matches('[data-reorder] tbody tr')) {
424
-
425
- if(target.parentNode != null && draggedRow.parentNode != null && target != draggedRow){
426
-
427
- draggedRow.parentNode.removeChild( draggedRow );
428
-
429
- if(draggedRow.getAttribute('data-order') > target.getAttribute('data-order'))
430
- target.parentNode.insertBefore(draggedRow, target);
431
- else
432
- target.parentNode.insertBefore(draggedRow, target.nextElementSibling);
433
-
434
- // Re label the rows
435
- Array.from(tbody.querySelectorAll('tr')).forEach((tableRowOrder, index) => {
436
- tableRowOrder.classList.remove('tr--dragging')
437
- tableRowOrder.classList.remove('tr--dropable')
438
- tableRowOrder.querySelector('th').innerHTML = index + 1;
439
- tableRowOrder.setAttribute('data-order',index+1);
440
- });
441
-
442
- tableElement.dispatchEvent(reorderedEvent);
443
- }
444
- break;
445
- }
446
- }
447
- }, false);
448
-
449
- }
450
- // #endregion Reorderable
451
-
452
- // Watch for the filterable event and re-sort the tbody
453
- tableElement.addEventListener('filtered', function (e) {
454
-
455
- if(tableElement.getAttribute('data-sortBy') && tableElement.getAttribute('data-sort'))
456
- sortTable(tableElement.getAttribute('data-sortBy'), tableElement.getAttribute('data-sort'));
457
-
458
- if(tableElement.getAttribute('data-show')){
459
-
460
- const show = parseInt(tableElement.getAttribute('data-show'));
461
- const totalRows = tableElement.querySelectorAll('tbody tr').length;
462
- const tablePagination = tableElement.querySelector('.table__pagination');
463
-
464
- if(tablePagination != null)
378
+ tableElement.addEventListener('populated', function (e) {
379
+ var tableFilter = tableElement.querySelector('.table__filters');
380
+ tableFilter.remove();
381
+ var tablePagination = tableElement.querySelector('.table__pagination');
465
382
  tablePagination.remove();
466
-
467
- if(show < totalRows){
468
-
469
- paginateRows(show,1);
470
- createPaginationForm(randID,tableElement,show,1,totalRows);
471
- createPaginationButttons(randID,tableElement,show,1,totalRows);
472
- }
473
- }
474
-
475
- if(tableElement.getAttribute('data-reorder')){
476
-
477
- setReorderRows();
478
- }
479
- }, false);
480
-
481
- tableElement.addEventListener('sorted', function (e) {
482
-
483
- if(tableElement.getAttribute('data-reorder')){
484
-
485
- setReorderRows();
486
- }
487
- }, false);
488
-
489
- tableElement.addEventListener('populated', function (e) {
490
-
491
- var tableFilter = tableElement.querySelector('.table__filters')
492
- tableFilter.remove();
493
-
494
- var tablePagination = tableElement.querySelector('.table__pagination')
495
- tablePagination.remove();
496
-
497
- var newTable = tableElement.cloneNode(true);
498
- tableElement.parentNode.replaceChild(newTable, tableElement);
499
-
500
- table(newTable);
501
- }, false);
383
+ var newTable = tableElement.cloneNode(true);
384
+ tableElement.parentNode.replaceChild(newTable, tableElement);
385
+ table(newTable);
386
+ }, false);
502
387
  }
503
-
504
- export const createPaginationForm = function(randID,tableElement,show,page,totalRows){
505
-
506
- const form = document.createElement("div");
507
- form.classList.add('table__pagination');
508
- form.classList.add('row');
509
- form.classList.add('pt-3');
510
- form.classList.add('pb-3');
511
-
512
- // Create the form and create a container div to hold the pagination buttons
513
- form.innerHTML = `<div class="col mw-fit-content mb-3">
388
+ export const createPaginationForm = function (randID, tableElement, show, page, totalRows) {
389
+ const form = document.createElement("div");
390
+ form.classList.add('table__pagination');
391
+ form.classList.add('row');
392
+ form.classList.add('pt-3');
393
+ form.classList.add('pb-3');
394
+ // Create the form and create a container div to hold the pagination buttons
395
+ form.innerHTML = `<div class="col mw-fit-content mb-3">
514
396
  <div class="form-control__wrapper form-control-inline mb-0">
515
397
  <label for="${randID}_showing" class="form-label">Showing:</label>
516
398
  <input type="number" name="${randID}_showing" id="${randID}_showing" class="form-control form-control-sm showing-input-field" placeholder="" list="${randID}_pagination" value="${show}" min="1" max="${totalRows}" />
@@ -524,62 +406,46 @@ ${totalRows > 20 ? `<option value="20">20</option>` : ''}
524
406
  </div>
525
407
  <div class="col mw-fit-content me-auto d-flex align-items-center mb-3"><span class="label">per page</span></div>
526
408
  <div class="col mw-fit-content d-sm-flex justify-content-end align-items-center" id="${randID}_paginationBtns"></div>`;
527
-
528
- // Add after the actual table
529
- tableElement.append(form)
530
- }
531
-
532
- export const createPaginationButttons = function(randID,tableElement,show,page,totalRows){
533
-
534
- const paginationButtonsWrapper = document.getElementById(randID+'_paginationBtns')
535
-
536
- if(paginationButtonsWrapper == null)
537
- return false;
538
-
539
- const numberPages = Math.ceil(totalRows / show)
540
-
541
- if(numberPages == 1){ // Remore the buttons or dont display any if we dont need them
542
- paginationButtonsWrapper.innerHTML = '';
543
- }
544
- else if(numberPages < 5){ // If less than 5 pages (which fits comfortably on mobile) we display buttons
545
-
546
- let strButtons = '';
547
-
548
- for (let i = 1; i <= numberPages; i++) {
549
-
550
- if(i == page)
551
- strButtons += `<li class="page-item active" aria-current="page"><span class="page-link">${i}</span></li>`;
552
- else
553
- strButtons += `<li class="page-item"><button class="page-link" data-page="${i}">${i}</button></li>`;
409
+ // Add after the actual table
410
+ tableElement.append(form);
411
+ };
412
+ export const createPaginationButttons = function (randID, tableElement, show, page, totalRows) {
413
+ const paginationButtonsWrapper = document.getElementById(randID + '_paginationBtns');
414
+ if (paginationButtonsWrapper == null)
415
+ return false;
416
+ const numberPages = Math.ceil(totalRows / show);
417
+ if (numberPages == 1) { // Remore the buttons or dont display any if we dont need them
418
+ paginationButtonsWrapper.innerHTML = '';
554
419
  }
555
-
556
- paginationButtonsWrapper.innerHTML = `<span class="pe-2 mb-3">Page: </span><ul class="pagination mb-3">
557
- ${page == 1 ? `<li class="page-item disabled"><span class="page-link">Previous</span></li>` : `<li class="page-item"><button class="page-link" data-page="${parseInt(page)-1}">Previous</button></li>`}
420
+ else if (numberPages < 5) { // If less than 5 pages (which fits comfortably on mobile) we display buttons
421
+ let strButtons = '';
422
+ for (let i = 1; i <= numberPages; i++) {
423
+ if (i == page)
424
+ strButtons += `<li class="page-item active" aria-current="page"><span class="page-link">${i}</span></li>`;
425
+ else
426
+ strButtons += `<li class="page-item"><button class="page-link" data-page="${i}">${i}</button></li>`;
427
+ }
428
+ paginationButtonsWrapper.innerHTML = `<span class="pe-2 mb-3">Page: </span><ul class="pagination mb-3">
429
+ ${page == 1 ? `<li class="page-item disabled"><span class="page-link">Previous</span></li>` : `<li class="page-item"><button class="page-link" data-page="${parseInt(page) - 1}">Previous</button></li>`}
558
430
  ${strButtons}
559
- ${page == numberPages ? `<li class="page-item disabled"><span class="page-link">Next</span></li>` : `<li class="page-item"><button class="page-link" data-page="${parseInt(page)+1}">Next</button></li>`}
431
+ ${page == numberPages ? `<li class="page-item disabled"><span class="page-link">Next</span></li>` : `<li class="page-item"><button class="page-link" data-page="${parseInt(page) + 1}">Next</button></li>`}
560
432
  </ul>`;
561
-
562
- }
563
- else { // If more than 5 lets show a select field instead so that we dont have loads and loads of buttons
564
-
565
- let strOptions = '';
566
-
567
- for (let i = 1; i <= numberPages; i++) {
568
-
569
- if(i == page)
570
- strOptions += `<option value="${i}" selected>Page ${i}</option>`;
571
- else
572
- strOptions += `<option value="${i}">Page ${i}</option>`;
573
433
  }
574
-
575
- paginationButtonsWrapper.innerHTML = `
434
+ else { // If more than 5 lets show a select field instead so that we dont have loads and loads of buttons
435
+ let strOptions = '';
436
+ for (let i = 1; i <= numberPages; i++) {
437
+ if (i == page)
438
+ strOptions += `<option value="${i}" selected>Page ${i}</option>`;
439
+ else
440
+ strOptions += `<option value="${i}">Page ${i}</option>`;
441
+ }
442
+ paginationButtonsWrapper.innerHTML = `
576
443
  <div class="form-control__wrapper page-number mb-2">
577
444
  <select class="form-select">
578
445
  ${strOptions}
579
446
  </select>
580
447
  </div>
581
448
  `;
582
- }
583
- }
584
-
585
- export default table
449
+ }
450
+ };
451
+ export default table;