@formio/js 5.3.6 → 5.4.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/dist/formio.builder.css +31 -5
- package/dist/formio.builder.min.css +1 -1
- package/dist/formio.embed.css +1 -1
- package/dist/formio.embed.js +1 -1
- package/dist/formio.embed.min.css +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 +31 -5
- package/dist/formio.form.js +2837 -2818
- 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 +31 -5
- package/dist/formio.full.js +3442 -3403
- 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 +1152 -1154
- package/dist/formio.min.js +1 -1
- package/dist/formio.min.js.LICENSE.txt +1 -1
- package/dist/formio.utils.js +1084 -1086
- package/dist/formio.utils.min.js +1 -1
- package/dist/formio.utils.min.js.LICENSE.txt +1 -1
- package/lib/cjs/Embed.js +28 -1
- package/lib/cjs/Form.d.ts +4 -2
- package/lib/cjs/Form.js +2 -2
- package/lib/cjs/FormBuilder.d.ts +2 -2
- package/lib/cjs/FormBuilder.js +1 -1
- package/lib/cjs/Formio.js +1 -1
- package/lib/cjs/PDF.js +2 -0
- package/lib/cjs/PDFBuilder.js +6 -1
- package/lib/cjs/Webform.d.ts +1 -0
- package/lib/cjs/Webform.js +50 -1
- package/lib/cjs/WebformBuilder.js +29 -1
- package/lib/cjs/Wizard.d.ts +1 -0
- package/lib/cjs/Wizard.js +11 -0
- package/lib/cjs/components/Components.d.ts +3 -0
- package/lib/cjs/components/_classes/component/Component.d.ts +13 -3
- package/lib/cjs/components/_classes/component/Component.js +167 -47
- package/lib/cjs/components/_classes/component/editForm/Component.edit.conditional.js +1 -1
- package/lib/cjs/components/_classes/component/editForm/Component.edit.data.d.ts +7 -0
- package/lib/cjs/components/_classes/component/editForm/Component.edit.data.js +2 -1
- package/lib/cjs/components/_classes/component/editForm/utils.d.ts +1 -0
- package/lib/cjs/components/_classes/component/editForm/utils.js +3 -0
- package/lib/cjs/components/_classes/nested/NestedComponent.js +5 -0
- package/lib/cjs/components/address/Address.js +18 -0
- package/lib/cjs/components/datagrid/DataGrid.js +12 -2
- package/lib/cjs/components/datamap/DataMap.d.ts +1 -0
- package/lib/cjs/components/datamap/DataMap.js +37 -4
- package/lib/cjs/components/datetime/DateTime.js +11 -1
- package/lib/cjs/components/day/Day.d.ts +0 -15
- package/lib/cjs/components/day/Day.js +8 -17
- package/lib/cjs/components/editgrid/EditGrid.js +11 -1
- package/lib/cjs/components/fieldset/Fieldset.js +1 -0
- package/lib/cjs/components/file/File.d.ts +3 -1
- package/lib/cjs/components/file/File.js +62 -17
- package/lib/cjs/components/form/Form.js +3 -1
- package/lib/cjs/components/number/Number.d.ts +1 -0
- package/lib/cjs/components/number/Number.js +18 -0
- package/lib/cjs/components/select/Select.js +5 -1
- package/lib/cjs/components/signature/Signature.js +5 -5
- package/lib/cjs/components/signature/editForm/Signature.edit.display.d.ts +0 -6
- package/lib/cjs/components/signature/editForm/Signature.edit.display.js +0 -1
- package/lib/cjs/components/table/editForm/Table.edit.display.d.ts +27 -0
- package/lib/cjs/components/table/editForm/Table.edit.display.js +10 -0
- package/lib/cjs/formio.form.js +2 -5
- package/lib/cjs/package.json +1 -1
- package/lib/cjs/providers/storage/azure.js +9 -3
- package/lib/cjs/templates/index.d.ts +3 -0
- package/lib/cjs/translations/en.d.ts +2 -0
- package/lib/cjs/translations/en.js +2 -0
- package/lib/cjs/utils/i18n.d.ts +1 -0
- package/lib/cjs/utils/i18n.js +2 -0
- package/lib/cjs/utils/index.d.ts +1 -1
- package/lib/cjs/utils/utils.d.ts +1 -1
- package/lib/cjs/utils/utils.js +23 -6
- package/lib/cjs/widgets/CalendarWidget.js +1 -1
- package/lib/mjs/Embed.js +26 -1
- package/lib/mjs/Form.d.ts +4 -2
- package/lib/mjs/Form.js +2 -2
- package/lib/mjs/FormBuilder.d.ts +2 -2
- package/lib/mjs/FormBuilder.js +1 -1
- package/lib/mjs/Formio.js +1 -1
- package/lib/mjs/PDF.js +2 -0
- package/lib/mjs/PDFBuilder.js +6 -1
- package/lib/mjs/Webform.d.ts +1 -0
- package/lib/mjs/Webform.js +48 -1
- package/lib/mjs/WebformBuilder.js +28 -1
- package/lib/mjs/Wizard.d.ts +1 -0
- package/lib/mjs/Wizard.js +12 -1
- package/lib/mjs/components/Components.d.ts +3 -0
- package/lib/mjs/components/_classes/component/Component.d.ts +13 -3
- package/lib/mjs/components/_classes/component/Component.js +164 -46
- package/lib/mjs/components/_classes/component/editForm/Component.edit.conditional.js +1 -1
- package/lib/mjs/components/_classes/component/editForm/Component.edit.data.d.ts +7 -0
- package/lib/mjs/components/_classes/component/editForm/Component.edit.data.js +2 -1
- package/lib/mjs/components/_classes/component/editForm/utils.d.ts +1 -0
- package/lib/mjs/components/_classes/component/editForm/utils.js +3 -0
- package/lib/mjs/components/_classes/nested/NestedComponent.js +5 -0
- package/lib/mjs/components/address/Address.js +17 -0
- package/lib/mjs/components/datagrid/DataGrid.js +14 -1
- package/lib/mjs/components/datamap/DataMap.d.ts +1 -0
- package/lib/mjs/components/datamap/DataMap.js +36 -4
- package/lib/mjs/components/datetime/DateTime.js +11 -1
- package/lib/mjs/components/day/Day.d.ts +0 -15
- package/lib/mjs/components/day/Day.js +8 -17
- package/lib/mjs/components/editgrid/EditGrid.js +11 -1
- package/lib/mjs/components/fieldset/Fieldset.js +1 -0
- package/lib/mjs/components/file/File.d.ts +3 -1
- package/lib/mjs/components/file/File.js +60 -15
- package/lib/mjs/components/form/Form.js +3 -1
- package/lib/mjs/components/number/Number.d.ts +1 -0
- package/lib/mjs/components/number/Number.js +17 -0
- package/lib/mjs/components/select/Select.js +5 -1
- package/lib/mjs/components/signature/Signature.js +1 -1
- package/lib/mjs/components/signature/editForm/Signature.edit.display.d.ts +0 -6
- package/lib/mjs/components/signature/editForm/Signature.edit.display.js +0 -1
- package/lib/mjs/components/table/editForm/Table.edit.display.d.ts +27 -0
- package/lib/mjs/components/table/editForm/Table.edit.display.js +10 -0
- package/lib/mjs/formio.form.js +4 -7
- package/lib/mjs/package.json +1 -1
- package/lib/mjs/providers/storage/azure.js +9 -3
- package/lib/mjs/templates/index.d.ts +3 -0
- package/lib/mjs/translations/en.d.ts +2 -0
- package/lib/mjs/translations/en.js +2 -0
- package/lib/mjs/utils/i18n.d.ts +1 -0
- package/lib/mjs/utils/i18n.js +2 -0
- package/lib/mjs/utils/index.d.ts +1 -1
- package/lib/mjs/utils/utils.d.ts +1 -1
- package/lib/mjs/utils/utils.js +22 -6
- package/lib/mjs/widgets/CalendarWidget.js +2 -2
- package/package.json +8 -6
package/lib/cjs/utils/utils.js
CHANGED
|
@@ -206,6 +206,7 @@ function checkSimpleConditional(component, condition, row, data, instance) {
|
|
|
206
206
|
return true;
|
|
207
207
|
}
|
|
208
208
|
const conditionsResult = lodash_1.default.map(conditions, (cond) => {
|
|
209
|
+
var _a;
|
|
209
210
|
const { value: comparedValue, operator, component: conditionComponentPath } = cond;
|
|
210
211
|
if (!conditionComponentPath) {
|
|
211
212
|
return true;
|
|
@@ -232,6 +233,16 @@ function checkSimpleConditional(component, condition, row, data, instance) {
|
|
|
232
233
|
}
|
|
233
234
|
else {
|
|
234
235
|
const value = getComponentActualValue(conditionComponentPath, data, row);
|
|
236
|
+
// When inside a DataGrid/EditGrid, construct a row-indexed path so that
|
|
237
|
+
// operators like isEmpty can look up the correct row's component instance.
|
|
238
|
+
let operatorPath = conditionComponentPath;
|
|
239
|
+
const dataParent = getDataParentComponent(instance);
|
|
240
|
+
if (dataParent && !lodash_1.default.isNil(instance === null || instance === void 0 ? void 0 : instance.rowIndex)) {
|
|
241
|
+
const parentPath = (_a = dataParent.paths) === null || _a === void 0 ? void 0 : _a.localPath;
|
|
242
|
+
if (parentPath && conditionComponentPath.startsWith(`${parentPath}.`)) {
|
|
243
|
+
operatorPath = conditionComponentPath.replace(`${parentPath}.`, `${parentPath}[${instance.rowIndex}].`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
235
246
|
const СonditionOperator = conditionOperators_1.default[operator];
|
|
236
247
|
return СonditionOperator
|
|
237
248
|
? new СonditionOperator().getResult({
|
|
@@ -239,7 +250,7 @@ function checkSimpleConditional(component, condition, row, data, instance) {
|
|
|
239
250
|
comparedValue,
|
|
240
251
|
instance,
|
|
241
252
|
component,
|
|
242
|
-
path:
|
|
253
|
+
path: operatorPath,
|
|
243
254
|
})
|
|
244
255
|
: true;
|
|
245
256
|
}
|
|
@@ -292,7 +303,11 @@ exports.getComponentActualValue = getComponentActualValue;
|
|
|
292
303
|
*/
|
|
293
304
|
function checkCustomConditional(component, custom, row, data, form, variable, onError, instance) {
|
|
294
305
|
if (typeof custom === 'string') {
|
|
295
|
-
custom = `
|
|
306
|
+
custom = `
|
|
307
|
+
var ${variable} = true;
|
|
308
|
+
${custom};
|
|
309
|
+
return ${variable};
|
|
310
|
+
`;
|
|
296
311
|
}
|
|
297
312
|
const value = instance && instance.evaluate
|
|
298
313
|
? instance.evaluate(custom, { row, data, form })
|
|
@@ -640,14 +655,16 @@ exports.shouldLoadZones = shouldLoadZones;
|
|
|
640
655
|
* @param {string} timezone - The timezone to load.
|
|
641
656
|
* @returns {Promise<any> | *} - Resolves when the zones for this timezone are loaded.
|
|
642
657
|
*/
|
|
643
|
-
function loadZones(url,
|
|
644
|
-
if (
|
|
645
|
-
|
|
646
|
-
return new Promise(lodash_1.default.noop);
|
|
658
|
+
function loadZones(url, _timezone) {
|
|
659
|
+
if (moment_timezone_1.default.zonesLoaded) {
|
|
660
|
+
return Promise.resolve();
|
|
647
661
|
}
|
|
648
662
|
if (moment_timezone_1.default.zonesPromise) {
|
|
649
663
|
return moment_timezone_1.default.zonesPromise;
|
|
650
664
|
}
|
|
665
|
+
// Always load the full packed dataset once. The previous optimization skipped fetch when the
|
|
666
|
+
// display timezone matched the runtime zone, but moment-timezone still needs `tz.load()` for
|
|
667
|
+
// `.tz(ianaName)` and `z` formatting to work; otherwise conversions silently match server local time.
|
|
651
668
|
return (moment_timezone_1.default.zonesPromise = fetch(url).then((resp) => resp.json().then((zones) => {
|
|
652
669
|
moment_timezone_1.default.tz.load(zones);
|
|
653
670
|
moment_timezone_1.default.zonesLoaded = true;
|
|
@@ -61,7 +61,7 @@ class CalendarWidget extends InputWidget_1.default {
|
|
|
61
61
|
if (this.zoneLoading) {
|
|
62
62
|
return true;
|
|
63
63
|
}
|
|
64
|
-
if (!(0, utils_1.zonesLoaded)()
|
|
64
|
+
if (!(0, utils_1.zonesLoaded)()) {
|
|
65
65
|
this.zoneLoading = true;
|
|
66
66
|
(0, utils_1.loadZones)(this.timezonesUrl, timezone).then(() => {
|
|
67
67
|
this.zoneLoading = false;
|
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.4.0';
|
|
18
18
|
static setLicense(license, norecurse = false) {
|
|
19
19
|
Formio.license = license;
|
|
20
20
|
if (!norecurse && Formio.FormioClass) {
|
|
@@ -340,6 +340,24 @@ export class Formio {
|
|
|
340
340
|
};
|
|
341
341
|
});
|
|
342
342
|
const id = Formio.config.id || `formio-${Math.random().toString(36).substring(7)}`;
|
|
343
|
+
const hasQuillComponent = (components = []) => {
|
|
344
|
+
if (!Array.isArray(components)) {
|
|
345
|
+
return false;
|
|
346
|
+
}
|
|
347
|
+
return components.some((component) => {
|
|
348
|
+
if (!component || typeof component !== 'object') {
|
|
349
|
+
return false;
|
|
350
|
+
}
|
|
351
|
+
const isQuillTextarea = component.type === 'textarea' &&
|
|
352
|
+
component.wysiwyg === true &&
|
|
353
|
+
component.editor === 'quill';
|
|
354
|
+
return (isQuillTextarea ||
|
|
355
|
+
hasQuillComponent(component.components) ||
|
|
356
|
+
hasQuillComponent(component.columns?.flatMap((column) => column.components || [])) ||
|
|
357
|
+
hasQuillComponent(component.rows?.flatMap((row) => row.flatMap((cell) => cell.components || []))));
|
|
358
|
+
});
|
|
359
|
+
};
|
|
360
|
+
const disableShadowForQuill = hasQuillComponent(Formio.config.form?.components);
|
|
343
361
|
// Create a new wrapper and add the element inside of a new wrapper.
|
|
344
362
|
let wrapper = Formio.createElement('div', {
|
|
345
363
|
id: `${id}-wrapper`,
|
|
@@ -348,12 +366,19 @@ export class Formio {
|
|
|
348
366
|
// If we include the libraries, then we will attempt to run this in shadow dom.
|
|
349
367
|
const useShadowDom = Formio.config.includeLibs &&
|
|
350
368
|
!Formio.config.noshadow &&
|
|
369
|
+
!disableShadowForQuill &&
|
|
351
370
|
typeof wrapper.attachShadow === 'function';
|
|
352
371
|
if (useShadowDom) {
|
|
353
372
|
wrapper = wrapper.attachShadow({
|
|
354
373
|
mode: 'open',
|
|
355
374
|
});
|
|
356
375
|
options.shadowRoot = wrapper;
|
|
376
|
+
// Due to an issue with quill not loading styles in the shadowdom, we need to add quill styles and js to the shadowdom
|
|
377
|
+
const quill = {
|
|
378
|
+
js: `${Formio.cdn.quill}/quill.js`,
|
|
379
|
+
css: `${Formio.cdn.quill}/quill.snow.css`
|
|
380
|
+
};
|
|
381
|
+
await Formio.addLibrary(wrapper, quill, 'quill');
|
|
357
382
|
}
|
|
358
383
|
element.parentNode.removeChild(element);
|
|
359
384
|
wrapper.appendChild(element);
|
package/lib/mjs/Form.d.ts
CHANGED
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
* @property {number} [saveDraftThrottle] - The throttle for the save draft feature.
|
|
46
46
|
* @property {boolean} [readOnly] - Set this form to readOnly.
|
|
47
47
|
* @property {boolean} [noAlerts] - Disable the alerts dialog.
|
|
48
|
-
* @property {{[key: string]: string}} [i18n] - The translation file for this rendering.
|
|
48
|
+
* @property {{[key: string]: string} | { translationsUrl: string }} [i18n] - The translation file for this rendering.
|
|
49
49
|
* @property {string} [template] - Custom logic for creation of elements.
|
|
50
50
|
* @property {boolean} [noDefaults] - Exclude default values from the settings.
|
|
51
51
|
* @property {any} [fileService] - The file service for this form.
|
|
@@ -202,6 +202,8 @@ export type FormOptions = {
|
|
|
202
202
|
*/
|
|
203
203
|
i18n?: {
|
|
204
204
|
[key: string]: string;
|
|
205
|
+
} | {
|
|
206
|
+
translationsUrl: string;
|
|
205
207
|
} | undefined;
|
|
206
208
|
/**
|
|
207
209
|
* - Custom logic for creation of elements.
|
|
@@ -236,7 +238,7 @@ export type FormOptions = {
|
|
|
236
238
|
/**
|
|
237
239
|
* - The render mode for this form.
|
|
238
240
|
*/
|
|
239
|
-
renderMode?: "
|
|
241
|
+
renderMode?: "form" | "builder" | "html" | "flat" | "pdf" | undefined;
|
|
240
242
|
/**
|
|
241
243
|
* - Highlight any errors on the form.
|
|
242
244
|
*/
|
package/lib/mjs/Form.js
CHANGED
|
@@ -50,7 +50,7 @@ import FormioUtils from './utils';
|
|
|
50
50
|
* @property {number} [saveDraftThrottle] - The throttle for the save draft feature.
|
|
51
51
|
* @property {boolean} [readOnly] - Set this form to readOnly.
|
|
52
52
|
* @property {boolean} [noAlerts] - Disable the alerts dialog.
|
|
53
|
-
* @property {{[key: string]: string}} [i18n] - The translation file for this rendering.
|
|
53
|
+
* @property {{[key: string]: string} | { translationsUrl: string }} [i18n] - The translation file for this rendering.
|
|
54
54
|
* @property {string} [template] - Custom logic for creation of elements.
|
|
55
55
|
* @property {boolean} [noDefaults] - Exclude default values from the settings.
|
|
56
56
|
* @property {any} [fileService] - The file service for this form.
|
|
@@ -354,7 +354,7 @@ export default class Form extends Element {
|
|
|
354
354
|
return Promise.resolve(this.instance);
|
|
355
355
|
}
|
|
356
356
|
this.form.display = display;
|
|
357
|
-
this.instance.destroy();
|
|
357
|
+
this.instance.destroy(true);
|
|
358
358
|
this.instance = this.create(display);
|
|
359
359
|
return this.setForm(this.form).then(() => {
|
|
360
360
|
this.instance.emit('setDisplay', this.form.display);
|
package/lib/mjs/FormBuilder.d.ts
CHANGED
|
@@ -73,11 +73,11 @@ export default class FormBuilder extends Form {
|
|
|
73
73
|
/**
|
|
74
74
|
* Creates a new form builder.
|
|
75
75
|
* @param {HTMLElement} element - The HTML element to place the form builder.
|
|
76
|
-
* @param {string | object} form - The form to pass to the builder
|
|
76
|
+
* @param {string | object | undefined} form - The form to pass to the builder
|
|
77
77
|
* @param {FormBuilderOptions} options - The options to create this builder.
|
|
78
78
|
* @returns {FormBuilder} - The form builder instance.
|
|
79
79
|
*/
|
|
80
|
-
constructor(element: HTMLElement, form: string | object, options: {
|
|
80
|
+
constructor(element: HTMLElement, form: string | object | undefined, options: {
|
|
81
81
|
/**
|
|
82
82
|
* - An array of "keys" of components that should be disabled within the form builder. Example: ['firstName', 'lastName']
|
|
83
83
|
*/
|
package/lib/mjs/FormBuilder.js
CHANGED
|
@@ -25,7 +25,7 @@ export default class FormBuilder extends Form {
|
|
|
25
25
|
/**
|
|
26
26
|
* Creates a new form builder.
|
|
27
27
|
* @param {HTMLElement} element - The HTML element to place the form builder.
|
|
28
|
-
* @param {string | object} form - The form to pass to the builder
|
|
28
|
+
* @param {string | object | undefined} form - The form to pass to the builder
|
|
29
29
|
* @param {FormBuilderOptions} options - The options to create this builder.
|
|
30
30
|
* @returns {FormBuilder} - The form builder instance.
|
|
31
31
|
*/
|
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.4.0';
|
|
8
8
|
CDN.defaultCDN = FormioCore.version.includes('rc')
|
|
9
9
|
? 'https://cdn.test-form.io'
|
|
10
10
|
: 'https://cdn.form.io';
|
package/lib/mjs/PDF.js
CHANGED
|
@@ -12,9 +12,11 @@ export default class PDF extends Webform {
|
|
|
12
12
|
// Handle an iframe submission.
|
|
13
13
|
this.on('iframe-submission', (submission) => this.setValue(submission, {
|
|
14
14
|
fromIframe: true,
|
|
15
|
+
noDefault: true
|
|
15
16
|
}), true);
|
|
16
17
|
this.on('iframe-change', (submission) => this.setValue(submission, {
|
|
17
18
|
fromIframe: true,
|
|
19
|
+
noDefault: true
|
|
18
20
|
}), true);
|
|
19
21
|
this.on('iframe-getIframePositions', (query) => {
|
|
20
22
|
const iframe = document.getElementById(`iframe-${query.formId}`);
|
package/lib/mjs/PDFBuilder.js
CHANGED
|
@@ -227,7 +227,12 @@ export default class PDFBuilder extends WebformBuilder {
|
|
|
227
227
|
nonFillableConversionUsed: autoConversionComponentsAssigned && result.data.formfields.nonFillableConversionUsed,
|
|
228
228
|
});
|
|
229
229
|
this.emit('pdfUploaded', result.data);
|
|
230
|
-
|
|
230
|
+
if (autoConversionComponentsAssigned) {
|
|
231
|
+
this.rebuild();
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
this.redraw();
|
|
235
|
+
}
|
|
231
236
|
})
|
|
232
237
|
.catch((err) => this.setUploadError(err));
|
|
233
238
|
}
|
package/lib/mjs/Webform.d.ts
CHANGED
|
@@ -372,6 +372,7 @@ declare class Webform extends NestedDataComponent {
|
|
|
372
372
|
submit(before?: boolean, options?: any): Promise<any>;
|
|
373
373
|
submitUrl(URL: any, headers: any): void;
|
|
374
374
|
triggerCaptcha(components?: null): void;
|
|
375
|
+
loadTranslations(): Promise<any>;
|
|
375
376
|
_nosubmit: any;
|
|
376
377
|
get conditions(): any;
|
|
377
378
|
get variables(): any;
|
package/lib/mjs/Webform.js
CHANGED
|
@@ -569,7 +569,9 @@ export default class Webform extends NestedDataComponent {
|
|
|
569
569
|
}
|
|
570
570
|
this.initialized = false;
|
|
571
571
|
const rebuild = this.rebuild() || Promise.resolve();
|
|
572
|
-
return
|
|
572
|
+
return this.loadTranslations()
|
|
573
|
+
.then(() => rebuild)
|
|
574
|
+
.then(() => {
|
|
573
575
|
this.emit('formLoad', form);
|
|
574
576
|
if (!this.options.server) {
|
|
575
577
|
this.triggerCaptcha();
|
|
@@ -1115,6 +1117,7 @@ export default class Webform extends NestedDataComponent {
|
|
|
1115
1117
|
this.setPristine(true);
|
|
1116
1118
|
// We want to return the submitted submission and setValue will mutate the submission so cloneDeep it here.
|
|
1117
1119
|
this.setValue(fastCloneDeep(submission), {
|
|
1120
|
+
noDefault: true,
|
|
1118
1121
|
noValidate: true,
|
|
1119
1122
|
noCheck: true,
|
|
1120
1123
|
});
|
|
@@ -1288,6 +1291,7 @@ export default class Webform extends NestedDataComponent {
|
|
|
1288
1291
|
userAgent: navigator.userAgent,
|
|
1289
1292
|
pathName: window.location.pathname,
|
|
1290
1293
|
onLine: navigator.onLine,
|
|
1294
|
+
language: this.i18next?.originalLanguage || this.options.language || this.i18next?.language,
|
|
1291
1295
|
});
|
|
1292
1296
|
}
|
|
1293
1297
|
submitForm(options = {}, local = false) {
|
|
@@ -1517,6 +1521,49 @@ export default class Webform extends NestedDataComponent {
|
|
|
1517
1521
|
captchaComponent[0].verify(`${this.form.name ? this.form.name : 'form'}Load`);
|
|
1518
1522
|
}
|
|
1519
1523
|
}
|
|
1524
|
+
loadTranslations() {
|
|
1525
|
+
// We only need a resolve since if translations cannot load, we still want to proceed and render the for
|
|
1526
|
+
let translationsLoadResolve;
|
|
1527
|
+
const promise = new Promise((resolve) => {
|
|
1528
|
+
translationsLoadResolve = resolve;
|
|
1529
|
+
});
|
|
1530
|
+
const translationsUrl = typeof this.options.i18n?.translationsUrl === 'string'
|
|
1531
|
+
? this.options.i18n.translationsUrl
|
|
1532
|
+
: null;
|
|
1533
|
+
if (translationsUrl) {
|
|
1534
|
+
const url = this.sanitize(this.interpolate(translationsUrl, {}), this.shouldSanitizeValue);
|
|
1535
|
+
Formio.makeStaticRequest(url, 'GET')
|
|
1536
|
+
.then((response) => {
|
|
1537
|
+
let languages = response;
|
|
1538
|
+
try {
|
|
1539
|
+
if (typeof languages == 'string') {
|
|
1540
|
+
languages = JSON.parse(languages);
|
|
1541
|
+
}
|
|
1542
|
+
this.i18next.setLanguages(languages);
|
|
1543
|
+
this.i18next.changeLanguage(this.i18next.originalLanguage, (err) => {
|
|
1544
|
+
if (err) {
|
|
1545
|
+
return;
|
|
1546
|
+
}
|
|
1547
|
+
this.emit('languageChanged');
|
|
1548
|
+
});
|
|
1549
|
+
this.redraw();
|
|
1550
|
+
translationsLoadResolve();
|
|
1551
|
+
}
|
|
1552
|
+
catch (err) {
|
|
1553
|
+
console.warn(err.message);
|
|
1554
|
+
translationsLoadResolve();
|
|
1555
|
+
}
|
|
1556
|
+
})
|
|
1557
|
+
.catch((err) => {
|
|
1558
|
+
console.warn(err);
|
|
1559
|
+
translationsLoadResolve();
|
|
1560
|
+
});
|
|
1561
|
+
}
|
|
1562
|
+
else {
|
|
1563
|
+
translationsLoadResolve();
|
|
1564
|
+
}
|
|
1565
|
+
return promise;
|
|
1566
|
+
}
|
|
1520
1567
|
set nosubmit(value) {
|
|
1521
1568
|
this._nosubmit = !!value;
|
|
1522
1569
|
this.emit('nosubmit', this._nosubmit);
|
|
@@ -364,11 +364,14 @@ export default class WebformBuilder extends Component {
|
|
|
364
364
|
this.attachTooltip(component.refs.editComponent, this.t('Edit'));
|
|
365
365
|
component.addEventListener(component.refs.editComponent, 'click', () => this.editComponent(component.schema, parent, false, false, component.component, {
|
|
366
366
|
inDataGrid: component.isInDataGrid,
|
|
367
|
+
editComponentPath: component.path,
|
|
367
368
|
}));
|
|
368
369
|
}
|
|
369
370
|
if (component.refs.editJson) {
|
|
370
371
|
this.attachTooltip(component.refs.editJson, this.t('Edit JSON'));
|
|
371
|
-
component.addEventListener(component.refs.editJson, 'click', () => this.editComponent(component.schema, parent, false, true, component.component
|
|
372
|
+
component.addEventListener(component.refs.editJson, 'click', () => this.editComponent(component.schema, parent, false, true, component.component, {
|
|
373
|
+
editComponentPath: component.path,
|
|
374
|
+
}));
|
|
372
375
|
}
|
|
373
376
|
if (component.refs.removeComponent) {
|
|
374
377
|
this.attachTooltip(component.refs.removeComponent, this.t('Remove'));
|
|
@@ -932,7 +935,22 @@ export default class WebformBuilder extends Component {
|
|
|
932
935
|
rebuild = Promise.resolve();
|
|
933
936
|
}
|
|
934
937
|
return rebuild.then(() => {
|
|
938
|
+
// Get the updated `toIndex` after the component has been inserted/rebuilt
|
|
939
|
+
const toIndex = _.findIndex(target.formioContainer, { key: info.key });
|
|
935
940
|
this.emit('addComponent', info, parent, path, index, isNew && !this.options.noNewEdit && !info.noNewEdit);
|
|
941
|
+
// If this is not a new component — it means it was moved
|
|
942
|
+
if (!isNew) {
|
|
943
|
+
const payload = {
|
|
944
|
+
component: info,
|
|
945
|
+
parent,
|
|
946
|
+
path,
|
|
947
|
+
fromIndex: index,
|
|
948
|
+
toIndex,
|
|
949
|
+
timestamp: new Date()
|
|
950
|
+
};
|
|
951
|
+
// New event that allows explicit tracking of reordering
|
|
952
|
+
this.emit('moveComponent', payload);
|
|
953
|
+
}
|
|
936
954
|
if (!isNew || this.options.noNewEdit || info.noNewEdit) {
|
|
937
955
|
this.emit('change', this.form);
|
|
938
956
|
}
|
|
@@ -1066,6 +1084,14 @@ export default class WebformBuilder extends Component {
|
|
|
1066
1084
|
_.get(this.webform, 'form.globalSettings.sanitizeConfig');
|
|
1067
1085
|
// Update the preview.
|
|
1068
1086
|
if (this.preview) {
|
|
1087
|
+
if (changed?.instance?.key === 'allowMultipleMasks' && changed?.value === false) {
|
|
1088
|
+
const changedComp = this.preview?.getComponent(component.key);
|
|
1089
|
+
if (changedComp) {
|
|
1090
|
+
const emptyValue = changedComp.emptyValue;
|
|
1091
|
+
changedComp.dataValue = emptyValue;
|
|
1092
|
+
component.defaultValue = emptyValue;
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1069
1095
|
this.preview.form = {
|
|
1070
1096
|
components: [
|
|
1071
1097
|
_.omit({ ...component }, [
|
|
@@ -1381,6 +1407,7 @@ export default class WebformBuilder extends Component {
|
|
|
1381
1407
|
// Pass along the form being edited.
|
|
1382
1408
|
editFormOptions.editForm = this.form;
|
|
1383
1409
|
editFormOptions.editComponent = component;
|
|
1410
|
+
editFormOptions.editComponentPath = flags.editComponentPath;
|
|
1384
1411
|
editFormOptions.flags = flags;
|
|
1385
1412
|
this.hook('editComponentParentInstance', editFormOptions, parent);
|
|
1386
1413
|
this.editForm = new Webform({
|
package/lib/mjs/Wizard.d.ts
CHANGED
|
@@ -90,6 +90,7 @@ declare class Wizard extends Webform {
|
|
|
90
90
|
nextPage(): Promise<void>;
|
|
91
91
|
validateCurrentPage(flags?: {}): any;
|
|
92
92
|
emitPrevPage(): void;
|
|
93
|
+
announceCurrentPage(): void;
|
|
93
94
|
prevPage(): Promise<void>;
|
|
94
95
|
cancel(noconfirm: any): Promise<void> | Promise<number>;
|
|
95
96
|
getPageIndexByKey(key: any): number;
|
package/lib/mjs/Wizard.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
2
|
import Webform from './Webform';
|
|
3
3
|
import { Formio } from './Formio';
|
|
4
|
-
import { fastCloneDeep, checkCondition, firstNonNil, uniqueKey, eachComponent } from './utils';
|
|
4
|
+
import { fastCloneDeep, checkCondition, firstNonNil, uniqueKey, eachComponent, screenReaderSpeech } from './utils';
|
|
5
5
|
export default class Wizard extends Webform {
|
|
6
6
|
/**
|
|
7
7
|
* Constructor for wizard-based forms.
|
|
@@ -701,6 +701,7 @@ export default class Wizard extends Webform {
|
|
|
701
701
|
}
|
|
702
702
|
emitNextPage() {
|
|
703
703
|
this.emit('nextPage', { page: this.page, submission: this.submission });
|
|
704
|
+
this.announceCurrentPage();
|
|
704
705
|
}
|
|
705
706
|
nextPage() {
|
|
706
707
|
// Read-only forms should not worry about validation before going to next page, nor should they submit.
|
|
@@ -745,6 +746,16 @@ export default class Wizard extends Webform {
|
|
|
745
746
|
}
|
|
746
747
|
emitPrevPage() {
|
|
747
748
|
this.emit('prevPage', { page: this.page, submission: this.submission });
|
|
749
|
+
this.announceCurrentPage();
|
|
750
|
+
}
|
|
751
|
+
announceCurrentPage() {
|
|
752
|
+
if (_.get(this.form, 'settings.wizardHeaderType', '') === 'StepIndicator') {
|
|
753
|
+
screenReaderSpeech(`Now on step ${this.page + 1} of ${this.pages.length}: ${_.get(this.currentPage, 'component.title')}`);
|
|
754
|
+
const currentLink = _.get(this.refs, `${this.wizardKey}-link.[${this.page}]`);
|
|
755
|
+
if (currentLink) {
|
|
756
|
+
currentLink.focus();
|
|
757
|
+
}
|
|
758
|
+
}
|
|
748
759
|
}
|
|
749
760
|
prevPage() {
|
|
750
761
|
return this.beforePage().then(() => {
|
|
@@ -2,6 +2,7 @@ export default class Components {
|
|
|
2
2
|
static _editFormUtils: {
|
|
3
3
|
sortAndFilterComponents(components: any): any;
|
|
4
4
|
unifyComponents(objValue: any, srcValue: any): any;
|
|
5
|
+
tokenVariableDescription(): string;
|
|
5
6
|
logicVariablesTable(additional: any): {
|
|
6
7
|
type: string;
|
|
7
8
|
tag: string;
|
|
@@ -86,6 +87,7 @@ export default class Components {
|
|
|
86
87
|
static set EditFormUtils(value: {
|
|
87
88
|
sortAndFilterComponents(components: any): any;
|
|
88
89
|
unifyComponents(objValue: any, srcValue: any): any;
|
|
90
|
+
tokenVariableDescription(): string;
|
|
89
91
|
logicVariablesTable(additional: any): {
|
|
90
92
|
type: string;
|
|
91
93
|
tag: string;
|
|
@@ -169,6 +171,7 @@ export default class Components {
|
|
|
169
171
|
static get EditFormUtils(): {
|
|
170
172
|
sortAndFilterComponents(components: any): any;
|
|
171
173
|
unifyComponents(objValue: any, srcValue: any): any;
|
|
174
|
+
tokenVariableDescription(): string;
|
|
172
175
|
logicVariablesTable(additional: any): {
|
|
173
176
|
type: string;
|
|
174
177
|
tag: string;
|
|
@@ -177,6 +177,7 @@ declare class Component extends Element {
|
|
|
177
177
|
* @returns {boolean} - If the parent should conditionally clear.
|
|
178
178
|
*/
|
|
179
179
|
parentShouldConditionallyClear(): boolean;
|
|
180
|
+
hasCondionallyHiddenLayoutParent(): boolean;
|
|
180
181
|
parentConditionallyHidden(): boolean;
|
|
181
182
|
/**
|
|
182
183
|
* Returns true if any of the parents default their component "hidden" property to true.
|
|
@@ -593,6 +594,15 @@ declare class Component extends Element {
|
|
|
593
594
|
* @returns {string} - The custom style
|
|
594
595
|
*/
|
|
595
596
|
get customStyle(): string;
|
|
597
|
+
/**
|
|
598
|
+
* Build custom styles from the styles form option or global config.
|
|
599
|
+
* @param {string[]} templateNames - The possible template names.
|
|
600
|
+
* @returns {{ [refName: string]: string[] }} - The custom styles object for the named template.
|
|
601
|
+
* @todo - Rename this to a better method name that doesn't clash
|
|
602
|
+
*/
|
|
603
|
+
getCustomStyles(templateNames: string[]): {
|
|
604
|
+
[refName: string]: string[];
|
|
605
|
+
};
|
|
596
606
|
/**
|
|
597
607
|
* Returns if the application is on a mobile device.
|
|
598
608
|
* @returns {boolean} - TRUE if the application is on a mobile device.
|
|
@@ -927,9 +937,9 @@ declare class Component extends Element {
|
|
|
927
937
|
*/
|
|
928
938
|
get hasDefaultValue(): boolean;
|
|
929
939
|
/**
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
940
|
+
* Determine if we should add a default value for this component.
|
|
941
|
+
* @returns {boolean} - TRUE if a default value should be set
|
|
942
|
+
*/
|
|
933
943
|
get shouldAddDefaultValue(): boolean;
|
|
934
944
|
/**
|
|
935
945
|
* Get the default value of this component.
|