@bcrs-shared-components/base-address 3.0.2 → 3.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BaseAddress.stories.ts +52 -53
- package/BaseAddress.vue +381 -381
- package/LICENSE +201 -201
- package/factories/address-factory.ts +216 -216
- package/factories/countries-provinces-factory.ts +78 -78
- package/factories/index.ts +3 -3
- package/factories/validation-factory.ts +42 -42
- package/index.ts +1 -1
- package/package.json +5 -12
- package/resources/default-schema.ts +42 -42
- package/resources/index.ts +1 -1
- package/factories/vuelidate-validation-factory.ts +0 -118
package/BaseAddress.vue
CHANGED
|
@@ -1,381 +1,381 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="base-address">
|
|
3
|
-
<!-- Display fields -->
|
|
4
|
-
<v-expand-transition>
|
|
5
|
-
<div
|
|
6
|
-
v-if="!editing"
|
|
7
|
-
class="address-block"
|
|
8
|
-
>
|
|
9
|
-
<div class="address-block__info pre-wrap">
|
|
10
|
-
<p class="address-block__info-row">
|
|
11
|
-
{{ addressLocal.streetAddress }}
|
|
12
|
-
</p>
|
|
13
|
-
<p
|
|
14
|
-
v-if="addressLocal.streetAddressAdditional"
|
|
15
|
-
class="address-block__info-row"
|
|
16
|
-
>
|
|
17
|
-
{{ addressLocal.streetAddressAdditional }}
|
|
18
|
-
</p>
|
|
19
|
-
<p class="address-block__info-row">
|
|
20
|
-
<span>{{ addressLocal.addressCity }}</span>
|
|
21
|
-
<span v-if="addressLocal.addressRegion"> {{ addressLocal.addressRegion }} </span>
|
|
22
|
-
<span v-if="addressLocal.postalCode"> {{ addressLocal.postalCode }}</span>
|
|
23
|
-
</p>
|
|
24
|
-
<p class="address-block__info-row">
|
|
25
|
-
{{ getCountryName(country) }}
|
|
26
|
-
</p>
|
|
27
|
-
<p
|
|
28
|
-
v-if="addressLocal.deliveryInstructions"
|
|
29
|
-
class="address-block__info-row delivery-text"
|
|
30
|
-
>
|
|
31
|
-
{{ addressLocal.deliveryInstructions }}
|
|
32
|
-
</p>
|
|
33
|
-
</div>
|
|
34
|
-
</div>
|
|
35
|
-
</v-expand-transition>
|
|
36
|
-
|
|
37
|
-
<!-- Edit fields -->
|
|
38
|
-
<v-expand-transition>
|
|
39
|
-
<v-form
|
|
40
|
-
v-if="editing"
|
|
41
|
-
ref="addressForm"
|
|
42
|
-
name="address-form"
|
|
43
|
-
lazy-validation
|
|
44
|
-
>
|
|
45
|
-
<div class="form__row">
|
|
46
|
-
<v-autocomplete
|
|
47
|
-
v-model="addressLocal.addressCountry"
|
|
48
|
-
autocomplete="new-password"
|
|
49
|
-
:name="Math.random().toString()"
|
|
50
|
-
variant="filled"
|
|
51
|
-
class="address-country"
|
|
52
|
-
hide-no-data
|
|
53
|
-
item-title="name"
|
|
54
|
-
item-value="code"
|
|
55
|
-
:items="getCountries()"
|
|
56
|
-
:label="countryLabel"
|
|
57
|
-
:rules="[...schemaLocal.country]"
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
<!--
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
:
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
v-model="addressLocal.
|
|
142
|
-
variant="filled"
|
|
143
|
-
class="item
|
|
144
|
-
:label="
|
|
145
|
-
:name="Math.random().toString()"
|
|
146
|
-
:rules="[...schemaLocal.
|
|
147
|
-
/>
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
} from '
|
|
180
|
-
import {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
})
|
|
317
|
-
</script>
|
|
318
|
-
|
|
319
|
-
<style lang="scss" scoped>
|
|
320
|
-
@import '@/assets/styles/theme.scss';
|
|
321
|
-
|
|
322
|
-
.delivery-text {
|
|
323
|
-
font-style: italic;
|
|
324
|
-
margin-top: 10px;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
// Address Block Layout
|
|
328
|
-
.address-block {
|
|
329
|
-
display: flex;
|
|
330
|
-
p {
|
|
331
|
-
margin-bottom: unset;
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
.address-block__info {
|
|
336
|
-
flex: 1 1 auto;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
// Form Row Elements
|
|
340
|
-
.form__row.three-column {
|
|
341
|
-
align-items: stretch;
|
|
342
|
-
display: flex;
|
|
343
|
-
flex-flow: row nowrap;
|
|
344
|
-
margin-left: -0.5rem;
|
|
345
|
-
margin-right: -0.5rem;
|
|
346
|
-
|
|
347
|
-
.item {
|
|
348
|
-
flex: 1 1 auto;
|
|
349
|
-
flex-basis: 0;
|
|
350
|
-
margin-left: 0.5rem;
|
|
351
|
-
margin-right: 0.5rem;
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
.pre-wrap {
|
|
356
|
-
white-space: pre-wrap;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
// make 'readonly' inputs looks disabled
|
|
360
|
-
// (can't use 'disabled' because we want normal error styling)
|
|
361
|
-
.v-select.v-input--is-readonly,
|
|
362
|
-
.v-text-field.v-input--is-readonly {
|
|
363
|
-
pointer-events: none;
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
// set label colour to same as disabled
|
|
367
|
-
color: rgba(0,0,0,.38);
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
// set selection colour to same as disabled
|
|
372
|
-
color: rgba(0,0,0,.38);
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
// set error icon colour to same as disabled
|
|
377
|
-
color: rgba(0,0,0,.38) !important;
|
|
378
|
-
opacity: 0.6;
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
</style>
|
|
1
|
+
<template>
|
|
2
|
+
<div class="base-address">
|
|
3
|
+
<!-- Display fields -->
|
|
4
|
+
<v-expand-transition>
|
|
5
|
+
<div
|
|
6
|
+
v-if="!editing"
|
|
7
|
+
class="address-block"
|
|
8
|
+
>
|
|
9
|
+
<div class="address-block__info pre-wrap">
|
|
10
|
+
<p class="address-block__info-row">
|
|
11
|
+
{{ addressLocal.streetAddress }}
|
|
12
|
+
</p>
|
|
13
|
+
<p
|
|
14
|
+
v-if="addressLocal.streetAddressAdditional"
|
|
15
|
+
class="address-block__info-row"
|
|
16
|
+
>
|
|
17
|
+
{{ addressLocal.streetAddressAdditional }}
|
|
18
|
+
</p>
|
|
19
|
+
<p class="address-block__info-row">
|
|
20
|
+
<span>{{ addressLocal.addressCity }}</span>
|
|
21
|
+
<span v-if="addressLocal.addressRegion"> {{ addressLocal.addressRegion }} </span>
|
|
22
|
+
<span v-if="addressLocal.postalCode"> {{ addressLocal.postalCode }}</span>
|
|
23
|
+
</p>
|
|
24
|
+
<p class="address-block__info-row">
|
|
25
|
+
{{ getCountryName(country) }}
|
|
26
|
+
</p>
|
|
27
|
+
<p
|
|
28
|
+
v-if="addressLocal.deliveryInstructions"
|
|
29
|
+
class="address-block__info-row delivery-text"
|
|
30
|
+
>
|
|
31
|
+
{{ addressLocal.deliveryInstructions }}
|
|
32
|
+
</p>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
</v-expand-transition>
|
|
36
|
+
|
|
37
|
+
<!-- Edit fields -->
|
|
38
|
+
<v-expand-transition>
|
|
39
|
+
<v-form
|
|
40
|
+
v-if="editing"
|
|
41
|
+
ref="addressForm"
|
|
42
|
+
name="address-form"
|
|
43
|
+
lazy-validation
|
|
44
|
+
>
|
|
45
|
+
<div class="form__row">
|
|
46
|
+
<v-autocomplete
|
|
47
|
+
v-model="addressLocal.addressCountry"
|
|
48
|
+
autocomplete="new-password"
|
|
49
|
+
:name="Math.random().toString()"
|
|
50
|
+
variant="filled"
|
|
51
|
+
class="address-country"
|
|
52
|
+
hide-no-data
|
|
53
|
+
item-title="name"
|
|
54
|
+
item-value="code"
|
|
55
|
+
:items="getCountries()"
|
|
56
|
+
:label="countryLabel"
|
|
57
|
+
:rules="[...schemaLocal.country]"
|
|
58
|
+
>
|
|
59
|
+
<template #item="{item, props: autoCompleteProps}">
|
|
60
|
+
<v-divider v-if="item.raw.divider" />
|
|
61
|
+
<v-list-item
|
|
62
|
+
v-else
|
|
63
|
+
v-bind="autoCompleteProps"
|
|
64
|
+
/>
|
|
65
|
+
</template>
|
|
66
|
+
</v-autocomplete>
|
|
67
|
+
<!-- special field to select AddressComplete country, separate from our model field -->
|
|
68
|
+
<input
|
|
69
|
+
:id="countryId"
|
|
70
|
+
type="hidden"
|
|
71
|
+
:value="country"
|
|
72
|
+
>
|
|
73
|
+
</div>
|
|
74
|
+
<div class="form__row">
|
|
75
|
+
<!-- NB1: AddressComplete needs to be enabled each time user clicks in this search field.
|
|
76
|
+
NB2: Only process first keypress -- assumes if user moves between instances of this
|
|
77
|
+
component then they are using the mouse (and thus, clicking). -->
|
|
78
|
+
<v-text-field
|
|
79
|
+
:id="streetId"
|
|
80
|
+
v-model="addressLocal.streetAddress"
|
|
81
|
+
autocomplete="new-password"
|
|
82
|
+
class="street-address"
|
|
83
|
+
variant="filled"
|
|
84
|
+
:hint="hideAddressHint ? '' : 'Street address, PO box, rural route, or general delivery address'"
|
|
85
|
+
:label="streetLabel"
|
|
86
|
+
:name="Math.random().toString()"
|
|
87
|
+
persistent-hint
|
|
88
|
+
:rules="[...schemaLocal.street]"
|
|
89
|
+
@keypress.once="enableAddressComplete()"
|
|
90
|
+
@click="enableAddressComplete()"
|
|
91
|
+
/>
|
|
92
|
+
</div>
|
|
93
|
+
<div class="form__row">
|
|
94
|
+
<v-textarea
|
|
95
|
+
v-model="addressLocal.streetAddressAdditional"
|
|
96
|
+
autocomplete="new-password"
|
|
97
|
+
auto-grow
|
|
98
|
+
variant="filled"
|
|
99
|
+
class="street-address-additional"
|
|
100
|
+
:label="streetAdditionalLabel"
|
|
101
|
+
:name="Math.random().toString()"
|
|
102
|
+
rows="1"
|
|
103
|
+
:rules="!!addressLocal.streetAddressAdditional ? [...schemaLocal.streetAdditional] : []"
|
|
104
|
+
/>
|
|
105
|
+
</div>
|
|
106
|
+
<div class="form__row three-column">
|
|
107
|
+
<v-text-field
|
|
108
|
+
v-model="addressLocal.addressCity"
|
|
109
|
+
autocomplete="new-password"
|
|
110
|
+
variant="filled"
|
|
111
|
+
class="item address-city"
|
|
112
|
+
:label="cityLabel"
|
|
113
|
+
:name="Math.random().toString()"
|
|
114
|
+
:rules="[...schemaLocal.city]"
|
|
115
|
+
/>
|
|
116
|
+
<v-autocomplete
|
|
117
|
+
v-if="useCountryRegions(country)"
|
|
118
|
+
v-model="addressLocal.addressRegion"
|
|
119
|
+
autocomplete="new-password"
|
|
120
|
+
variant="filled"
|
|
121
|
+
class="item address-region"
|
|
122
|
+
hide-no-data
|
|
123
|
+
item-title="name"
|
|
124
|
+
item-value="short"
|
|
125
|
+
:items="getCountryRegions(country)"
|
|
126
|
+
:label="regionLabel"
|
|
127
|
+
:menu-props="{ maxHeight: '14rem' }"
|
|
128
|
+
:name="Math.random().toString()"
|
|
129
|
+
:rules="[...schemaLocal.region]"
|
|
130
|
+
>
|
|
131
|
+
<template #item="{item, props: autoCompleteProps}">
|
|
132
|
+
<v-divider v-if="item.raw.divider" />
|
|
133
|
+
<v-list-item
|
|
134
|
+
v-else
|
|
135
|
+
v-bind="autoCompleteProps"
|
|
136
|
+
/>
|
|
137
|
+
</template>
|
|
138
|
+
</v-autocomplete>
|
|
139
|
+
<v-text-field
|
|
140
|
+
v-else
|
|
141
|
+
v-model="addressLocal.addressRegion"
|
|
142
|
+
variant="filled"
|
|
143
|
+
class="item address-region"
|
|
144
|
+
:label="regionLabel"
|
|
145
|
+
:name="Math.random().toString()"
|
|
146
|
+
:rules="[...schemaLocal.region]"
|
|
147
|
+
/>
|
|
148
|
+
<v-text-field
|
|
149
|
+
v-model="addressLocal.postalCode"
|
|
150
|
+
variant="filled"
|
|
151
|
+
class="item postal-code"
|
|
152
|
+
:label="postalCodeLabel"
|
|
153
|
+
:name="Math.random().toString()"
|
|
154
|
+
:rules="[...schemaLocal.postalCode]"
|
|
155
|
+
/>
|
|
156
|
+
</div>
|
|
157
|
+
<div
|
|
158
|
+
v-if="!hideDeliveryAddress"
|
|
159
|
+
class="form__row"
|
|
160
|
+
>
|
|
161
|
+
<v-textarea
|
|
162
|
+
v-model="addressLocal.deliveryInstructions"
|
|
163
|
+
auto-grow
|
|
164
|
+
variant="filled"
|
|
165
|
+
class="delivery-instructions"
|
|
166
|
+
:label="deliveryInstructionsLabel"
|
|
167
|
+
:name="Math.random().toString()"
|
|
168
|
+
rows="2"
|
|
169
|
+
:rules="!!addressLocal.deliveryInstructions ? [...schemaLocal.deliveryInstructions] : []"
|
|
170
|
+
/>
|
|
171
|
+
</div>
|
|
172
|
+
</v-form>
|
|
173
|
+
</v-expand-transition>
|
|
174
|
+
</div>
|
|
175
|
+
</template>
|
|
176
|
+
|
|
177
|
+
<script setup lang="ts">
|
|
178
|
+
import { AddressIF, SchemaIF } from '@bcrs-shared-components/interfaces'
|
|
179
|
+
import { Ref, onMounted, toRef, watch } from 'vue'
|
|
180
|
+
import {
|
|
181
|
+
baseRules,
|
|
182
|
+
spaceRules,
|
|
183
|
+
useAddress,
|
|
184
|
+
useAddressComplete,
|
|
185
|
+
useBaseValidations,
|
|
186
|
+
useCountriesProvinces,
|
|
187
|
+
useCountryRegions
|
|
188
|
+
} from '@bcrs-shared-components/base-address/factories'
|
|
189
|
+
import { AddressValidationRules } from '@bcrs-shared-components/enums'
|
|
190
|
+
|
|
191
|
+
const props = withDefaults(defineProps<{
|
|
192
|
+
value: AddressIF
|
|
193
|
+
editing: boolean
|
|
194
|
+
schema: SchemaIF
|
|
195
|
+
triggerErrors: boolean
|
|
196
|
+
hideAddressHint: boolean
|
|
197
|
+
hideDeliveryAddress: boolean
|
|
198
|
+
}>(), {
|
|
199
|
+
value: () => ({
|
|
200
|
+
streetAddress: '',
|
|
201
|
+
streetAddressAdditional: '',
|
|
202
|
+
addressCity: '',
|
|
203
|
+
addressRegion: '',
|
|
204
|
+
postalCode: '',
|
|
205
|
+
addressCountry: null,
|
|
206
|
+
deliveryInstructions: ''
|
|
207
|
+
}),
|
|
208
|
+
/* used for readonly mode vs edit mode */
|
|
209
|
+
editing: false,
|
|
210
|
+
/* contains validation for each field */
|
|
211
|
+
schema: null,
|
|
212
|
+
/* triggers all current form validation errors */
|
|
213
|
+
triggerErrors: false,
|
|
214
|
+
/* Hides the persistent hint field on Address Input */
|
|
215
|
+
hideAddressHint: false,
|
|
216
|
+
/* Hides Delivery Address field (e.g. for Unit Notes) */
|
|
217
|
+
hideDeliveryAddress: false
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
const emits = defineEmits<{
|
|
221
|
+
'update-address': [address: AddressIF]
|
|
222
|
+
valid: [valid: boolean]
|
|
223
|
+
}>()
|
|
224
|
+
|
|
225
|
+
// eslint-disable-next-line vue/no-setup-props-destructure
|
|
226
|
+
const localSchema = { ...props.schema }
|
|
227
|
+
const {
|
|
228
|
+
addressLocal,
|
|
229
|
+
country,
|
|
230
|
+
schemaLocal,
|
|
231
|
+
labels
|
|
232
|
+
} = useAddress(toRef(props.value) as Ref<AddressIF>, localSchema)
|
|
233
|
+
|
|
234
|
+
const origPostalCodeRules = localSchema.postalCode
|
|
235
|
+
const origRegionRules = localSchema.region
|
|
236
|
+
|
|
237
|
+
const { addressForm, resetValidation, validate } = useBaseValidations()
|
|
238
|
+
|
|
239
|
+
const { enableAddressComplete, uniqueIds } = useAddressComplete(addressLocal)
|
|
240
|
+
|
|
241
|
+
const countryProvincesHelpers = useCountriesProvinces()
|
|
242
|
+
|
|
243
|
+
const countryChangeHandler = (val: string, oldVal: string) => {
|
|
244
|
+
// do not trigger any changes if it is view only (summary instance)
|
|
245
|
+
if (!props.editing) return
|
|
246
|
+
|
|
247
|
+
if (val === 'CA') {
|
|
248
|
+
localSchema.postalCode = origPostalCodeRules.concat([baseRules.postalCode])
|
|
249
|
+
localSchema.region = origRegionRules
|
|
250
|
+
} else if (val === 'US') {
|
|
251
|
+
localSchema.postalCode = origPostalCodeRules.concat([baseRules.zipCode])
|
|
252
|
+
localSchema.region = origRegionRules
|
|
253
|
+
} else {
|
|
254
|
+
localSchema.postalCode = origPostalCodeRules.concat([baseRules[AddressValidationRules.MAX_LENGTH](15)])
|
|
255
|
+
localSchema.region = [baseRules[AddressValidationRules.MAX_LENGTH](2), ...spaceRules]
|
|
256
|
+
}
|
|
257
|
+
// reset other address fields (check is for loading an existing address)
|
|
258
|
+
if (oldVal) {
|
|
259
|
+
addressLocal.value.streetAddress = ''
|
|
260
|
+
addressLocal.value.streetAddressAdditional = ''
|
|
261
|
+
addressLocal.value.addressCity = ''
|
|
262
|
+
addressLocal.value.addressRegion = ''
|
|
263
|
+
addressLocal.value.postalCode = ''
|
|
264
|
+
}
|
|
265
|
+
// wait for schema update and validate the form
|
|
266
|
+
setTimeout(() => {
|
|
267
|
+
props.triggerErrors ? validate() : resetValidation()
|
|
268
|
+
}, 5)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
onMounted(() => {
|
|
272
|
+
countryChangeHandler(addressLocal.value.addressCountry, null)
|
|
273
|
+
})
|
|
274
|
+
|
|
275
|
+
watch(() => addressLocal.value, (val) => {
|
|
276
|
+
let valid = true
|
|
277
|
+
/** checks each field against the schema rules to see if the address is valid or not
|
|
278
|
+
* NOTE: we don't want it to trigger error msgs yet which is why this does not call validate()
|
|
279
|
+
*/
|
|
280
|
+
for (const key in val) {
|
|
281
|
+
for (const index in schemaLocal.value[key]) {
|
|
282
|
+
if (schemaLocal.value[key][index](val[key]) !== true) {
|
|
283
|
+
valid = false
|
|
284
|
+
break
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
if (!valid) break
|
|
288
|
+
}
|
|
289
|
+
emits('valid', valid)
|
|
290
|
+
emits('update-address', val)
|
|
291
|
+
}, { immediate: true, deep: true })
|
|
292
|
+
|
|
293
|
+
watch(() => country.value, (val, oldVal) => {
|
|
294
|
+
countryChangeHandler(val, oldVal)
|
|
295
|
+
})
|
|
296
|
+
|
|
297
|
+
watch(() => props.triggerErrors, () => {
|
|
298
|
+
validate()
|
|
299
|
+
})
|
|
300
|
+
|
|
301
|
+
const { getCountries, getCountryName, getCountryRegions } = countryProvincesHelpers
|
|
302
|
+
const {
|
|
303
|
+
countryLabel,
|
|
304
|
+
streetLabel,
|
|
305
|
+
streetAdditionalLabel,
|
|
306
|
+
cityLabel,
|
|
307
|
+
regionLabel,
|
|
308
|
+
postalCodeLabel,
|
|
309
|
+
deliveryInstructionsLabel
|
|
310
|
+
} = labels
|
|
311
|
+
const { streetId, countryId } = uniqueIds
|
|
312
|
+
|
|
313
|
+
defineExpose({
|
|
314
|
+
addressForm,
|
|
315
|
+
validate
|
|
316
|
+
})
|
|
317
|
+
</script>
|
|
318
|
+
|
|
319
|
+
<style lang="scss" scoped>
|
|
320
|
+
@import '@/assets/styles/theme.scss';
|
|
321
|
+
|
|
322
|
+
.delivery-text {
|
|
323
|
+
font-style: italic;
|
|
324
|
+
margin-top: 10px;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Address Block Layout
|
|
328
|
+
.address-block {
|
|
329
|
+
display: flex;
|
|
330
|
+
p {
|
|
331
|
+
margin-bottom: unset;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
.address-block__info {
|
|
336
|
+
flex: 1 1 auto;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Form Row Elements
|
|
340
|
+
.form__row.three-column {
|
|
341
|
+
align-items: stretch;
|
|
342
|
+
display: flex;
|
|
343
|
+
flex-flow: row nowrap;
|
|
344
|
+
margin-left: -0.5rem;
|
|
345
|
+
margin-right: -0.5rem;
|
|
346
|
+
|
|
347
|
+
.item {
|
|
348
|
+
flex: 1 1 auto;
|
|
349
|
+
flex-basis: 0;
|
|
350
|
+
margin-left: 0.5rem;
|
|
351
|
+
margin-right: 0.5rem;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
.pre-wrap {
|
|
356
|
+
white-space: pre-wrap;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// make 'readonly' inputs looks disabled
|
|
360
|
+
// (can't use 'disabled' because we want normal error styling)
|
|
361
|
+
.v-select.v-input--is-readonly,
|
|
362
|
+
.v-text-field.v-input--is-readonly {
|
|
363
|
+
pointer-events: none;
|
|
364
|
+
|
|
365
|
+
:deep(.v-label) {
|
|
366
|
+
// set label colour to same as disabled
|
|
367
|
+
color: rgba(0,0,0,.38);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
:deep(.v-select__selection) {
|
|
371
|
+
// set selection colour to same as disabled
|
|
372
|
+
color: rgba(0,0,0,.38);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
:deep(.v-icon) {
|
|
376
|
+
// set error icon colour to same as disabled
|
|
377
|
+
color: rgba(0,0,0,.38) !important;
|
|
378
|
+
opacity: 0.6;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
</style>
|