@formio/js 5.5.2 → 5.6.0
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/README.md +2 -2
- package/dist/formio.builder.css +3 -0
- package/dist/formio.builder.min.css +1 -1
- package/dist/formio.embed.js +1 -1
- package/dist/formio.embed.min.js +1 -1
- package/dist/formio.embed.min.js.LICENSE.txt +1 -1
- package/dist/formio.form.css +3 -0
- package/dist/formio.form.js +23 -23
- package/dist/formio.form.min.css +1 -1
- package/dist/formio.form.min.js +1 -1
- package/dist/formio.form.min.js.LICENSE.txt +1 -1
- package/dist/formio.full.css +3 -0
- package/dist/formio.full.js +25 -25
- package/dist/formio.full.min.css +1 -1
- package/dist/formio.full.min.js +1 -1
- package/dist/formio.full.min.js.LICENSE.txt +1 -1
- package/dist/formio.js +10 -10
- package/dist/formio.min.js +1 -1
- package/dist/formio.min.js.LICENSE.txt +1 -1
- package/dist/formio.utils.js +8 -8
- package/dist/formio.utils.min.js +1 -1
- package/dist/formio.utils.min.js.LICENSE.txt +1 -1
- package/lib/cjs/Embed.js +1 -1
- package/lib/cjs/Formio.js +1 -1
- package/lib/cjs/components/_classes/component/Component.js +2 -1
- package/lib/cjs/components/address/Address.js +5 -2
- package/lib/cjs/components/address/editForm/Address.edit.provider.d.ts +24 -0
- package/lib/cjs/components/address/editForm/Address.edit.provider.js +13 -0
- package/lib/cjs/components/datagrid/DataGrid.js +2 -1
- package/lib/cjs/components/file/File.js +17 -8
- package/lib/cjs/components/file/editForm/File.edit.file.d.ts +44 -0
- package/lib/cjs/components/file/editForm/File.edit.file.js +2 -1
- package/lib/cjs/components/form/Form.d.ts +7 -0
- package/lib/cjs/components/form/Form.js +24 -2
- package/lib/cjs/components/signature/Signature.js +2 -2
- package/lib/cjs/package.json +1 -1
- package/lib/cjs/providers/address/GoogleAddressProvider.d.ts +9 -1
- package/lib/cjs/providers/address/GoogleAddressProvider.js +116 -32
- package/lib/mjs/Embed.js +1 -1
- package/lib/mjs/Formio.js +1 -1
- package/lib/mjs/components/_classes/component/Component.js +1 -1
- package/lib/mjs/components/address/Address.js +5 -2
- package/lib/mjs/components/address/editForm/Address.edit.provider.d.ts +24 -0
- package/lib/mjs/components/address/editForm/Address.edit.provider.js +13 -0
- package/lib/mjs/components/datagrid/DataGrid.js +2 -1
- package/lib/mjs/components/file/File.js +17 -8
- package/lib/mjs/components/file/editForm/File.edit.file.d.ts +44 -0
- package/lib/mjs/components/file/editForm/File.edit.file.js +2 -1
- package/lib/mjs/components/form/Form.d.ts +7 -0
- package/lib/mjs/components/form/Form.js +24 -2
- package/lib/mjs/components/signature/Signature.js +2 -2
- package/lib/mjs/package.json +1 -1
- package/lib/mjs/providers/address/GoogleAddressProvider.d.ts +9 -1
- package/lib/mjs/providers/address/GoogleAddressProvider.js +94 -32
- package/package.json +7 -7
package/lib/mjs/Embed.js
CHANGED
|
@@ -14,7 +14,7 @@ export class Formio {
|
|
|
14
14
|
Formio._formioReady = ready;
|
|
15
15
|
Formio._formioReadyReject = reject;
|
|
16
16
|
});
|
|
17
|
-
static version = '5.
|
|
17
|
+
static version = '5.6.0';
|
|
18
18
|
static setLicense(license, norecurse = false) {
|
|
19
19
|
Formio.license = license;
|
|
20
20
|
if (!norecurse && Formio.FormioClass) {
|
package/lib/mjs/Formio.js
CHANGED
|
@@ -4,7 +4,7 @@ import CDN from './CDN';
|
|
|
4
4
|
import Providers from './providers';
|
|
5
5
|
FormioCore.cdn = new CDN();
|
|
6
6
|
FormioCore.Providers = Providers;
|
|
7
|
-
FormioCore.version = '5.
|
|
7
|
+
FormioCore.version = '5.6.0';
|
|
8
8
|
CDN.defaultCDN = FormioCore.version.includes('rc')
|
|
9
9
|
? 'https://cdn.test-form.io'
|
|
10
10
|
: 'https://cdn.form.io';
|
|
@@ -924,7 +924,7 @@ export default class Component extends Element {
|
|
|
924
924
|
return '';
|
|
925
925
|
}
|
|
926
926
|
// Use _userInput: true to ignore translations from defaults
|
|
927
|
-
if (text in enTranslation && params._userInput) {
|
|
927
|
+
if (this.i18next?.language === 'en' && text in enTranslation && params._userInput) {
|
|
928
928
|
return text;
|
|
929
929
|
}
|
|
930
930
|
params.data = params.data || this.rootValue;
|
|
@@ -414,8 +414,12 @@ export default class AddressComponent extends ContainerComponent {
|
|
|
414
414
|
this.searchInput.forEach((element, index) => {
|
|
415
415
|
if (!this.builderMode && element && this.provider) {
|
|
416
416
|
if (this.component.provider === 'google') {
|
|
417
|
+
if (this.component.enableNewPlacesApi) {
|
|
418
|
+
this.provider.options.version = 'newPlacesApi';
|
|
419
|
+
}
|
|
417
420
|
this.googlePlacesCleanups = [];
|
|
418
|
-
this.provider
|
|
421
|
+
this.provider
|
|
422
|
+
.attachAutocomplete(element, index, this.onSelectAddress.bind(this), this.disabled)
|
|
419
423
|
.then((cleanup) => {
|
|
420
424
|
if (typeof cleanup === 'function') {
|
|
421
425
|
this.googlePlacesCleanups.push(cleanup);
|
|
@@ -516,7 +520,6 @@ export default class AddressComponent extends ContainerComponent {
|
|
|
516
520
|
if (this.autocompleterWidget && typeof this.autocompleterWidget.destroy === 'function') {
|
|
517
521
|
this.autocompleterWidget.destroy();
|
|
518
522
|
}
|
|
519
|
-
;
|
|
520
523
|
(this.googlePlacesCleanups || []).forEach((cleanup) => {
|
|
521
524
|
cleanup();
|
|
522
525
|
});
|
|
@@ -118,6 +118,30 @@ declare const _default: ({
|
|
|
118
118
|
validate?: undefined;
|
|
119
119
|
defaultValue?: undefined;
|
|
120
120
|
description?: undefined;
|
|
121
|
+
} | {
|
|
122
|
+
weight: number;
|
|
123
|
+
type: string;
|
|
124
|
+
input: boolean;
|
|
125
|
+
key: string;
|
|
126
|
+
label: string;
|
|
127
|
+
tooltip: string;
|
|
128
|
+
conditional: {
|
|
129
|
+
json: {
|
|
130
|
+
'===': (string | {
|
|
131
|
+
var: string;
|
|
132
|
+
})[];
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
placeholder?: undefined;
|
|
136
|
+
valueProperty?: undefined;
|
|
137
|
+
dataSrc?: undefined;
|
|
138
|
+
data?: undefined;
|
|
139
|
+
validate?: undefined;
|
|
140
|
+
defaultValue?: undefined;
|
|
141
|
+
rows?: undefined;
|
|
142
|
+
editor?: undefined;
|
|
143
|
+
as?: undefined;
|
|
144
|
+
description?: undefined;
|
|
121
145
|
} | {
|
|
122
146
|
type: string;
|
|
123
147
|
input: boolean;
|
|
@@ -136,6 +136,19 @@ export default [
|
|
|
136
136
|
},
|
|
137
137
|
},
|
|
138
138
|
},
|
|
139
|
+
{
|
|
140
|
+
weight: 10,
|
|
141
|
+
type: 'checkbox',
|
|
142
|
+
input: true,
|
|
143
|
+
key: 'enableNewPlacesApi',
|
|
144
|
+
label: 'Places API (New)',
|
|
145
|
+
tooltip: 'Enable the new Google Places API instead of the legacy version.',
|
|
146
|
+
conditional: {
|
|
147
|
+
json: {
|
|
148
|
+
'===': [{ var: 'data.provider' }, 'google'],
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
},
|
|
139
152
|
{
|
|
140
153
|
type: 'textarea',
|
|
141
154
|
input: true,
|
|
@@ -539,10 +539,11 @@ export default class DataGridComponent extends NestedArrayComponent {
|
|
|
539
539
|
}, modified);
|
|
540
540
|
this.triggerRootChange(flags, changed, modified);
|
|
541
541
|
}
|
|
542
|
+
const rowData = this.dataValue[rowIndex];
|
|
542
543
|
this.processRow('checkData', null, {
|
|
543
544
|
...flags,
|
|
544
545
|
changed,
|
|
545
|
-
},
|
|
546
|
+
}, rowData, _.toArray(this.rows[rowIndex]));
|
|
546
547
|
};
|
|
547
548
|
let columnComponent;
|
|
548
549
|
if (this.builderMode) {
|
|
@@ -92,6 +92,11 @@ export default class FileComponent extends Field {
|
|
|
92
92
|
this.abortUploads = [];
|
|
93
93
|
this.pendingfiles = [];
|
|
94
94
|
this.resolvedFiles = [];
|
|
95
|
+
const imageSize = Number(this.component.imageSize);
|
|
96
|
+
const isValidImageSize = imageSize > 0;
|
|
97
|
+
if (!isValidImageSize) {
|
|
98
|
+
this.component.imageSize = '200';
|
|
99
|
+
}
|
|
95
100
|
}
|
|
96
101
|
get dataReady() {
|
|
97
102
|
return this.filesReady || Promise.resolve();
|
|
@@ -635,7 +640,7 @@ export default class FileComponent extends Field {
|
|
|
635
640
|
fileKey: this.component.fileKey || 'file',
|
|
636
641
|
storage: this.component.storage,
|
|
637
642
|
options: this.component.storage === 'url'
|
|
638
|
-
?
|
|
643
|
+
? this.component.urlRequestOptions || this.component.options
|
|
639
644
|
: this.component.options,
|
|
640
645
|
file,
|
|
641
646
|
size: file.size,
|
|
@@ -668,7 +673,9 @@ export default class FileComponent extends Field {
|
|
|
668
673
|
return fileWithSameNameUploaded || fileWithSameNameUploading
|
|
669
674
|
? {
|
|
670
675
|
status: 'error',
|
|
671
|
-
message: this.t(fileWithSameNameUploading
|
|
676
|
+
message: this.t(fileWithSameNameUploading
|
|
677
|
+
? 'fileWithDuplicatedNameInProgress'
|
|
678
|
+
: 'fileWithDuplicatedNameLoaded'),
|
|
672
679
|
}
|
|
673
680
|
: {};
|
|
674
681
|
}
|
|
@@ -866,8 +873,8 @@ export default class FileComponent extends Field {
|
|
|
866
873
|
}
|
|
867
874
|
async deleteFile(fileInfo) {
|
|
868
875
|
const options = this.component.storage === 'url'
|
|
869
|
-
?
|
|
870
|
-
:
|
|
876
|
+
? this.component.urlRequestOptions || this.component.options || {}
|
|
877
|
+
: this.component.options || {};
|
|
871
878
|
if (fileInfo &&
|
|
872
879
|
['url', 'indexeddb', 's3', 'azure', 'googledrive'].includes(this.component.storage)) {
|
|
873
880
|
const { fileService } = this;
|
|
@@ -1006,7 +1013,7 @@ export default class FileComponent extends Field {
|
|
|
1006
1013
|
delete fileToSync.progress;
|
|
1007
1014
|
this.redraw();
|
|
1008
1015
|
if (fileInfo) {
|
|
1009
|
-
const fileExists = this.resolvedFiles.find(x => x.fileInfo.originalName === fileToSync.originalName);
|
|
1016
|
+
const fileExists = this.resolvedFiles.find((x) => x.fileInfo.originalName === fileToSync.originalName);
|
|
1010
1017
|
if (!fileExists && fileToSync.status !== 'error') {
|
|
1011
1018
|
this.resolvedFiles.push({ fileToSync, fileInfo });
|
|
1012
1019
|
}
|
|
@@ -1060,8 +1067,8 @@ export default class FileComponent extends Field {
|
|
|
1060
1067
|
}
|
|
1061
1068
|
getFile(fileInfo) {
|
|
1062
1069
|
const options = this.component.storage === 'url'
|
|
1063
|
-
?
|
|
1064
|
-
:
|
|
1070
|
+
? this.component.urlRequestOptions || this.component.options || {}
|
|
1071
|
+
: this.component.options || {};
|
|
1065
1072
|
const { fileService } = this;
|
|
1066
1073
|
if (!fileService) {
|
|
1067
1074
|
return alert(this.t('noFileService'));
|
|
@@ -1101,7 +1108,9 @@ export default class FileComponent extends Field {
|
|
|
1101
1108
|
return Promise.resolve();
|
|
1102
1109
|
}
|
|
1103
1110
|
await this.syncFiles();
|
|
1104
|
-
return this.shouldSyncFiles
|
|
1111
|
+
return this.shouldSyncFiles
|
|
1112
|
+
? Promise.reject(this.t('synchronizationFailed'))
|
|
1113
|
+
: Promise.resolve();
|
|
1105
1114
|
}
|
|
1106
1115
|
catch (error) {
|
|
1107
1116
|
return Promise.reject(error.message);
|
|
@@ -18,6 +18,7 @@ declare const _default: ({
|
|
|
18
18
|
editor?: undefined;
|
|
19
19
|
as?: undefined;
|
|
20
20
|
logic?: undefined;
|
|
21
|
+
clearOnHide?: undefined;
|
|
21
22
|
optionsLabelPosition?: undefined;
|
|
22
23
|
inline?: undefined;
|
|
23
24
|
defaultValue?: undefined;
|
|
@@ -48,6 +49,7 @@ declare const _default: ({
|
|
|
48
49
|
editor?: undefined;
|
|
49
50
|
as?: undefined;
|
|
50
51
|
logic?: undefined;
|
|
52
|
+
clearOnHide?: undefined;
|
|
51
53
|
optionsLabelPosition?: undefined;
|
|
52
54
|
inline?: undefined;
|
|
53
55
|
defaultValue?: undefined;
|
|
@@ -95,6 +97,7 @@ declare const _default: ({
|
|
|
95
97
|
editor?: undefined;
|
|
96
98
|
as?: undefined;
|
|
97
99
|
logic?: undefined;
|
|
100
|
+
clearOnHide?: undefined;
|
|
98
101
|
optionsLabelPosition?: undefined;
|
|
99
102
|
inline?: undefined;
|
|
100
103
|
defaultValue?: undefined;
|
|
@@ -125,6 +128,7 @@ declare const _default: ({
|
|
|
125
128
|
editor?: undefined;
|
|
126
129
|
as?: undefined;
|
|
127
130
|
logic?: undefined;
|
|
131
|
+
clearOnHide?: undefined;
|
|
128
132
|
optionsLabelPosition?: undefined;
|
|
129
133
|
inline?: undefined;
|
|
130
134
|
defaultValue?: undefined;
|
|
@@ -161,6 +165,7 @@ declare const _default: ({
|
|
|
161
165
|
editor?: undefined;
|
|
162
166
|
as?: undefined;
|
|
163
167
|
logic?: undefined;
|
|
168
|
+
clearOnHide?: undefined;
|
|
164
169
|
optionsLabelPosition?: undefined;
|
|
165
170
|
inline?: undefined;
|
|
166
171
|
defaultValue?: undefined;
|
|
@@ -191,6 +196,7 @@ declare const _default: ({
|
|
|
191
196
|
tableView?: undefined;
|
|
192
197
|
components?: undefined;
|
|
193
198
|
logic?: undefined;
|
|
199
|
+
clearOnHide?: undefined;
|
|
194
200
|
optionsLabelPosition?: undefined;
|
|
195
201
|
inline?: undefined;
|
|
196
202
|
defaultValue?: undefined;
|
|
@@ -237,6 +243,7 @@ declare const _default: ({
|
|
|
237
243
|
rows?: undefined;
|
|
238
244
|
editor?: undefined;
|
|
239
245
|
as?: undefined;
|
|
246
|
+
clearOnHide?: undefined;
|
|
240
247
|
optionsLabelPosition?: undefined;
|
|
241
248
|
inline?: undefined;
|
|
242
249
|
defaultValue?: undefined;
|
|
@@ -259,6 +266,7 @@ declare const _default: ({
|
|
|
259
266
|
editor?: undefined;
|
|
260
267
|
as?: undefined;
|
|
261
268
|
logic?: undefined;
|
|
269
|
+
clearOnHide?: undefined;
|
|
262
270
|
optionsLabelPosition?: undefined;
|
|
263
271
|
inline?: undefined;
|
|
264
272
|
defaultValue?: undefined;
|
|
@@ -281,6 +289,7 @@ declare const _default: ({
|
|
|
281
289
|
editor?: undefined;
|
|
282
290
|
as?: undefined;
|
|
283
291
|
logic?: undefined;
|
|
292
|
+
clearOnHide?: undefined;
|
|
284
293
|
optionsLabelPosition?: undefined;
|
|
285
294
|
inline?: undefined;
|
|
286
295
|
defaultValue?: undefined;
|
|
@@ -311,6 +320,7 @@ declare const _default: ({
|
|
|
311
320
|
editor?: undefined;
|
|
312
321
|
as?: undefined;
|
|
313
322
|
logic?: undefined;
|
|
323
|
+
clearOnHide?: undefined;
|
|
314
324
|
optionsLabelPosition?: undefined;
|
|
315
325
|
inline?: undefined;
|
|
316
326
|
defaultValue?: undefined;
|
|
@@ -323,6 +333,7 @@ declare const _default: ({
|
|
|
323
333
|
placeholder: string;
|
|
324
334
|
tooltip: string;
|
|
325
335
|
weight: number;
|
|
336
|
+
clearOnHide: boolean;
|
|
326
337
|
conditional: {
|
|
327
338
|
json: {
|
|
328
339
|
'==': (boolean | {
|
|
@@ -345,6 +356,37 @@ declare const _default: ({
|
|
|
345
356
|
inline?: undefined;
|
|
346
357
|
defaultValue?: undefined;
|
|
347
358
|
values?: undefined;
|
|
359
|
+
} | {
|
|
360
|
+
type: string;
|
|
361
|
+
input: boolean;
|
|
362
|
+
key: string;
|
|
363
|
+
label: string;
|
|
364
|
+
placeholder: string;
|
|
365
|
+
tooltip: string;
|
|
366
|
+
weight: number;
|
|
367
|
+
conditional: {
|
|
368
|
+
json: {
|
|
369
|
+
'==': (boolean | {
|
|
370
|
+
var: string;
|
|
371
|
+
})[];
|
|
372
|
+
'==='?: undefined;
|
|
373
|
+
in?: undefined;
|
|
374
|
+
};
|
|
375
|
+
};
|
|
376
|
+
valueProperty?: undefined;
|
|
377
|
+
dataSrc?: undefined;
|
|
378
|
+
data?: undefined;
|
|
379
|
+
tableView?: undefined;
|
|
380
|
+
components?: undefined;
|
|
381
|
+
rows?: undefined;
|
|
382
|
+
editor?: undefined;
|
|
383
|
+
as?: undefined;
|
|
384
|
+
logic?: undefined;
|
|
385
|
+
clearOnHide?: undefined;
|
|
386
|
+
optionsLabelPosition?: undefined;
|
|
387
|
+
inline?: undefined;
|
|
388
|
+
defaultValue?: undefined;
|
|
389
|
+
values?: undefined;
|
|
348
390
|
} | {
|
|
349
391
|
type: string;
|
|
350
392
|
input: boolean;
|
|
@@ -370,6 +412,7 @@ declare const _default: ({
|
|
|
370
412
|
editor?: undefined;
|
|
371
413
|
as?: undefined;
|
|
372
414
|
logic?: undefined;
|
|
415
|
+
clearOnHide?: undefined;
|
|
373
416
|
} | {
|
|
374
417
|
type: string;
|
|
375
418
|
input: boolean;
|
|
@@ -393,6 +436,7 @@ declare const _default: ({
|
|
|
393
436
|
editor?: undefined;
|
|
394
437
|
as?: undefined;
|
|
395
438
|
logic?: undefined;
|
|
439
|
+
clearOnHide?: undefined;
|
|
396
440
|
optionsLabelPosition?: undefined;
|
|
397
441
|
inline?: undefined;
|
|
398
442
|
defaultValue?: undefined;
|
|
@@ -290,8 +290,9 @@ export default [
|
|
|
290
290
|
key: 'imageSize',
|
|
291
291
|
label: 'Image Size',
|
|
292
292
|
placeholder: '100',
|
|
293
|
-
tooltip: 'The image size for previewing images.',
|
|
293
|
+
tooltip: 'The image size, in square pixels, for previewing images.',
|
|
294
294
|
weight: 40,
|
|
295
|
+
clearOnHide: false,
|
|
295
296
|
conditional: {
|
|
296
297
|
json: {
|
|
297
298
|
'==': [{ var: 'data.image' }, true],
|
|
@@ -63,6 +63,13 @@ export default class FormComponent extends Component {
|
|
|
63
63
|
checkComponentConditions(data: any, flags: any, row: any): any;
|
|
64
64
|
calculateValue(data: any, flags: any, row: any): any;
|
|
65
65
|
setPristine(pristine: any): void;
|
|
66
|
+
/**
|
|
67
|
+
* Determine if an ancestor is hidden by the `hidden` JSON flag alone. An ancestor that has its
|
|
68
|
+
* own condition is governed by that condition instead and is left to `parentConditionallyHidden`
|
|
69
|
+
* — the `hidden` flag and conditionally-hidden are distinct states (FIO-11691).
|
|
70
|
+
* @returns {boolean} - TRUE if an ancestor is hidden in the JSON and has no condition.
|
|
71
|
+
*/
|
|
72
|
+
hasAncestorHiddenInJsonOnly(): boolean;
|
|
66
73
|
/**
|
|
67
74
|
* Determine if the subform should be submitted.
|
|
68
75
|
* @returns {*|boolean} - TRUE if the subform should be submitted, FALSE if it should not.
|
|
@@ -554,16 +554,38 @@ export default class FormComponent extends Component {
|
|
|
554
554
|
this.subForm.setPristine(pristine);
|
|
555
555
|
}
|
|
556
556
|
}
|
|
557
|
+
/**
|
|
558
|
+
* Determine if an ancestor is hidden by the `hidden` JSON flag alone. An ancestor that has its
|
|
559
|
+
* own condition is governed by that condition instead and is left to `parentConditionallyHidden`
|
|
560
|
+
* — the `hidden` flag and conditionally-hidden are distinct states (FIO-11691).
|
|
561
|
+
* @returns {boolean} - TRUE if an ancestor is hidden in the JSON and has no condition.
|
|
562
|
+
*/
|
|
563
|
+
hasAncestorHiddenInJsonOnly() {
|
|
564
|
+
let currentParent = this.parent;
|
|
565
|
+
while (currentParent) {
|
|
566
|
+
if (currentParent.component.hidden && !currentParent.hasCondition()) {
|
|
567
|
+
return true;
|
|
568
|
+
}
|
|
569
|
+
currentParent = currentParent.parent;
|
|
570
|
+
}
|
|
571
|
+
return false;
|
|
572
|
+
}
|
|
557
573
|
/**
|
|
558
574
|
* Determine if the subform should be submitted.
|
|
559
575
|
* @returns {*|boolean} - TRUE if the subform should be submitted, FALSE if it should not.
|
|
560
576
|
*/
|
|
561
577
|
get shouldSubmit() {
|
|
578
|
+
const savesAsReference = !this.component.hasOwnProperty('reference') || this.component.reference;
|
|
562
579
|
const hiddenByJsonOnly = !this.hasCondition() && this.component.hidden;
|
|
580
|
+
// Layout ancestors (fieldset, panel, tabs...) hide us without appearing in our data path, so
|
|
581
|
+
// their hidden state is only reachable by walking the instance chain (FIO-9879).
|
|
582
|
+
const hiddenByAncestor = this.hasAncestorHiddenInJsonOnly() || this.parentConditionallyHidden();
|
|
583
|
+
// Gate on our own clearOnHide, never an ancestor's.
|
|
584
|
+
const clearedWhileHidden = (hiddenByJsonOnly || hiddenByAncestor) && this.component.clearOnHide;
|
|
563
585
|
return (this.subFormReady &&
|
|
564
|
-
|
|
586
|
+
savesAsReference &&
|
|
565
587
|
!this.shouldConditionallyClear() &&
|
|
566
|
-
!
|
|
588
|
+
!clearedWhileHidden);
|
|
567
589
|
}
|
|
568
590
|
/**
|
|
569
591
|
* Returns the data for the subform.
|
|
@@ -199,7 +199,7 @@ export default class SignatureComponent extends Input {
|
|
|
199
199
|
penColor: this.component.penColor,
|
|
200
200
|
backgroundColor: this.component.backgroundColor,
|
|
201
201
|
});
|
|
202
|
-
this.signaturePad.addEventListener('endStroke', () => this.setValue(this.signaturePad.toDataURL()));
|
|
202
|
+
this.signaturePad.addEventListener('endStroke', () => this.setValue(this.signaturePad.toDataURL(), { modified: true }));
|
|
203
203
|
this.refs.signatureImage.setAttribute('src', this.signaturePad.toDataURL());
|
|
204
204
|
this.onDisabled();
|
|
205
205
|
// Ensure the signature is always the size of its container.
|
|
@@ -228,7 +228,7 @@ export default class SignatureComponent extends Input {
|
|
|
228
228
|
event.preventDefault();
|
|
229
229
|
this.showCanvas(true);
|
|
230
230
|
this.signaturePad.clear();
|
|
231
|
-
this.setValue(this.defaultValue);
|
|
231
|
+
this.setValue(this.defaultValue, { modified: true });
|
|
232
232
|
});
|
|
233
233
|
this.setValue(this.dataValue);
|
|
234
234
|
return superAttach;
|
package/lib/mjs/package.json
CHANGED
|
@@ -39,6 +39,14 @@ export class GoogleAddressProvider extends AddressProvider {
|
|
|
39
39
|
* @returns {string} The alternative property to use for display value.
|
|
40
40
|
*/
|
|
41
41
|
get alternativeDisplayValueProperty(): string;
|
|
42
|
+
/**
|
|
43
|
+
* @returns {string} The property to use for display value on places returned by the new Places API.
|
|
44
|
+
*/
|
|
45
|
+
get newApiDisplayValueProperty(): string;
|
|
46
|
+
/**
|
|
47
|
+
* @returns {boolean} Whether the provider is configured to use the new Places API.
|
|
48
|
+
*/
|
|
49
|
+
get usesNewPlacesApi(): boolean;
|
|
42
50
|
/**
|
|
43
51
|
* @param {AutocompleteOptions} options - The autocomplete options.
|
|
44
52
|
*/
|
|
@@ -78,7 +86,7 @@ export class GoogleAddressProvider extends AddressProvider {
|
|
|
78
86
|
*/
|
|
79
87
|
addRequiredProviderOptions(options: AutocompleteOptions): void;
|
|
80
88
|
filterPlace(place: any): {};
|
|
81
|
-
attachAutocomplete(elem: any, index: any, onSelectAddress: any): any;
|
|
89
|
+
attachAutocomplete(elem: any, index: any, onSelectAddress: any, disable?: boolean): any;
|
|
82
90
|
search(): Promise<void>;
|
|
83
91
|
makeRequest(): Promise<void>;
|
|
84
92
|
getDisplayValue(address: any): any;
|
|
@@ -5,6 +5,7 @@ import { AddressProvider } from './AddressProvider';
|
|
|
5
5
|
const GOOGLE_MAPS_BASE_URL = 'https://maps.googleapis.com';
|
|
6
6
|
const GOOGLE_MAPS_JS_URL = `${GOOGLE_MAPS_BASE_URL}/maps/api/js`;
|
|
7
7
|
const GOOGLE_MAPS_JS_WITH_PARAMS_URL = `${GOOGLE_MAPS_JS_URL}?v=quarterly&libraries=places&loading=async&callback=googleMapsCallback`;
|
|
8
|
+
const NEW_PLACES_API_VERSION = 'newPlacesApi';
|
|
8
9
|
/**
|
|
9
10
|
* @typedef {object} AutocompleteOptions
|
|
10
11
|
* @property {string[]} fields - The fields to include in the autocomplete response.
|
|
@@ -71,6 +72,18 @@ export class GoogleAddressProvider extends AddressProvider {
|
|
|
71
72
|
get alternativeDisplayValueProperty() {
|
|
72
73
|
return 'formatted_address';
|
|
73
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* @returns {string} The property to use for display value on places returned by the new Places API.
|
|
77
|
+
*/
|
|
78
|
+
get newApiDisplayValueProperty() {
|
|
79
|
+
return 'formattedAddress';
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* @returns {boolean} Whether the provider is configured to use the new Places API.
|
|
83
|
+
*/
|
|
84
|
+
get usesNewPlacesApi() {
|
|
85
|
+
return this.options?.version === NEW_PLACES_API_VERSION;
|
|
86
|
+
}
|
|
74
87
|
/**
|
|
75
88
|
* @param {AutocompleteOptions} options - The autocomplete options.
|
|
76
89
|
*/
|
|
@@ -88,10 +101,11 @@ export class GoogleAddressProvider extends AddressProvider {
|
|
|
88
101
|
|
|
89
102
|
*/
|
|
90
103
|
setAutocompleteOptions() {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
104
|
+
// Clone so the stored provider options are never mutated: the required fields
|
|
105
|
+
// differ per Places API version, and stale fields from a previous computation
|
|
106
|
+
// must not leak into the next one (FIO-10428).
|
|
107
|
+
const storedOptions = _.get(this.options, 'autocompleteOptions', {});
|
|
108
|
+
const options = _.isObject(storedOptions) ? _.cloneDeep(storedOptions) : {};
|
|
95
109
|
this.addRequiredProviderOptions(options);
|
|
96
110
|
this.autocompleteOptions = options;
|
|
97
111
|
}
|
|
@@ -131,14 +145,9 @@ export class GoogleAddressProvider extends AddressProvider {
|
|
|
131
145
|
* @returns {string[]} The required address properties.
|
|
132
146
|
*/
|
|
133
147
|
getRequiredAddressProperties() {
|
|
134
|
-
return
|
|
135
|
-
'
|
|
136
|
-
'formatted_address',
|
|
137
|
-
'geometry',
|
|
138
|
-
'place_id',
|
|
139
|
-
'plus_code',
|
|
140
|
-
'types',
|
|
141
|
-
];
|
|
148
|
+
return this.usesNewPlacesApi
|
|
149
|
+
? ['addressComponents', 'formattedAddress', 'location', 'viewport', 'id', 'plusCode', 'types']
|
|
150
|
+
: ['address_components', 'formatted_address', 'geometry', 'place_id', 'plus_code', 'types'];
|
|
142
151
|
}
|
|
143
152
|
/**
|
|
144
153
|
* Adds the required provider options to the options.
|
|
@@ -167,24 +176,75 @@ export class GoogleAddressProvider extends AddressProvider {
|
|
|
167
176
|
}
|
|
168
177
|
return filteredPlace;
|
|
169
178
|
}
|
|
170
|
-
attachAutocomplete(elem, index, onSelectAddress) {
|
|
179
|
+
attachAutocomplete(elem, index, onSelectAddress, disable = false) {
|
|
180
|
+
if (disable) {
|
|
181
|
+
return Promise.resolve();
|
|
182
|
+
}
|
|
171
183
|
return Formio.libraryReady(this.getLibraryName()).then(() => {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
if (google?.maps?.event) {
|
|
180
|
-
google.maps.event.clearInstanceListeners(autocomplete);
|
|
181
|
-
google.maps.event.removeListener(listener);
|
|
182
|
-
}
|
|
183
|
-
document.querySelectorAll('.pac-container').forEach((node) => {
|
|
184
|
-
if (node.parentNode) {
|
|
185
|
-
node.parentNode.removeChild(node);
|
|
186
|
-
}
|
|
184
|
+
this.setAutocompleteOptions();
|
|
185
|
+
if (!this.usesNewPlacesApi) {
|
|
186
|
+
const autocomplete = new google.maps.places.Autocomplete(elem, this.autocompleteOptions);
|
|
187
|
+
const listener = autocomplete.addListener('place_changed', () => {
|
|
188
|
+
const place = this.filterPlace(autocomplete.getPlace());
|
|
189
|
+
place.formattedPlace = _.get(autocomplete, 'gm_accessors_.place.se.formattedPrediction', place[this.alternativeDisplayValueProperty]);
|
|
190
|
+
onSelectAddress(place, elem, index);
|
|
187
191
|
});
|
|
192
|
+
return () => {
|
|
193
|
+
if (google?.maps?.event) {
|
|
194
|
+
google.maps.event.clearInstanceListeners(autocomplete);
|
|
195
|
+
google.maps.event.removeListener(listener);
|
|
196
|
+
}
|
|
197
|
+
document.querySelectorAll('.pac-container').forEach((node) => {
|
|
198
|
+
if (node.parentNode) {
|
|
199
|
+
node.parentNode.removeChild(node);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
const { fields, componentRestrictions, ...elementOptions } = this.autocompleteOptions;
|
|
205
|
+
const country = componentRestrictions?.country;
|
|
206
|
+
if (country) {
|
|
207
|
+
// The new element spells legacy componentRestrictions.country as includedRegionCodes.
|
|
208
|
+
elementOptions.includedRegionCodes = _.castArray(country);
|
|
209
|
+
}
|
|
210
|
+
elementOptions.noInputIcon = true;
|
|
211
|
+
const autocomplete = new google.maps.places.PlaceAutocompleteElement(elementOptions);
|
|
212
|
+
if (elem?.value) {
|
|
213
|
+
autocomplete.value = elem.value;
|
|
214
|
+
}
|
|
215
|
+
autocomplete.classList.add('form-control');
|
|
216
|
+
// Replace the existing element with the autocomplete element
|
|
217
|
+
elem.parentNode.replaceChildren(autocomplete);
|
|
218
|
+
const handlePlaceSelect = async (event) => {
|
|
219
|
+
let selectedPlace;
|
|
220
|
+
try {
|
|
221
|
+
const place = event.placePrediction.toPlace();
|
|
222
|
+
await place.fetchFields({
|
|
223
|
+
fields: fields || this.getRequiredAddressProperties(),
|
|
224
|
+
});
|
|
225
|
+
const convertedPlace = {
|
|
226
|
+
addressComponents: place.addressComponents || [],
|
|
227
|
+
formattedAddress: place.formattedAddress || '',
|
|
228
|
+
location: place.location || {},
|
|
229
|
+
viewport: place.viewport || {},
|
|
230
|
+
id: place.id || '',
|
|
231
|
+
plusCode: place.plusCode || {},
|
|
232
|
+
types: place.types || [],
|
|
233
|
+
};
|
|
234
|
+
selectedPlace = this.filterPlace(convertedPlace);
|
|
235
|
+
selectedPlace.formattedPlace = convertedPlace.formattedAddress;
|
|
236
|
+
}
|
|
237
|
+
catch (err) {
|
|
238
|
+
// fetchFields rejections are otherwise swallowed by the Maps event
|
|
239
|
+
// dispatcher; never let a failed details request drop the selection.
|
|
240
|
+
console.warn(`Unable to fetch the selected place's details: ${err}`);
|
|
241
|
+
selectedPlace = { formattedPlace: String(event.placePrediction?.text ?? '') };
|
|
242
|
+
}
|
|
243
|
+
onSelectAddress(selectedPlace, elem, index);
|
|
244
|
+
};
|
|
245
|
+
autocomplete.addEventListener('gmp-select', handlePlaceSelect);
|
|
246
|
+
return () => {
|
|
247
|
+
autocomplete.removeEventListener('gmp-select', handlePlaceSelect);
|
|
188
248
|
};
|
|
189
249
|
});
|
|
190
250
|
}
|
|
@@ -195,10 +255,12 @@ export class GoogleAddressProvider extends AddressProvider {
|
|
|
195
255
|
return Promise.resolve();
|
|
196
256
|
}
|
|
197
257
|
getDisplayValue(address) {
|
|
198
|
-
const displayedProperty =
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
258
|
+
const displayedProperty = [
|
|
259
|
+
this.displayValueProperty,
|
|
260
|
+
this.alternativeDisplayValueProperty,
|
|
261
|
+
this.newApiDisplayValueProperty,
|
|
262
|
+
].find((property) => _.has(address, property));
|
|
263
|
+
return displayedProperty ? _.get(address, displayedProperty, '') : '';
|
|
202
264
|
}
|
|
203
265
|
/**
|
|
204
266
|
* Tries to remove the library if api key for loaded script is different.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@formio/js",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.6.0",
|
|
4
4
|
"description": "JavaScript powered Forms with JSON Form Builder",
|
|
5
5
|
"main": "lib/cjs/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -56,6 +56,8 @@
|
|
|
56
56
|
},
|
|
57
57
|
"homepage": "https://github.com/formio/formio.js#readme",
|
|
58
58
|
"dependencies": {
|
|
59
|
+
"@formio/bootstrap": "^4.0.5",
|
|
60
|
+
"@formio/core": "^2.8.3",
|
|
59
61
|
"@formio/text-mask-addons": "^3.8.0-formio.4",
|
|
60
62
|
"@formio/vanilla-text-mask": "^5.1.1-formio.1",
|
|
61
63
|
"abortcontroller-polyfill": "^1.7.5",
|
|
@@ -69,7 +71,7 @@
|
|
|
69
71
|
"core-js": "^3.37.1",
|
|
70
72
|
"dialog-polyfill": "^0.5.6",
|
|
71
73
|
"dom-autoscroller": "^2.3.4",
|
|
72
|
-
"dompurify": "^3.4.
|
|
74
|
+
"dompurify": "^3.4.13",
|
|
73
75
|
"downloadjs": "^1.4.7",
|
|
74
76
|
"dragula": "^3.7.3",
|
|
75
77
|
"eventemitter3": "^5.0.1",
|
|
@@ -88,11 +90,10 @@
|
|
|
88
90
|
"signature_pad": "^4.2.0",
|
|
89
91
|
"string-hash": "^1.1.3",
|
|
90
92
|
"tippy.js": "^6.3.7",
|
|
91
|
-
"vanilla-picker": "^2.12.3"
|
|
92
|
-
"@formio/bootstrap": "^4.0.5",
|
|
93
|
-
"@formio/core": "^2.8.2"
|
|
93
|
+
"vanilla-picker": "^2.12.3"
|
|
94
94
|
},
|
|
95
95
|
"devDependencies": {
|
|
96
|
+
"@formio/eslint-config": "0.0.0",
|
|
96
97
|
"@types/node": "^22.15.19",
|
|
97
98
|
"ace-builds": "1.34.2",
|
|
98
99
|
"async-limiter": "^2.0.0",
|
|
@@ -145,8 +146,7 @@
|
|
|
145
146
|
"webpack-bundle-analyzer": "^4.10.2",
|
|
146
147
|
"webpack-cli": "^5.1.1",
|
|
147
148
|
"webpack-node-externals": "^3.0.0",
|
|
148
|
-
"webpack-stream": "^7.0.0"
|
|
149
|
-
"@formio/eslint-config": "0.0.0"
|
|
149
|
+
"webpack-stream": "^7.0.0"
|
|
150
150
|
},
|
|
151
151
|
"ossRepo": {
|
|
152
152
|
"repo": "https://github.com/formio/formio.js.git",
|