@iamproperty/components 7.5.1--beta2 → 7.5.1--beta3

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 (133) hide show
  1. package/assets/css/components/actionbar.component.css +1 -1
  2. package/assets/css/components/actionbar.component.css.map +1 -1
  3. package/assets/css/components/address-lookup.component.css +1 -1
  4. package/assets/css/components/address-lookup.component.css.map +1 -1
  5. package/assets/css/components/address-lookup.preload.css +1 -0
  6. package/assets/css/components/address-lookup.preload.css.map +1 -0
  7. package/assets/css/components/barchart.component.css +1 -1
  8. package/assets/css/components/barchart.component.css.map +1 -1
  9. package/assets/css/components/calendar.component.css +1 -1
  10. package/assets/css/components/calendar.component.css.map +1 -1
  11. package/assets/css/components/card.component.css +1 -1
  12. package/assets/css/components/card.component.css.map +1 -1
  13. package/assets/css/components/carousel.component.css +1 -1
  14. package/assets/css/components/carousel.component.css.map +1 -1
  15. package/assets/css/components/collapsible-side.css +1 -1
  16. package/assets/css/components/collapsible-side.css.map +1 -1
  17. package/assets/css/components/content.component.css +1 -1
  18. package/assets/css/components/content.component.css.map +1 -1
  19. package/assets/css/components/doughnutchart.component.css +1 -1
  20. package/assets/css/components/doughnutchart.component.css.map +1 -1
  21. package/assets/css/components/fileupload.css +1 -1
  22. package/assets/css/components/fileupload.css.map +1 -1
  23. package/assets/css/components/inline-edit.css +1 -1
  24. package/assets/css/components/inline-edit.css.map +1 -1
  25. package/assets/css/components/multiselect.css +1 -1
  26. package/assets/css/components/multiselect.css.map +1 -1
  27. package/assets/css/components/nav.component.css +1 -1
  28. package/assets/css/components/nav.component.css.map +1 -1
  29. package/assets/css/components/pagination.css +1 -1
  30. package/assets/css/components/pagination.css.map +1 -1
  31. package/assets/css/components/slider.css +1 -1
  32. package/assets/css/components/slider.css.map +1 -1
  33. package/assets/css/components/split-button.component.css +1 -1
  34. package/assets/css/components/split-button.component.css.map +1 -1
  35. package/assets/css/components/table-basic.global.css +1 -1
  36. package/assets/css/components/table-basic.global.css.map +1 -1
  37. package/assets/css/components/table.global.css +1 -1
  38. package/assets/css/components/table.global.css.map +1 -1
  39. package/assets/css/components/tabs.component.css +1 -1
  40. package/assets/css/components/tabs.component.css.map +1 -1
  41. package/assets/css/core.min.css +1 -1
  42. package/assets/css/core.min.css.map +1 -1
  43. package/assets/css/mobile-core.min.css +1 -1
  44. package/assets/css/mobile-core.min.css.map +1 -1
  45. package/assets/css/mobile.min.css +1 -1
  46. package/assets/css/mobile.min.css.map +1 -1
  47. package/assets/css/style.min.css +1 -1
  48. package/assets/css/style.min.css.map +1 -1
  49. package/assets/js/components/accordion/accordion.component.min.js +1 -1
  50. package/assets/js/components/actionbar/actionbar.component.min.js +4 -4
  51. package/assets/js/components/actionbar/actionbar.component.min.js.map +1 -1
  52. package/assets/js/components/address-lookup/address-lookup.component.js +332 -102
  53. package/assets/js/components/address-lookup/address-lookup.component.min.js +32 -14
  54. package/assets/js/components/address-lookup/address-lookup.component.min.js.map +1 -1
  55. package/assets/js/components/advanced-select/advanced-select.component.min.js +3 -3
  56. package/assets/js/components/advanced-select/advanced-select.component.min.js.map +1 -1
  57. package/assets/js/components/applied-filters/applied-filters.component.min.js +1 -1
  58. package/assets/js/components/barchart/barchart.component.min.js +2 -2
  59. package/assets/js/components/barchart/barchart.component.min.js.map +1 -1
  60. package/assets/js/components/bento-grid/bento-grid.component.min.js +1 -1
  61. package/assets/js/components/calendar/calendar.component.min.js +5 -5
  62. package/assets/js/components/calendar/calendar.component.min.js.map +1 -1
  63. package/assets/js/components/card/card.component.min.js +2 -2
  64. package/assets/js/components/carousel/carousel.component.min.js +2 -2
  65. package/assets/js/components/collapsible-side/collapsible-side.component.min.js +2 -2
  66. package/assets/js/components/content/content.component.min.js +2 -2
  67. package/assets/js/components/darkmode/darkmode.component.min.js +1 -1
  68. package/assets/js/components/doughnutchart/doughnutchart.component.min.js +2 -2
  69. package/assets/js/components/doughnutchart/doughnutchart.component.min.js.map +1 -1
  70. package/assets/js/components/fileupload/fileupload.component.min.js +4 -4
  71. package/assets/js/components/filter-card/filter-card.component.min.js +1 -1
  72. package/assets/js/components/filterlist/filterlist.component.min.js +1 -1
  73. package/assets/js/components/header/header.component.min.js +1 -1
  74. package/assets/js/components/inline-edit/inline-edit.component.min.js +3 -3
  75. package/assets/js/components/marketing/marketing.component.min.js +1 -1
  76. package/assets/js/components/menu/menu.component.min.js +1 -1
  77. package/assets/js/components/milestone/milestone.component.min.js +1 -1
  78. package/assets/js/components/milestone-group/milestone-group.component.min.js +1 -1
  79. package/assets/js/components/multi-step/multi-step.component.min.js +1 -1
  80. package/assets/js/components/multiselect/multiselect.component.min.js +4 -4
  81. package/assets/js/components/nav/nav.component.min.js +5 -5
  82. package/assets/js/components/notification/notification.component.min.js +1 -1
  83. package/assets/js/components/pagination/pagination.component.min.js +3 -3
  84. package/assets/js/components/password-indicator/password-indicator.component.min.js +1 -1
  85. package/assets/js/components/rank/rank.component.min.js +1 -1
  86. package/assets/js/components/rankings/rankings.component.min.js +1 -1
  87. package/assets/js/components/record-card/record-card.component.min.js +1 -1
  88. package/assets/js/components/search/search.component.js +64 -24
  89. package/assets/js/components/search/search.component.min.js +5 -5
  90. package/assets/js/components/search/search.component.min.js.map +1 -1
  91. package/assets/js/components/slider/slider.component.min.js +3 -3
  92. package/assets/js/components/split-button/split-button.component.min.js +3 -3
  93. package/assets/js/components/std-address-lookup/std-address-lookup.component.js +1715 -0
  94. package/assets/js/components/std-address-lookup/std-address-lookup.component.min.js +172 -0
  95. package/assets/js/components/std-address-lookup/std-address-lookup.component.min.js.map +1 -0
  96. package/assets/js/components/table/table.component.min.js +2 -2
  97. package/assets/js/components/table/table.component.min.js.map +1 -1
  98. package/assets/js/components/table-ajax/table-ajax.component.min.js +2 -2
  99. package/assets/js/components/table-ajax/table-ajax.component.min.js.map +1 -1
  100. package/assets/js/components/table-basic/table-basic.component.min.js +4 -4
  101. package/assets/js/components/table-basic/table-basic.component.min.js.map +1 -1
  102. package/assets/js/components/table-no-submit/table-no-submit.component.min.js +5 -5
  103. package/assets/js/components/table-no-submit/table-no-submit.component.min.js.map +1 -1
  104. package/assets/js/components/table-submit/table-submit.component.min.js +2 -2
  105. package/assets/js/components/table-submit/table-submit.component.min.js.map +1 -1
  106. package/assets/js/components/tabs/tabs.component.min.js +2 -2
  107. package/assets/js/components/tabs/tabs.component.min.js.map +1 -1
  108. package/assets/js/components/video-card/video-card.component.min.js +1 -1
  109. package/assets/js/components/word-count/word-count.component.min.js +1 -1
  110. package/assets/js/modules/advanced-select.js +26 -25
  111. package/assets/js/modules/helpers.js +15 -3
  112. package/assets/js/scripts.bundle.js +3 -3
  113. package/assets/js/scripts.bundle.js.map +1 -1
  114. package/assets/js/scripts.bundle.min.js +2 -2
  115. package/assets/js/scripts.bundle.min.js.map +1 -1
  116. package/assets/sass/_components.scss +6 -0
  117. package/assets/sass/components/address-lookup.component.scss +91 -5
  118. package/assets/sass/components/address-lookup.preload.scss +81 -0
  119. package/assets/sass/components/table-basic.global.scss +175 -0
  120. package/assets/sass/components/table.global.scss +0 -163
  121. package/assets/sass/elements/buttons--action.scss +26 -0
  122. package/assets/sass/elements/buttons--global.scss +1 -4
  123. package/assets/sass/elements/forms.scss +181 -35
  124. package/assets/ts/components/address-lookup/address-lookup.component.ts +421 -108
  125. package/assets/ts/components/advanced-select/advanced-select.component.ts +1 -0
  126. package/assets/ts/components/search/search.component.ts +85 -26
  127. package/assets/ts/components/std-address-lookup/std-address-lookup.component.ts +1760 -0
  128. package/assets/ts/modules/advanced-select.ts +36 -26
  129. package/assets/ts/modules/helpers.ts +17 -3
  130. package/dist/components.es.js +144 -144
  131. package/dist/components.umd.js +372 -187
  132. package/package.json +1 -1
  133. package/src/components/STDAddressLookup/STDAddressLookup.vue +22 -0
@@ -1,4 +1,5 @@
1
1
  import Cookies from 'js-cookie';
2
+ import advancedSelect from '../../modules/advanced-select';
2
3
 
3
4
  // Data layer Web component created
4
5
  declare global {
@@ -20,8 +21,8 @@ class iamAddressLookup extends HTMLElement {
20
21
  const assetLocation = document.body.hasAttribute('data-assets-location')
21
22
  ? document.body.getAttribute('data-assets-location')
22
23
  : '/assets';
23
-
24
- const loadCSS = `@import "${assetLocation}/css/components/address-lookup.css";`;
24
+
25
+ const loadCSS = `@import "${assetLocation}/css/components/address-lookup.component.css";`;
25
26
 
26
27
  const template = document.createElement('template');
27
28
  template.innerHTML = `
@@ -32,29 +33,47 @@ class iamAddressLookup extends HTMLElement {
32
33
  <link rel="stylesheet" href="https://kit.fontawesome.com/26fdbf0179.css" crossorigin="anonymous" />
33
34
  <div class="wrapper">
34
35
 
35
- <div class="postcode-lookup">
36
+ <div class="postcode-lookup was-validated">
36
37
  <div>
37
- <label class="mb-2">Search <span class="title text-lowercase"></span> <span class="optional">(Optional)</span>
38
+ <label class="mb-1"><span class="title text-lowercase"></span>
38
39
  <span>
39
- <input type="text" name="postcode" list="address-lookup__addressess" autocomplete="off" aria-autocomplete="none" placeholder="Postcode" part="input" />
40
- <span class="suffix fa-regular fa-search" part="suffix"></span>
40
+ <input type="text" name="postcode" class="${this.hasAttribute('data-input-class') ? this.getAttribute('data-input-class') : ''}" list="address-lookup__addressess" autocomplete="one-time-code" aria-autocomplete="none" placeholder="${this?.hasAttribute('data-placeholder') ? this?.getAttribute('data-placeholder') : 'Postcode'}" value="${this.hasAttribute('data-postcode-value')? this.getAttribute('data-postcode-value') : ''}" part="input" />
41
+ <button id="postcode__submit" class="suffix fa-regular fa-search" part="suffix"></button>
41
42
  </span>
42
- <span class="invalid-feedback">Required Adddress fields missing</span>
43
43
  </label>
44
-
44
+
45
+ <span class="invalid-feedback mb-2">${this.hasAttribute('data-error-msg') ? this.getAttribute('data-error-msg') : 'Required address fields'}</span>
46
+
47
+ <div class="datalist__wrapper ${this.hasAttribute('data-list-class') ? this.getAttribute('data-list-class') : ''}" tabindex="0" part="list-wrapper">
48
+ <slot name="beforeList"></slot>
49
+ <slot name="preloadedList"></slot>
50
+ <datalist id="address-lookup__addressess" class=""></datalist>
51
+ <div id="paginationWrapper"></div>
52
+ <slot name="afterList"></slot>
53
+ </div>
54
+ </div>
55
+ <slot name="hint"></slot>
56
+ <div class="actions">
57
+ <button class="btn btn-tertiary switch-to-manual-btn" type="button" part="manualButton">Or enter address manually</button>
58
+ <slot name="actions"></slot>
45
59
  </div>
46
- <button class="btn btn-tertiary switch-to-manual-btn" type="button" part="button">Or enter address manually</button>
47
60
  </div>
48
- <datalist id="address-lookup__addressess"></datalist>
49
61
 
50
62
  <div class="manual-address pb-2 js-hide">
51
63
  <slot part="contents"></slot>
52
- <button class="btn btn-tertiary switch-to-lookup-btn" type="button" part="button">Use postcode lookup</button>
64
+ <button class="btn btn-tertiary switch-to-lookup-btn" type="button" part="button">${this.hasAttribute('data-postcode-lookup-label')? this.getAttribute('data-postcode-lookup-label') : 'Use postcode lookup'}</button>
53
65
  <slot name="after"></slot>
54
66
  </div>
55
- <div class="pre-filled pb-2 js-hide">
67
+ <div class="pre-filled p-2 js-hide">
56
68
  <strong class="title text-primary d-block"></strong>
57
- <p><span class="pre-filled-address"></span><button class="text-primary text-decoration-none ms-1 cursor-pointer" type="button" part="edit-button"><i class="fa-regular fa-pen-to-square"></i> <span class="visually-hidden">Edit</span></button><slot name="prefilled"></slot></p>
69
+ <p><span class="pre-filled-address"></span>
70
+ <button class="link m-0 text-primary ms-2 cursor-pointer" type="button" part="edit-button">
71
+ <i class="fa-regular fa-pen-to-square m-0"></i> <span class="visually-hidden">Edit</span>
72
+ </button>
73
+ <button class="link m-0 text-primary ms-2 cursor-pointer" type="button" part="remove-button">
74
+ <i class="fa-regular fa-trash m-0"></i> <span class="visually-hidden">Remove</span>
75
+ </button>
76
+ <slot name="prefilled"></slot></p>
58
77
  </div>
59
78
  </div>
60
79
  `;
@@ -66,29 +85,57 @@ class iamAddressLookup extends HTMLElement {
66
85
  const lookupWrapper = this.shadowRoot.querySelector('.postcode-lookup');
67
86
  const manualWrapper = this.shadowRoot.querySelector('.manual-address');
68
87
  const preFilledWrapper = this.shadowRoot.querySelector('.pre-filled');
69
- const list = this.shadowRoot.querySelector('datalist');
88
+ const list = this.querySelector('datalist[slot="preloadedList"]') ? this.querySelector('datalist[slot="preloadedList"]') : this.shadowRoot.querySelector('.datalist__wrapper datalist');
89
+ const listWrapper = this.shadowRoot.querySelector('.datalist__wrapper');
70
90
  const switchManualBtn = this.shadowRoot.querySelector('.switch-to-manual-btn');
71
91
  const switchLookupBtn = this.shadowRoot.querySelector('.switch-to-lookup-btn');
72
- const title = this.hasAttribute('data-title') ? this.getAttribute('data-title') : 'Property address';
73
- const preFilledAddressBtn = this.shadowRoot.querySelector('.pre-filled-address + button');
92
+ const title = this.hasAttribute('data-title') ? this.getAttribute('data-title') : 'Find an address';
93
+ const preFilledAddressBtn = this.shadowRoot.querySelector('[part="edit-button"]');
94
+ const preFilledAddressRemoveBtn = this.shadowRoot.querySelector('[part="remove-button"]');
74
95
  const dataDisplayText = this.hasAttribute('data-display-text');
96
+ const postcodeSubmit = this.shadowRoot?.querySelector('#postcode__submit');
97
+ const errorMsg = this.shadowRoot?.querySelector('.invalid-feedback');
98
+ const paginationWrapper = this.shadowRoot?.querySelector('#paginationWrapper');
99
+ const minChars = this.hasAttribute('data-min-chars') ? parseInt(this.getAttribute('data-min-chars')) : 3;
100
+ let pageNumber = 1;
101
+ const atleastone = this.querySelector('.atleastone');
75
102
 
76
103
  Array.from(this.shadowRoot.querySelectorAll('.title')).forEach((titleElement) => {
77
104
  titleElement.innerHTML = title;
78
105
  });
79
106
 
107
+ // #region functions
80
108
  function checkFilled(component): void {
109
+
81
110
  const preFilledAddress = component.shadowRoot.querySelector('.pre-filled-address');
82
111
  let preFilled = true;
83
112
  preFilledAddress.innerHTML = '';
84
113
 
114
+
85
115
  Array.from(
86
116
  component.querySelectorAll('input[required],input[data-required],select[required],select[data-required]')
87
117
  ).forEach((input) => {
88
- const value = input.value;
118
+ let value = input.hasAttribute('data-value') ? input.getAttribute('data-value') : input.value;
119
+
120
+ if(input.tagName == "SELECT" && component.querySelector(`[value="${input.value}"][data-value]`))
121
+ value = component.querySelector(`[value="${input.value}"][data-value]`).getAttribute('data-value');
122
+
123
+ if (!value){
89
124
 
90
- if (!value) preFilled = false;
91
- else preFilledAddress.innerHTML += value + (/^-?\d+$/.test(value) ? ' ' : ', ');
125
+ if(input.closest('.atleastone')){
126
+
127
+ if(!atleastone.querySelector('input:valid, input.is-valid')){
128
+ preFilled = false;
129
+ }
130
+ }
131
+ else {
132
+ preFilled = false;
133
+ }
134
+
135
+ }
136
+ else {
137
+ preFilledAddress.innerHTML += value + (/^-?\d+$/.test(value) ? ' ' : ', ');
138
+ }
92
139
  });
93
140
 
94
141
  preFilledAddress.innerHTML = preFilledAddress.innerHTML.slice(0, -2);
@@ -99,116 +146,135 @@ class iamAddressLookup extends HTMLElement {
99
146
  manualWrapper.classList.add('js-hide');
100
147
  }
101
148
  }
102
- checkFilled(this);
103
149
 
104
- this.addEventListener('filled', () => {
105
- checkFilled(this);
106
- });
150
+ function openManualWrapper(): void {
107
151
 
108
- if (this.hasAttribute('data-use')) {
109
- const useLabel = this.hasAttribute('data-use-label') ? this.getAttribute('data-use-label') : 'Use saved address';
110
- const useCheckbox = `<div><input type="checkbox" name="use" id="use" value="yes"><label for="use">${useLabel}</label></div>`;
152
+
153
+ lookupWrapper.classList.add('js-hide');
154
+ manualWrapper.classList.remove('js-hide');
111
155
 
112
- lookupWrapper.insertAdjacentHTML('afterbegin', useCheckbox);
156
+ Array.from(manualWrapper.querySelectorAll('[data-required]')).forEach((input) => {
113
157
 
114
- this.shadowRoot.addEventListener('change', (event) => {
115
- if (event && event.target instanceof HTMLElement && event.target.closest('[name="use"]')) {
116
- const checkbox = event.target.closest('[name="use"]');
158
+ input.setAttribute('required', 'true');
159
+ });
117
160
 
118
- if (checkbox.checked) {
119
- lookupWrapper.classList.add('js-hide');
120
- manualWrapper.classList.remove('js-hide');
161
+ manualWrapper.scrollIntoView();
162
+ }
121
163
 
122
- const values = JSON.parse(this.getAttribute('data-use'));
164
+ const atleastoneValidate = (): void => {
123
165
 
124
- Object.keys(values).forEach((key) => {
125
- const value = values[key];
126
- if (this.querySelector(`[data-name="${key}"]`)) this.querySelector(`[data-name="${key}"]`).value = value;
127
- else if (this.querySelector(`[name="${key}"]`)) this.querySelector(`[name="${key}"]`).value = value;
128
- });
129
- }
130
- }
131
- });
166
+ if(atleastone.querySelector('input:valid, input.is-valid')){
167
+ Array.from(atleastone.querySelectorAll('input')).forEach(element => {
168
+ element.removeAttribute('required');
169
+ });
170
+ }
171
+ else {
172
+ Array.from(atleastone.querySelectorAll('input')).forEach((input) => {
173
+ input.setAttribute('required', 'true');
174
+ });
175
+ }
132
176
  }
133
177
 
134
- if (this.hasAttribute('data-manual')) {
135
- lookupWrapper.classList.add('js-hide');
136
- manualWrapper.classList.remove('js-hide');
137
178
 
138
- Array.from(manualWrapper.querySelectorAll('[data-required]')).forEach((input) => {
139
- input.setAttribute('required', 'true');
140
- });
141
- }
179
+ const fillInputs = (values): void => {
142
180
 
143
- function openManualWrapper(): void {
144
181
  lookupWrapper.classList.add('js-hide');
145
182
  manualWrapper.classList.remove('js-hide');
146
183
 
147
- Array.from(manualWrapper.querySelectorAll('[data-required]')).forEach((input) => {
148
- input.setAttribute('required', 'true');
184
+ Object.keys(values).forEach((key) => {
185
+ const value = values[key];
186
+ let input = false;
187
+ if (this.querySelector(`[data-name="${key}"]`))
188
+ input = this.querySelector(`[data-name="${key}"]`);
189
+ else if (this.querySelector(`[data-name-alt="${key}"]`))
190
+ input = this.querySelector(`[data-name-alt="${key}"]`);
191
+ else if (this.querySelector(`[name="${key}"]`))
192
+ input = this.querySelector(`[name="${key}"]`);
193
+
194
+ if(input && input.tagName == "SELECT" && value.id){
195
+ input.value = value.id;
196
+
197
+ }
198
+ else if(input && value != ''){
199
+
200
+ input.value = value;
201
+
202
+ if(input.hasAttribute('data-readonly')){
203
+ input.setAttribute('readonly', true);
204
+ input.classList.add('is-valid');
205
+ }
206
+ }
207
+ else if(value != ""){
208
+ this.insertAdjacentHTML('beforeend',`<input type="hidden" class="inserted" data-hidden name="${key}" value="${value}" />`);
209
+ }
210
+
211
+ if (this.querySelector(`[data-name-2="${key}"]`))
212
+ this.querySelector(`[data-name-2="${key}"]`).value += ' ' + value;
149
213
  });
150
214
 
151
- manualWrapper.scrollIntoView();
152
- }
215
+ Array.from(this.querySelectorAll('[data-required]')).forEach((input) => {
216
+ input.setAttribute('required', 'true');
217
+ });
218
+ lookup.removeAttribute('required');
153
219
 
154
- preFilledAddressBtn.addEventListener('click', () => {
155
- preFilledWrapper.classList.add('js-hide');
156
- openManualWrapper();
157
- });
158
- switchManualBtn.addEventListener('click', () => {
159
- openManualWrapper();
160
- });
161
- switchLookupBtn.addEventListener('click', () => {
162
- lookupWrapper.classList.remove('js-hide');
163
- manualWrapper.classList.add('js-hide');
220
+ if(atleastone){
164
221
 
165
- lookupWrapper.scrollIntoView();
166
- });
222
+ atleastoneValidate();
223
+ }
167
224
 
168
- lookup.addEventListener('keyup', () => {
169
- if (lookup.value.length >= 3) search(lookup.value);
170
- });
225
+ if(!this.hasAttribute('data-force-manual'))
226
+ checkFilled(this);
227
+ }
171
228
 
172
- lookup.addEventListener('change', () => {
173
- if (lookup.value.length >= 3) {
174
- search(lookup.value);
229
+ const search = async (searchValue, paginate = false): any => {
175
230
 
176
- if (list.querySelector(`[value="${lookup.value}"]`)) {
177
- lookupWrapper.classList.add('js-hide');
178
- manualWrapper.classList.remove('js-hide');
231
+ // check if postcode is valid
232
+ const limit = this.hasAttribute('data-limit') ? parseInt(this.getAttribute('data-limit')) : 100;
233
+
234
+ if(paginate)
235
+ pageNumber++;
236
+ else
237
+ pageNumber = 1;
179
238
 
180
- const values = JSON.parse(list.querySelector(`[value="${lookup.value}"]`).getAttribute('data-values'));
239
+ let ajaxURL = this.getAttribute('data-url');
240
+ ajaxURL += `${encodeURI(searchValue)}&page[number]=${pageNumber}&page[size]=${limit}`;
241
+
242
+ if(this.hasAttribute('data-url-2')){
243
+ ajaxURL += this.getAttribute('data-url-2');
244
+ }
181
245
 
182
- Object.keys(values).forEach((key) => {
183
- const value = values[key];
184
- if (this.querySelector(`[data-name="${key}"]`) && value != '')
185
- this.querySelector(`[data-name="${key}"]`).value = value;
186
- else if (this.querySelector(`[data-name-alt="${key}"]`) && value != '')
187
- this.querySelector(`[data-name-alt="${key}"]`).value = value;
188
- else if (this.querySelector(`[name="${key}"]`) && value != '')
189
- this.querySelector(`[name="${key}"]`).value = value;
246
+ const postcode = searchValue; // TODO: remove when postcode comes from response
190
247
 
191
- if (this.querySelector(`[data-name-2="${key}"]`))
192
- this.querySelector(`[data-name-2="${key}"]`).value += ' ' + value;
193
- });
248
+ if(this.hasAttribute('data-postcode')){
249
+ const regexp = /^([A-Z][A-HJ-Y]?[0-9][A-Z0-9]? ?[0-9][A-Z]{2}|GIR ?0A{2})$/gmi;
194
250
 
195
- // Focus on first input
196
- this.querySelector('[name]').focus();
251
+ if (!regexp.test(searchValue)){
252
+ return "Invalid postcode, please enter a valid postcode";
253
+ }
254
+ else {
255
+ if(!paginate)
256
+ list.innerHTML = "";
257
+ list?.classList.add('loading');
258
+ list?.classList.remove('noresults');
259
+ lookup?.classList.remove('is-invalid');
260
+ errorMsg?.innerHTML = "";
261
+ list?.classList.remove('show-welsh-banner');
197
262
 
198
263
  Array.from(this.querySelectorAll('[data-required]')).forEach((input) => {
199
- input.setAttribute('required', 'true');
264
+ input.removeAttribute('required');
265
+ });
266
+ Array.from(this.querySelectorAll('[data-readonly]')).forEach((input) => {
267
+ input.removeAttribute('readonly');
268
+ input.classList.remove('is-valid');
269
+ });
270
+ Array.from(this.querySelectorAll('.inserted')).forEach((input) => {
271
+ input.remove();
200
272
  });
201
- lookup.removeAttribute('required');
202
-
203
- if (this.shadowRoot.querySelector('[name="use"]'))
204
- this.shadowRoot.querySelector('[name="use"]').checked = false;
205
273
  }
206
274
  }
207
- });
208
275
 
209
- const search = async (postcode): any => {
210
- let ajaxURL = this.getAttribute('data-url');
211
- ajaxURL += `${encodeURI(postcode)}`;
276
+ this.classList.add('searched');
277
+ this.classList.add('was-validated');
212
278
 
213
279
  // Setup controller vars if not already set
214
280
  if (!window.controller) window.controller = [];
@@ -221,7 +287,7 @@ class iamAddressLookup extends HTMLElement {
221
287
  const { signal } = controller[ajaxURL];
222
288
 
223
289
  try {
224
- await fetch(ajaxURL, {
290
+ return await fetch(ajaxURL, {
225
291
  signal: signal,
226
292
  method: 'get',
227
293
  credentials: 'same-origin',
@@ -236,36 +302,283 @@ class iamAddressLookup extends HTMLElement {
236
302
  .then((response) => {
237
303
  // populate datalist
238
304
  let listString = '';
239
- response.forEach((address) => {
305
+
306
+ const addresses = response['data'] ? response['data'] : response;
307
+
308
+ addresses.forEach((address) => {
309
+
240
310
  // Deal with agent platform response
241
- if (typeof address.value == 'object') {
311
+ if (typeof address.attributes == 'object' && address.attributes.label) {
312
+ const values = JSON.stringify(address.attributes);
313
+ listString += `<option data-values='${values}' >${address.attributes.label}</option>`;
314
+ }
315
+ else if (typeof address.value == 'object') {
242
316
  const values = JSON.stringify(address.value);
243
- listString += `<option value="${address['label']}, ${postcode}" data-values='${values}'></option>`;
317
+ listString += `<option data-values='${values}'>${address['label']}, ${postcode}</option>`;
244
318
  } else {
245
319
  const values = JSON.stringify(address);
246
320
 
247
321
  if (dataDisplayText) {
248
- listString += `<option value="${address[dataDisplayText]}, ${postcode}" data-values='${values}'></option>`;
322
+ listString += `<option data-values='${values}'>${address[dataDisplayText]}, ${postcode}</option>`;
249
323
  } else {
250
324
  let itemString = '';
251
325
  for (const [key, value] of Object.entries(address)) {
252
326
  if (key == 'address_number_name') itemString += `${value} `;
253
- else if (key != 'postcode' && key != 'address_title')
327
+ else if (key != 'postcode' && key != 'address_title' && key != 'group')
254
328
  itemString += `${value}${/^-?\d+$/.test(value) ? '' : ','} `;
255
329
  }
256
330
 
257
- listString += `<option value="${itemString}${postcode}" data-values='${values}'></option>`;
331
+ listString += `<option data-values='${values}'>${itemString}, ${postcode}</option>`; // TODO postcode should come from the response
258
332
  }
259
333
  }
334
+
335
+
260
336
  });
261
- list.innerHTML = listString;
262
337
 
263
- return response;
338
+ if(paginate)
339
+ list.innerHTML += listString;
340
+ else
341
+ list.innerHTML = listString;
342
+
343
+ if(addresses.length){
344
+ list?.classList.remove('loading');
345
+
346
+ }
347
+ else {
348
+
349
+ list?.classList.remove('loading');
350
+ list?.classList.add('noresults');
351
+ }
352
+
353
+ // pagination
354
+ if(response.meta && response.meta.current_page && response.meta.total_pages && response.meta.total_pages > response.meta.current_page){
355
+
356
+ paginationWrapper?.innerHTML = `<div class="bg-light text-center p-2"><p class="m-0">Showing 1-${response.meta.current_page * limit} of ${response.meta.total_results} addresses <br /><button type="button" data-next="${response.meta.current_page+1}" class="mt-1 mb-0 btn btn-action"><i class="fa-regular fa-eye me-1"></i>Show more addresses</button></p></div>`;
357
+ }
358
+ else {
359
+ paginationWrapper?.innerHTML = '';
360
+ }
361
+
362
+ if(response.meta && response.meta.welsh_language){
363
+
364
+ list?.classList.add('show-welsh-banner');
365
+ }
366
+ listWrapper?.focus();
367
+ list?.querySelector('option')?.focus();
368
+
369
+ return true;
264
370
  });
265
371
  } catch (error) {
266
- console.log(error);
372
+ console.log(error)
373
+ return "There has been a problem. Please try again in a few moments.";
267
374
  }
268
375
  };
376
+
377
+ // #endregion
378
+
379
+ // #region check attributes and trigger functions
380
+ if(!this.hasAttribute('data-force-manual'))
381
+ checkFilled(this);
382
+
383
+ this.addEventListener('filled', () => {
384
+ if(!this.hasAttribute('data-force-manual'))
385
+ checkFilled(this);
386
+ });
387
+
388
+ if (this.hasAttribute('data-use')) {
389
+ const useLabel = this.hasAttribute('data-use-label') ? this.getAttribute('data-use-label') : 'Use saved address';
390
+ const useCheckbox = `<div><input type="checkbox" name="use" id="use" value="yes"><label for="use">${useLabel}</label></div>`;
391
+
392
+ lookupWrapper.insertAdjacentHTML('afterbegin', useCheckbox);
393
+
394
+ this.shadowRoot.addEventListener('change', (event) => {
395
+ if (event && event.target instanceof HTMLElement && event.target.closest('[name="use"]')) {
396
+ const checkbox = event.target.closest('[name="use"]');
397
+
398
+ if (checkbox.checked) {
399
+ lookupWrapper.classList.add('js-hide');
400
+ manualWrapper.classList.remove('js-hide');
401
+
402
+ const values = JSON.parse(this.getAttribute('data-use'));
403
+
404
+ Object.keys(values).forEach((key) => {
405
+ const value = values[key];
406
+ if (this.querySelector(`[data-name="${key}"]`)) this.querySelector(`[data-name="${key}"]`).value = value;
407
+ else if (this.querySelector(`[name="${key}"]`)) this.querySelector(`[name="${key}"]`).value = value;
408
+ });
409
+ }
410
+ }
411
+ });
412
+
413
+
414
+ if(this.hasAttribute('data-use-default')){
415
+ lookupWrapper.querySelector('[name="use"]').checked = true;
416
+
417
+ const values = JSON.parse(this.getAttribute('data-use'));
418
+ fillInputs(values);
419
+ }
420
+ }
421
+
422
+ if (this.hasAttribute('data-manual')) {
423
+ fillInputs({});
424
+ }
425
+
426
+ if(this.classList.contains('show-pagination'))
427
+ paginationWrapper?.innerHTML = `<div class="bg-light text-center p-2"><p class="m-0">Showing 1-500 of 585 addresses <br /><button type="button" data-next="2" class="mt-1 mb-0 btn btn-action"><i class="fa-regular fa-eye me-1"></i>Show more addresses</button></p></div>`;
428
+
429
+ if(this.classList.contains('scroll-to-bottom-results'))
430
+ paginationWrapper.scrollIntoView({container: 'nearest'});
431
+ // #endregion
432
+
433
+ // #region event listeners
434
+ preFilledAddressBtn.addEventListener('click', () => {
435
+ preFilledWrapper.classList.add('js-hide');
436
+ openManualWrapper();
437
+ });
438
+
439
+ preFilledAddressRemoveBtn.addEventListener('click', () => {
440
+ preFilledWrapper.classList.add('js-hide');
441
+ lookupWrapper.classList.remove('js-hide');
442
+ manualWrapper.classList.add('js-hide');
443
+
444
+ list.innerHTML = "";
445
+ list?.classList.remove('loading');
446
+ list?.classList.remove('noresults');
447
+ lookup?.classList.remove('is-invalid');
448
+ errorMsg?.innerHTML = "";
449
+ list?.classList.remove('show-welsh-banner');
450
+
451
+ lookup.focus();
452
+ lookup.value = "";
453
+
454
+ if(lookup?.hasAttribute('data-placeholder'))
455
+ lookup.setAttribute('placeholder',lookup?.getAttribute('data-placeholder'));
456
+
457
+ const updateEvent = new CustomEvent('switch-to-lookup');
458
+ this.dispatchEvent(updateEvent);
459
+
460
+ lookupWrapper.scrollIntoView();
461
+ });
462
+
463
+ switchManualBtn.addEventListener('click', () => {
464
+ openManualWrapper();
465
+ });
466
+
467
+ this.addEventListener('open-manual', () => {
468
+ openManualWrapper();
469
+ });
470
+
471
+ switchLookupBtn.addEventListener('click', () => {
472
+ lookupWrapper.classList.remove('js-hide');
473
+ manualWrapper.classList.add('js-hide');
474
+
475
+ const updateEvent = new CustomEvent('switch-to-lookup');
476
+ this.dispatchEvent(updateEvent);
477
+
478
+ lookupWrapper.scrollIntoView();
479
+ });
480
+
481
+ lookup.addEventListener('keyup', async (e) => {
482
+
483
+ if (![40,38,13].includes(e.keyCode) && lookup.value.length >= minChars){
484
+ const valid = await search(lookup.value);
485
+
486
+ if(valid != true){
487
+ lookup?.classList.add('is-invalid');
488
+ errorMsg?.innerHTML = valid;
489
+ }
490
+ }
491
+
492
+ if (e.keyCode == 13){
493
+ const valid = await search(lookup.value);
494
+
495
+ if(valid != true){
496
+ lookup?.classList.add('is-invalid');
497
+ errorMsg?.innerHTML = valid;
498
+ }
499
+ }
500
+ });
501
+
502
+ lookup.addEventListener('change', async () => {
503
+
504
+ if (lookup.value.length >= minChars) {
505
+
506
+ const valid = await search(lookup.value);
507
+
508
+ if(valid != true){
509
+ lookup?.classList.add('is-invalid');
510
+ errorMsg?.innerHTML = valid;
511
+ }
512
+ }
513
+ });
514
+
515
+ list.addEventListener('click', (e) => {
516
+ if(e.target.tagName == "OPTION"){
517
+
518
+ const values = JSON.parse(e.target.getAttribute('data-values'));
519
+
520
+ fillInputs(values);
521
+
522
+ if (this.shadowRoot.querySelector('[name="use"]'))
523
+ this.shadowRoot.querySelector('[name="use"]').checked = false;
524
+ }
525
+ });
526
+
527
+ atleastone?.addEventListener('input', (e) => {
528
+
529
+ Array.from(atleastone.querySelectorAll('[data-required]')).forEach((input) => {
530
+ input.setAttribute('required', 'true');
531
+ });
532
+
533
+
534
+ atleastoneValidate();
535
+ });
536
+
537
+ postcodeSubmit?.addEventListener('click', async () => {
538
+ const valid = await search(lookup.value);
539
+
540
+ if(valid != true){
541
+ lookup?.classList.add('is-invalid');
542
+ errorMsg?.innerHTML = valid;
543
+ }
544
+ });
545
+
546
+ this?.addEventListener('search', async () => {
547
+ const valid = await search(lookup.value);
548
+
549
+ if(valid != true){
550
+ lookup?.classList.add('is-invalid');
551
+ errorMsg?.innerHTML = valid;
552
+ }
553
+ });
554
+
555
+ this?.addEventListener('close-button-pressed', () => {
556
+
557
+ list.innerHTML = "";
558
+ list?.classList.remove('loading');
559
+ list?.classList.remove('noresults');
560
+ lookup?.classList.remove('is-invalid');
561
+ errorMsg?.innerHTML = "";
562
+ list?.classList.remove('show-welsh-banner');
563
+
564
+ lookup.focus();
565
+ });
566
+
567
+ paginationWrapper?.addEventListener('click', async (e) => {
568
+
569
+ if(e.target.tagName == "BUTTON"){
570
+
571
+ const valid = await search(lookup.value, true);
572
+
573
+ if(valid != true){
574
+ lookup?.classList.add('is-invalid');
575
+ errorMsg?.innerHTML = valid;
576
+ }
577
+ }
578
+ });
579
+ // #endregion
580
+
581
+ advancedSelect(this, lookup, list, true);
269
582
  }
270
583
  }
271
584
 
@@ -71,4 +71,5 @@ class iamAdvancedSelect extends HTMLElement {
71
71
  }
72
72
  }
73
73
 
74
+
74
75
  export default iamAdvancedSelect;