@iamproperty/components 5.5.1-beta-2 → 5.5.1-beta-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 (84) hide show
  1. package/assets/css/components/actionbar.css +1 -1
  2. package/assets/css/components/actionbar.css.map +1 -1
  3. package/assets/css/components/actionbar.global.css +1 -1
  4. package/assets/css/components/actionbar.global.css.map +1 -1
  5. package/assets/css/components/inline-edit.css +1 -0
  6. package/assets/css/components/inline-edit.css.map +1 -0
  7. package/assets/css/components/inline-edit.preload.css +1 -0
  8. package/assets/css/components/inline-edit.preload.css.map +1 -0
  9. package/assets/css/components/multiselect.css +1 -0
  10. package/assets/css/components/multiselect.css.map +1 -0
  11. package/assets/css/components/multiselect.preload.css +1 -0
  12. package/assets/css/components/multiselect.preload.css.map +1 -0
  13. package/assets/css/components/nav.global.css +1 -1
  14. package/assets/css/components/nav.global.css.map +1 -1
  15. package/assets/css/core.min.css +1 -1
  16. package/assets/css/core.min.css.map +1 -1
  17. package/assets/css/style.min.css +1 -1
  18. package/assets/css/style.min.css.map +1 -1
  19. package/assets/js/components/accordion/accordion.component.min.js +1 -1
  20. package/assets/js/components/actionbar/actionbar.component.js +2 -0
  21. package/assets/js/components/actionbar/actionbar.component.min.js +5 -3
  22. package/assets/js/components/actionbar/actionbar.component.min.js.map +1 -1
  23. package/assets/js/components/address-lookup/address-lookup.component.min.js +1 -1
  24. package/assets/js/components/applied-filters/applied-filters.component.min.js +1 -1
  25. package/assets/js/components/card/card.component.min.js +1 -1
  26. package/assets/js/components/collapsible-side/collapsible-side.component.min.js +1 -1
  27. package/assets/js/components/fileupload/fileupload.component.min.js +1 -1
  28. package/assets/js/components/filterlist/filterlist.component.min.js +1 -1
  29. package/assets/js/components/header/header.component.min.js +1 -1
  30. package/assets/js/components/inline-edit/inline-edit.component.js +148 -0
  31. package/assets/js/components/inline-edit/inline-edit.component.min.js +22 -0
  32. package/assets/js/components/inline-edit/inline-edit.component.min.js.map +1 -0
  33. package/assets/js/components/multiselect/multiselect.component.js +221 -0
  34. package/assets/js/components/multiselect/multiselect.component.min.js +25 -0
  35. package/assets/js/components/multiselect/multiselect.component.min.js.map +1 -0
  36. package/assets/js/components/nav/nav.component.min.js +2 -2
  37. package/assets/js/components/notification/notification.component.min.js +1 -1
  38. package/assets/js/components/pagination/pagination.component.min.js +1 -1
  39. package/assets/js/components/search/search.component.min.js +1 -1
  40. package/assets/js/components/search/search.component.min.js.map +1 -1
  41. package/assets/js/components/table/table.component.js +26 -14
  42. package/assets/js/components/table/table.component.min.js +4 -4
  43. package/assets/js/components/table/table.component.min.js.map +1 -1
  44. package/assets/js/components/tabs/tabs.component.min.js +1 -1
  45. package/assets/js/dynamic.min.js +5 -5
  46. package/assets/js/dynamic.min.js.map +1 -1
  47. package/assets/js/modules/helpers.js +4 -0
  48. package/assets/js/modules/inputs.js +6 -2
  49. package/assets/js/modules/table.js +36 -18
  50. package/assets/js/scripts.bundle.js +4 -4
  51. package/assets/js/scripts.bundle.js.map +1 -1
  52. package/assets/js/scripts.bundle.min.js +2 -2
  53. package/assets/js/scripts.bundle.min.js.map +1 -1
  54. package/assets/sass/_components.scss +5 -0
  55. package/assets/sass/components/actionbar.global.scss +10 -0
  56. package/assets/sass/components/actionbar.scss +20 -3
  57. package/assets/sass/components/inline-edit.preload.scss +98 -0
  58. package/assets/sass/components/inline-edit.scss +32 -0
  59. package/assets/sass/components/multiselect.preload.scss +37 -0
  60. package/assets/sass/components/multiselect.scss +186 -0
  61. package/assets/sass/components/nav.global.scss +2 -0
  62. package/assets/sass/elements/admin-panel.scss +0 -3
  63. package/assets/sass/elements/badge-tag.scss +15 -5
  64. package/assets/sass/elements/forms.scss +16 -3
  65. package/assets/ts/components/actionbar/actionbar.component.ts +2 -0
  66. package/assets/ts/components/inline-edit/README.md +30 -0
  67. package/assets/ts/components/inline-edit/inline-edit.component.ts +211 -0
  68. package/assets/ts/components/multiselect/README.md +35 -0
  69. package/assets/ts/components/multiselect/multiselect.component.ts +304 -0
  70. package/assets/ts/components/search/README.md +36 -0
  71. package/assets/ts/components/table/table.component.ts +28 -21
  72. package/assets/ts/modules/helpers.ts +6 -0
  73. package/assets/ts/modules/inputs.ts +8 -2
  74. package/assets/ts/modules/table.ts +40 -19
  75. package/dist/components.es.js +66 -65
  76. package/dist/components.umd.js +61 -64
  77. package/package.json +1 -1
  78. package/src/components/InlineEdit/InlineEdit.vue +45 -0
  79. package/src/components/InlineEdit/README.md +7 -0
  80. package/src/components/Multiselect/Multiselect.vue +24 -0
  81. package/src/components/Multiselect/README.md +12 -0
  82. package/src/components/Search/README.md +11 -0
  83. package/src/components/Search/Search.vue +1 -1
  84. package/src/components/Table/Table.vue +2 -1
@@ -0,0 +1,211 @@
1
+ // @ts-nocheck
2
+
3
+ // Data layer Web component created
4
+ window.dataLayer = window.dataLayer || [];
5
+ window.dataLayer.push({
6
+ "event": "customElementRegistered",
7
+ "element": "inline edit"
8
+ });
9
+
10
+ class iamInlineEdit extends HTMLElement {
11
+
12
+ constructor(){
13
+ super();
14
+ const shadowRoot = this.attachShadow({ mode: 'open'});
15
+
16
+ const assetLocation = document.body.hasAttribute('data-assets-location') ? document.body.getAttribute('data-assets-location') : '/assets';
17
+ const coreCSS = document.body.hasAttribute('data-core-css') ? document.body.getAttribute('data-core-css') : `${assetLocation}/css/core.min.css`;
18
+ const loadCSS = `@import "${assetLocation}/css/components/inline-edit.css";`;
19
+
20
+ const template = document.createElement('template');
21
+ template.innerHTML = `
22
+ <style class="styles">
23
+ @import "${coreCSS}";
24
+ ${loadCSS}
25
+ </style>
26
+ <link rel="stylesheet" href="https://kit.fontawesome.com/26fdbf0179.css" crossorigin="anonymous">
27
+
28
+ <slot></slot>
29
+ <div class="btns">
30
+ <button class="btn btn-action" id="save"><i class="fa-regular fa-save m-0"></i> Save</button><button class="btn btn-action" id="cancel">Cancel</button>
31
+ </div>
32
+ <div class="status pe-none">
33
+ <span class="btn btn-action border-0 bg-transparent prevent-invert d-none" id="saving"><i class="fa-regular fa-spinner fa-spin me-1"></i> Saving...</span>
34
+ <span class="btn btn-action border-0 bg-transparent prevent-invert d-none" id="saved"><i class="fa-regular fa-check me-1"></i> Saved</span>
35
+ <span class="btn btn-action border-0 bg-transparent prevent-invert d-none" id="notsaved"><i class="fa-regular fa-circle-info me-1"></i> Not Saved</span>
36
+ </div>
37
+ `;
38
+
39
+ shadowRoot.appendChild(template.content.cloneNode(true));
40
+ }
41
+
42
+ connectedCallback() {
43
+
44
+ let inlineEdit = this;
45
+ let saveButton = this.shadowRoot.querySelector('#save');
46
+ let cancelButton = this.shadowRoot.querySelector('#cancel');
47
+
48
+ let label = this.querySelector('label');
49
+ let input = this.querySelector('input, textarea, select');
50
+
51
+ let statusSaving = this.shadowRoot.querySelector('#saving');
52
+ let statusSaved = this.shadowRoot.querySelector('#saved');
53
+ let statusNotSaved = this.shadowRoot.querySelector('#notsaved');
54
+
55
+ // Save the original value for later
56
+ let originalValue = input.value;
57
+
58
+ // cancel
59
+ cancelButton.addEventListener('click', (event) => {
60
+
61
+
62
+ console.log(originalValue)
63
+
64
+ input.value = originalValue;
65
+
66
+
67
+ input.blur();
68
+ inlineEdit.blur();
69
+
70
+ inlineEdit.classList.remove('was-validated');
71
+ statusNotSaved.classList.add('d-none');
72
+
73
+ const cancelEvent = new CustomEvent("inline-edit-cancel", { detail: { name: input.getAttribute('name')} });
74
+ inlineEdit.dispatchEvent(cancelEvent);
75
+ });
76
+
77
+ // Save
78
+ saveButton.addEventListener('click', (event) => {
79
+
80
+ if(inlineEdit.querySelector(':invalid')){
81
+
82
+ inlineEdit.classList.add('was-validated');
83
+
84
+ return false;
85
+ }
86
+
87
+ originalValue = input.value;
88
+
89
+ // dispatch save event
90
+ const saveEvent = new CustomEvent("inline-edit-save", { detail: { name: input.getAttribute('name'), value: input.value } });
91
+ inlineEdit.dispatchEvent(saveEvent);
92
+
93
+ //inlineEdit.setAttribute('data-saving','true');
94
+ input.disabled = true;
95
+
96
+ input.blur();
97
+ inlineEdit.blur();
98
+
99
+
100
+ statusSaving.classList.remove('d-none');
101
+ });
102
+
103
+ // Save
104
+ if(input.tagName === 'input'){
105
+ input.addEventListener('keydown', (event) => {
106
+
107
+ switch (event.key) { // change to event.key to key to use the above variable
108
+ case "Enter":
109
+
110
+ event.stopPropagation();
111
+ event.preventDefault();
112
+
113
+ saveButton.click();
114
+
115
+ break;
116
+ }
117
+ });
118
+ }
119
+
120
+ // Saved
121
+ inlineEdit.addEventListener('inline-edit-saved', (event) => {
122
+
123
+ setTimeout(() => {
124
+
125
+ statusSaving.classList.add('d-none');
126
+ statusSaved.classList.remove('d-none');
127
+
128
+ const confirmEvent = new CustomEvent("inline-edit-confirmed", { detail: { name: input.getAttribute('name') } });
129
+ inlineEdit.dispatchEvent(confirmEvent);
130
+ }, 100);
131
+
132
+ // Reset to normal
133
+ setTimeout(() => {
134
+
135
+ input.disabled = false;
136
+ inlineEdit.removeAttribute('data-saving');
137
+
138
+ statusSaving.classList.add('d-none');
139
+ statusSaved.classList.add('d-none');
140
+ statusNotSaved.classList.add('d-none');
141
+ }, 1000);
142
+ });
143
+
144
+ // enter key saves
145
+ if(input.tagName === 'SELECT'){
146
+
147
+ input.addEventListener('change',(event) => {
148
+
149
+ originalValue = input.value;
150
+
151
+ const saveEvent = new CustomEvent("inline-edit-save", { detail: { name: input.getAttribute('name'), value: input.value } });
152
+ inlineEdit.dispatchEvent(saveEvent);
153
+
154
+ inlineEdit.setAttribute('data-saving','true');
155
+ input.disabled = true;
156
+
157
+ input.blur();
158
+ });
159
+ }
160
+
161
+ if(input.tagName != 'SELECT'){
162
+ input.addEventListener('focus',(event) => {
163
+
164
+ input.select();
165
+ });
166
+ }
167
+
168
+ //blur it should autosave
169
+ inlineEdit.addEventListener('blur',(event) => {
170
+
171
+ if(input.value != originalValue){
172
+
173
+ let feedbackText = '(Unsaved)';
174
+
175
+ if(inlineEdit.hasAttribute('data-autosave')) {
176
+
177
+ originalValue = input.value;
178
+
179
+ const saveEvent = new CustomEvent("inline-edit-autosave", { detail: { name: input.getAttribute('name'), value: input.value } });
180
+ inlineEdit.dispatchEvent(saveEvent);
181
+
182
+ statusSaving.classList.remove('d-none');
183
+ }
184
+ else if(!inlineEdit.querySelector('.inline-feedback')){
185
+ statusNotSaved.classList.remove('d-none');
186
+ }
187
+ }
188
+ });
189
+
190
+ // checkboxes
191
+ inlineEdit.addEventListener('change', (event) => {
192
+ if (event && event.target instanceof HTMLElement && event.target.closest('input[type="checkbox"]')){
193
+
194
+ let saveValue = "";
195
+
196
+ Array.from(inlineEdit.querySelectorAll(`label input[type="checkbox"]:checked`)).forEach((checkbox, index) => {
197
+
198
+ if(index != 0)
199
+ saveValue += ", ";
200
+
201
+ saveValue += checkbox.value;
202
+ });
203
+
204
+ const saveEvent = new CustomEvent("inline-edit-save", { detail: { name: event.target.closest('input[type="checkbox"]').getAttribute('name'), value: saveValue } });
205
+ inlineEdit.dispatchEvent(saveEvent);
206
+ }
207
+ });
208
+ }
209
+ }
210
+
211
+ export default iamInlineEdit;
@@ -0,0 +1,35 @@
1
+ **Add the below to your initialise script**
2
+
3
+ ```
4
+ import('../node_modules/@iamproperty/components/assets/js/components/fileupload/fileupload.component.min').then(module => { // Might need to update the path
5
+
6
+ if (!window.customElements.get(`iam-fileupload`))
7
+ window.customElements.define(`iam-fileupload`, module.default);
8
+
9
+ }).catch((err) => {
10
+ console.log(err.message);
11
+ });
12
+ ```
13
+
14
+ **Add the below HTML code to where you want the component to live.**
15
+
16
+ ```
17
+ <iam-multiselect>
18
+ <span class="label" slot="label">Users</span>
19
+ <label class="tag"><input type="checkbox" name="tags" value="IT James Lambert" />James Lambert</label>
20
+ <label class="tag"><input type="checkbox" name="tags" value="IT Amanda Knight"/>Amanda Knight</label>
21
+ <label class="tag"><input type="checkbox" name="tags" value="IT Brian Lord"/>Brian Lord</label>
22
+ <label class="tag"><input type="checkbox" name="tags" value="Claire Lane"/>Claire Lane</label>
23
+ <label class="tag"><input type="checkbox" name="tags" value="John Smith"/>John Smith</label>
24
+ <label class="tag"><input type="checkbox" name="tags" value="James Brown"/>James Brown</label>
25
+ <label class="tag"><input type="checkbox" name="tags" value="Sarah Brown"/>Sarah Brown</label>
26
+ </iam-multiselect>
27
+ ```
28
+
29
+ **Properties**
30
+
31
+ | Option | Type | Default Value | Description |
32
+ | ------ | ---- | ------------- | ----------- |
33
+ | data-min | Int | - | Set's the minimum amout of tags needed for the input field to validate |
34
+ | data-min | Int | - | Set's the maximum amout of tags allowed to be added |
35
+ | data-is-required | flag | - | Makes it so at least one tag must be added for the it to be valid and allow the outer form to be sumitted |
@@ -0,0 +1,304 @@
1
+ // @ts-nocheck
2
+
3
+ // Data layer Web component created
4
+ window.dataLayer = window.dataLayer || [];
5
+ window.dataLayer.push({
6
+ "event": "customElementRegistered",
7
+ "element": "mutliselect"
8
+ });
9
+
10
+ class iamMultiselect extends HTMLElement {
11
+
12
+ constructor(){
13
+ super();
14
+ this.attachShadow({ mode: 'open'});
15
+
16
+ const assetLocation = document.body.hasAttribute('data-assets-location') ? document.body.getAttribute('data-assets-location') : '/assets'
17
+ const coreCSS = document.body.hasAttribute('data-core-css') ? document.body.getAttribute('data-core-css') : `${assetLocation}/css/core.min.css`;
18
+ const loadCSS = `@import "${assetLocation}/css/components/multiselect.css";`;
19
+
20
+ const template = document.createElement('template');
21
+ template.innerHTML = `
22
+ <style>
23
+ @import "${coreCSS}";
24
+ ${loadCSS}
25
+ ${this.hasAttribute('css') ? `@import "${this.getAttribute('css')}";` : ``}
26
+ </style>
27
+ <label for="search"> <slot name="feedback"></slot></label>
28
+ <div class="outer">
29
+ <div class="wrapper">
30
+
31
+ <slot name="checked"></slot>
32
+ <input name="search" id="search" autocomplete="off" required />
33
+ <span class="admin-panel feedback">This field is required</span>
34
+ <div class="admin-panel dropdown">
35
+ <slot></slot>
36
+ </div>
37
+ <button id="clear"><span class="visually-hidden">Clear</span></button>
38
+ </div>
39
+ </div>
40
+ `;
41
+ this.shadowRoot.appendChild(template.content.cloneNode(true));
42
+ }
43
+
44
+ connectedCallback() {
45
+
46
+ let multiselect = this;
47
+ let form = this.closest('form');
48
+ let wrapper = this.shadowRoot.querySelector('.wrapper');
49
+ let search = multiselect.shadowRoot.querySelector('#search');
50
+ let button = multiselect.shadowRoot.querySelector('#clear');
51
+ let order = 0;
52
+ let label = multiselect.shadowRoot.querySelector('label');
53
+
54
+
55
+ label.innerHTML = multiselect.getAttribute('data-label');
56
+
57
+ if(multiselect.hasAttribute('placeholder')){
58
+
59
+ search.setAttribute('placeholder', multiselect.getAttribute('placeholder'));
60
+ }
61
+
62
+ multiselect.setAttribute('data-error','true');
63
+
64
+ // If in form and is required lets watch for the form being submitted
65
+ if(form && multiselect.hasAttribute('data-is-required')){
66
+
67
+ let observer = new MutationObserver(function(mutations) {
68
+ mutations.forEach(function(mutationRecord) {
69
+ const targetElement = mutationRecord.target as HTMLElement;
70
+
71
+ console.log(targetElement);
72
+
73
+ if (targetElement.classList.contains("was-validated")) {
74
+ wrapper.classList.add('was-validated');
75
+ } else {
76
+ wrapper.classList.remove('was-validated');
77
+ };
78
+ })
79
+ });
80
+
81
+ if (form.classList.contains("was-validated")) {
82
+ wrapper.classList.add('was-validated');
83
+ } else {
84
+ wrapper.classList.remove('was-validated');
85
+ };
86
+
87
+ observer.observe(form, {
88
+ attributes : true,
89
+ attributeFilter : ['style', 'class']
90
+ });
91
+ }
92
+
93
+ // Set the correct attributes
94
+ function setItem(inputToSet){
95
+
96
+ if(inputToSet.checked == false){
97
+
98
+ inputToSet.closest('label').removeAttribute('slot');
99
+ inputToSet.closest('label').removeAttribute('style');
100
+ inputToSet.closest('label').removeAttribute('data-order');
101
+ }
102
+ else {
103
+
104
+ order++;
105
+
106
+ inputToSet.closest('label').setAttribute('slot','checked');
107
+ inputToSet.closest('label').setAttribute('style',`--order:${order};`);
108
+ inputToSet.closest('label').setAttribute('data-order',order);
109
+ }
110
+
111
+ // check for errors
112
+ if(multiselect.querySelector('label[slot="checked"]')){
113
+ wrapper.classList.add('filled');
114
+ multiselect.removeAttribute('data-error');
115
+
116
+ search.removeAttribute('placeholder');
117
+ }
118
+ else {
119
+ wrapper.classList.remove('filled');
120
+ multiselect.setAttribute('data-error','true');
121
+
122
+ if(multiselect.hasAttribute('placeholder')){
123
+
124
+ search.setAttribute('placeholder', multiselect.getAttribute('placeholder'));
125
+ }
126
+ }
127
+
128
+
129
+ }
130
+
131
+ // Set on load
132
+ Array.from(multiselect.querySelectorAll(`label input[type="checkbox"]:checked`)).forEach((checkbox, index) => {
133
+
134
+ setItem(checkbox);
135
+ });
136
+
137
+
138
+ // Filter list
139
+ search.addEventListener('input', (event) => {
140
+
141
+ Array.from(multiselect.querySelectorAll(`label:not([slot="checked"])`)).forEach((label, index) => {
142
+
143
+ let checkbox = label.querySelector('input');
144
+ let searchValue = checkbox.value;
145
+
146
+ if(searchValue.toLowerCase().includes(search.value.toLowerCase())){
147
+ label.removeAttribute('slot')
148
+ }
149
+ else {
150
+ label.setAttribute('slot','notmatched');
151
+ }
152
+ });
153
+ });
154
+
155
+ // Set items
156
+ multiselect.addEventListener('change', (event) => {
157
+
158
+ if (event && event.target instanceof HTMLElement && event.target.closest('input[type="checkbox"]')){
159
+ let checkbox = event.target.closest('input[type="checkbox"]');
160
+
161
+ setItem(checkbox);
162
+
163
+ search.focus();
164
+ }
165
+ });
166
+
167
+ // Clear all
168
+ button.addEventListener("click", function(event) {
169
+
170
+ Array.from(multiselect.querySelectorAll(`label input[type="checkbox"]`)).forEach((checkbox, index) => {
171
+
172
+ checkbox.checked = false;
173
+
174
+ setItem(checkbox);
175
+ });
176
+
177
+ search.focus();
178
+ });
179
+
180
+ // Add some keyboard features to keep it accessible
181
+ multiselect.addEventListener("keydown", function(event) {
182
+
183
+ const activeElement = document.activeElement;
184
+
185
+ switch (event.key) { // change to event.key to key to use the above variable
186
+ case "ArrowUp":
187
+ // Up pressed
188
+ event.preventDefault();
189
+
190
+ if(activeElement.hasAttribute('type') && activeElement.getAttribute('type') == "checkbox"){
191
+
192
+ let arrCheckboxes = multiselect.querySelectorAll(`label:not([slot="checked"]):not([slot="checked"])`);
193
+
194
+ let activeIndex = Array.from(arrCheckboxes).indexOf(activeElement.closest('label'));
195
+ let prevCheckbox = Array.from(arrCheckboxes)[activeIndex-1];
196
+
197
+ if(prevCheckbox)
198
+ prevCheckbox.focus();
199
+ else
200
+ search.focus();
201
+ }
202
+
203
+ break;
204
+ case "ArrowDown":
205
+ // Down pressed
206
+ event.preventDefault();
207
+
208
+ if(activeElement == multiselect){
209
+
210
+ multiselect.querySelector('label:not([slot="checked"]):not([slot="checked"])').focus();
211
+ }
212
+ else if(activeElement.hasAttribute('type') && activeElement.getAttribute('type') == "checkbox"){
213
+
214
+ let activeValue = activeElement.value;
215
+
216
+ let nextCheckbox = multiselect.querySelector(`label:has(input[value="${activeValue}"]) ~ label:not([slot="checked"]):not([slot="checked"])`);
217
+
218
+ if(nextCheckbox)
219
+ nextCheckbox.focus();
220
+ }
221
+
222
+ break;
223
+ case "Enter":
224
+
225
+ event.stopPropagation();
226
+ event.preventDefault();
227
+
228
+ if(activeElement.hasAttribute('type') && activeElement.getAttribute('type') == "checkbox"){
229
+
230
+ if(activeElement.checked == false)
231
+ activeElement.checked = true;
232
+ else
233
+ activeElement.checked = false;
234
+ }
235
+
236
+ setItem(activeElement);
237
+ search.focus();
238
+
239
+ break;
240
+ }
241
+ });
242
+
243
+ function checkLastTag(){
244
+
245
+ if(order == 0)
246
+ return false;
247
+
248
+ let lastTag = multiselect.querySelector(`label[data-order="${order}"]`);
249
+
250
+ if(!lastTag){
251
+ lastTag = checkLastTag(order--);
252
+ }
253
+
254
+ return lastTag;
255
+ }
256
+
257
+ search.addEventListener("keydown", function(event) {
258
+
259
+ switch (event.key) { // change to event.key to key to use the above variable
260
+ case "Enter":
261
+
262
+ let match = multiselect.querySelector(`input[value="${search.value}"]:not(:checked)`);
263
+
264
+ if(!match)
265
+ search.value = "";
266
+
267
+ search.focus();
268
+
269
+ break;
270
+ case "Backspace":
271
+
272
+ if(!search.value){
273
+
274
+ let lastTag = checkLastTag(order);
275
+
276
+ if(lastTag){
277
+
278
+ let lastTagInput = lastTag.querySelector('input');
279
+ lastTagInput.checked = false;
280
+ setItem(lastTagInput);
281
+ }
282
+
283
+ search.focus();
284
+ }
285
+
286
+ break;
287
+ }
288
+ });
289
+
290
+
291
+ // Fix for the inline edit multiselect
292
+ multiselect.addEventListener("mousedown", (event) => {
293
+
294
+ wrapper.setAttribute('data-mousedown','true');
295
+ });
296
+
297
+ multiselect.addEventListener("mouseup", (event) => {
298
+
299
+ wrapper.removeAttribute('data-mousedown');
300
+ });
301
+ }
302
+ }
303
+
304
+ export default iamMultiselect;
@@ -0,0 +1,36 @@
1
+ **Add the below to your initialise script**
2
+
3
+ ```
4
+ import('../node_modules/@iamproperty/components/assets/js/components/fileupload/fileupload.component.min').then(module => { // Might need to update the path
5
+
6
+ if (!window.customElements.get(`iam-fileupload`))
7
+ window.customElements.define(`iam-fileupload`, module.default);
8
+
9
+ }).catch((err) => {
10
+ console.log(err.message);
11
+ });
12
+ ```
13
+
14
+ **Add the below HTML code to where you want the component to live.**
15
+
16
+ ```
17
+ <iam-search>
18
+ <label>Search existing transactions
19
+ <span>
20
+ <input type="text" name="client" autocomplete="off" aria-autocomplete="none" required />
21
+ <span class="suffix fa-regular fa-search"></span>
22
+ </span>
23
+ </label>
24
+ <datalist id="properties"></datalist>
25
+ </iam-search>
26
+ ```
27
+
28
+ **Properties**
29
+
30
+ | Option | Type | Default Value | Description |
31
+ | ------ | ---- | ------------- | ----------- |
32
+ | data-url | String | - | Optional value that populates the datalist with extra results from an API |
33
+ | data-schema | String | - | Tells the JavaScript where to look for the array of values in the API JSON |
34
+ | data-value-schema | String | - | Tells the JavaScript where to look for the value within the API JSON |
35
+ | data-display-schema | String | - | Tells the JavaScript where to look for the title within the API JSON |
36
+
@@ -39,8 +39,9 @@ class iamTable extends HTMLElement {
39
39
  this.shadowRoot.appendChild(template.content.cloneNode(true));
40
40
 
41
41
  // insert extra CSS
42
- if(!document.getElementById('tableExtras'))
42
+ if(!document.getElementById('tableExtras')){
43
43
  document.head.insertAdjacentHTML('beforeend',`<style id="tableExtras">${loadExtraCSS}</style>`);
44
+ }
44
45
  }
45
46
 
46
47
  connectedCallback() {
@@ -48,17 +49,22 @@ class iamTable extends HTMLElement {
48
49
  const params = new URLSearchParams(window.location.search)
49
50
 
50
51
  // Set default attributes
51
- if(!this.hasAttribute('data-total'))
52
+ if(!this.hasAttribute('data-total')){
52
53
  this.setAttribute('data-total', this.querySelectorAll('table tbody tr').length);
54
+ }
53
55
 
54
- if(!this.hasAttribute('data-page'))
56
+ if(!this.hasAttribute('data-page')){
55
57
  this.setAttribute('data-page', (params.has('page') ? params.get('page') : 1));
58
+ }
56
59
 
57
- if(!this.hasAttribute('data-show'))
60
+ if(!this.hasAttribute('data-show')){
58
61
  this.setAttribute('data-show', (params.has('show') ? params.get('show') : 15));
59
-
60
- if(!this.hasAttribute('data-increment'))
62
+ }
63
+
64
+ if(!this.hasAttribute('data-increment')){
61
65
  this.setAttribute('data-increment', this.getAttribute('data-show'));
66
+ }
67
+
62
68
 
63
69
  // Update table__wrapper class
64
70
  let classList = this.classList.toString();
@@ -69,8 +75,9 @@ class iamTable extends HTMLElement {
69
75
  this.shadowRoot.querySelector('.table__wrapper').className += ` ${classList}`;
70
76
 
71
77
  // set actionbar class if needed
72
- if(this.querySelector('.actionbar__sticky'))
78
+ if(this.querySelector('.actionbar__sticky')){
73
79
  this.shadowRoot.querySelector('.table__wrapper').classList.add('has-actionbar');
80
+ }
74
81
 
75
82
  this.table = this.querySelector('table');
76
83
  this.savedTableBody = this.table.querySelector('tbody').cloneNode(true);
@@ -81,21 +88,21 @@ class iamTable extends HTMLElement {
81
88
  this.pagination.setAttribute('data-show', this.getAttribute('data-show'));
82
89
  this.pagination.setAttribute('data-increment', this.getAttribute('data-show'));
83
90
 
84
- if(this.hasAttribute('data-page-jump'))
91
+ if(this.hasAttribute('data-page-jump')){
85
92
  this.pagination.setAttribute('data-page-jump', 'true');
86
-
87
- if(this.hasAttribute('data-per-page'))
93
+ }
94
+ if(this.hasAttribute('data-per-page')){
88
95
  this.pagination.setAttribute('data-per-page', 'true');
89
-
90
- if(this.hasAttribute('data-item-count'))
96
+ }
97
+ if(this.hasAttribute('data-item-count')){
91
98
  this.pagination.setAttribute('data-item-count', 'true');
92
-
93
- if(this.hasAttribute('data-loading'))
99
+ }
100
+ if(this.hasAttribute('data-loading')){
94
101
  this.pagination.setAttribute('data-loading', 'true');
95
-
96
- if(this.classList.contains('table--fullwidth'))
102
+ }
103
+ if(this.classList.contains('table--fullwidth')){
97
104
  this.pagination.setAttribute('data-minimal', 'true');
98
-
105
+ }
99
106
 
100
107
  // Remove table CTA
101
108
  const isCTA = this.classList.contains('table--cta');
@@ -115,9 +122,9 @@ class iamTable extends HTMLElement {
115
122
  }
116
123
 
117
124
  // Set ajax class
118
- if(this.form.hasAttribute('data-ajax'))
125
+ if(this.form.hasAttribute('data-ajax')){
119
126
  this.table.classList.add('table--ajax');
120
-
127
+ }
121
128
  // Create a data list if a search input is present
122
129
  tableModule.createSearchDataList(this.table, this.form);
123
130
 
@@ -150,9 +157,9 @@ class iamTable extends HTMLElement {
150
157
 
151
158
  // Add in the checkboxes
152
159
 
153
- if(this.querySelector('iam-actionbar[data-selectall]')){
160
+ if(this.querySelector('iam-actionbar[data-selectall]') || document.querySelector(`iam-actionbar[data-for='${this.getAttribute('id')}']`)){
154
161
 
155
- const actionbar = this.querySelector('iam-actionbar[data-selectall]');
162
+ const actionbar = this.querySelector('iam-actionbar[data-selectall]') ? this.querySelector('iam-actionbar[data-selectall]') : document.querySelector(`iam-actionbar[data-for='${this.getAttribute('id')}']`);
156
163
 
157
164
  Array.from(this.table.querySelectorAll('thead tr')).forEach((row,index) => {
158
165