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

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