@formio/js 5.3.0 → 5.4.0-api98.1
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 +16 -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 +16 -5
- package/dist/formio.form.js +3234 -3226
- 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 -3
- package/dist/formio.full.css +16 -5
- package/dist/formio.full.js +3961 -3933
- 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 -3
- package/dist/formio.js +1485 -1487
- package/dist/formio.min.js +1 -1
- package/dist/formio.min.js.LICENSE.txt +1 -1
- package/dist/formio.utils.js +1402 -1415
- package/dist/formio.utils.min.js +1 -1
- package/dist/formio.utils.min.js.LICENSE.txt +1 -3
- package/lib/cjs/Embed.js +35 -1
- package/lib/cjs/Form.d.ts +3 -1
- 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 +11 -1
- package/lib/cjs/Webform.d.ts +2 -1
- package/lib/cjs/Webform.js +77 -2
- package/lib/cjs/WebformBuilder.js +15 -0
- package/lib/cjs/Wizard.d.ts +1 -0
- package/lib/cjs/Wizard.js +11 -0
- package/lib/cjs/components/_classes/component/Component.d.ts +14 -3
- package/lib/cjs/components/_classes/component/Component.js +91 -24
- 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 +1 -0
- package/lib/cjs/components/_classes/input/Input.js +17 -2
- package/lib/cjs/components/_classes/nested/NestedComponent.js +5 -0
- package/lib/cjs/components/address/Address.js +18 -1
- package/lib/cjs/components/datagrid/DataGrid.js +14 -3
- package/lib/cjs/components/datamap/DataMap.d.ts +4 -0
- package/lib/cjs/components/datamap/DataMap.js +6 -5
- package/lib/cjs/components/fieldset/Fieldset.d.ts +1 -0
- package/lib/cjs/components/fieldset/Fieldset.js +8 -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 +2 -1
- package/lib/cjs/components/select/Select.js +14 -9
- 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/components/tags/Tags.js +2 -1
- package/lib/cjs/package.json +1 -1
- 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/conditionOperators/IsEqualTo.d.ts +1 -3
- package/lib/cjs/utils/conditionOperators/IsEqualTo.js +6 -12
- package/lib/cjs/utils/conditionOperators/index.d.ts +2 -1
- package/lib/cjs/utils/i18n.d.ts +1 -0
- package/lib/cjs/utils/i18n.js +2 -0
- package/lib/cjs/utils/index.d.ts +2 -1
- package/lib/cjs/utils/utils.d.ts +9 -0
- package/lib/cjs/utils/utils.js +132 -2
- package/lib/cjs/widgets/CalendarWidget.js +2 -1
- package/lib/mjs/Embed.js +35 -1
- package/lib/mjs/Form.d.ts +3 -1
- 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 +11 -1
- package/lib/mjs/Webform.d.ts +2 -1
- package/lib/mjs/Webform.js +76 -2
- package/lib/mjs/WebformBuilder.js +15 -0
- package/lib/mjs/Wizard.d.ts +1 -0
- package/lib/mjs/Wizard.js +12 -1
- package/lib/mjs/components/_classes/component/Component.d.ts +14 -3
- package/lib/mjs/components/_classes/component/Component.js +87 -24
- 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 +1 -0
- package/lib/mjs/components/_classes/input/Input.js +16 -3
- package/lib/mjs/components/_classes/nested/NestedComponent.js +5 -0
- package/lib/mjs/components/address/Address.js +16 -1
- package/lib/mjs/components/datagrid/DataGrid.js +12 -2
- package/lib/mjs/components/datamap/DataMap.d.ts +4 -0
- package/lib/mjs/components/datamap/DataMap.js +6 -5
- package/lib/mjs/components/fieldset/Fieldset.d.ts +1 -0
- package/lib/mjs/components/fieldset/Fieldset.js +8 -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 +2 -1
- package/lib/mjs/components/select/Select.js +12 -9
- 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/components/tags/Tags.js +1 -1
- package/lib/mjs/package.json +1 -1
- 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/conditionOperators/IsEqualTo.d.ts +1 -3
- package/lib/mjs/utils/conditionOperators/IsEqualTo.js +6 -11
- package/lib/mjs/utils/conditionOperators/index.d.ts +2 -1
- package/lib/mjs/utils/i18n.d.ts +1 -0
- package/lib/mjs/utils/i18n.js +2 -0
- package/lib/mjs/utils/index.d.ts +2 -1
- package/lib/mjs/utils/utils.d.ts +9 -0
- package/lib/mjs/utils/utils.js +130 -1
- package/lib/mjs/widgets/CalendarWidget.js +1 -1
- package/package.json +5 -4
|
@@ -78,4 +78,6 @@ exports.default = {
|
|
|
78
78
|
requiredDayEmpty: '{{ field }} is required',
|
|
79
79
|
requiredMonthField: '{{ field }} is required',
|
|
80
80
|
requiredYearField: '{{ field }} is required',
|
|
81
|
+
fileTooSmall: 'File is too small; it must be at least {{ size }}',
|
|
82
|
+
fileTooBig: 'File is too big; it must be at most {{ size }}'
|
|
81
83
|
};
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
export default class IsEqualTo extends ConditionOperator {
|
|
2
|
-
execute({ value, comparedValue
|
|
2
|
+
execute({ value, comparedValue }: {
|
|
3
3
|
value: any;
|
|
4
4
|
comparedValue: any;
|
|
5
|
-
instance: any;
|
|
6
|
-
path: any;
|
|
7
5
|
}): any;
|
|
8
6
|
}
|
|
9
7
|
import ConditionOperator from './ConditionOperator';
|
|
@@ -5,7 +5,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const ConditionOperator_1 = __importDefault(require("./ConditionOperator"));
|
|
7
7
|
const lodash_1 = __importDefault(require("lodash"));
|
|
8
|
-
const __1 = require("../");
|
|
9
8
|
class IsEqualTo extends ConditionOperator_1.default {
|
|
10
9
|
static get operatorKey() {
|
|
11
10
|
return 'isEqual';
|
|
@@ -13,8 +12,7 @@ class IsEqualTo extends ConditionOperator_1.default {
|
|
|
13
12
|
static get displayedName() {
|
|
14
13
|
return 'Is Equal To';
|
|
15
14
|
}
|
|
16
|
-
execute({ value, comparedValue
|
|
17
|
-
var _a, _b;
|
|
15
|
+
execute({ value, comparedValue }) {
|
|
18
16
|
if ((value || value === false) &&
|
|
19
17
|
comparedValue &&
|
|
20
18
|
typeof value !== typeof comparedValue &&
|
|
@@ -26,19 +24,15 @@ class IsEqualTo extends ConditionOperator_1.default {
|
|
|
26
24
|
// ignore
|
|
27
25
|
}
|
|
28
26
|
}
|
|
29
|
-
if ((_a = instance === null || instance === void 0 ? void 0 : instance.root) === null || _a === void 0 ? void 0 : _a.getComponent) {
|
|
30
|
-
const conditionTriggerComponent = instance.root.getComponent(path);
|
|
31
|
-
if (conditionTriggerComponent &&
|
|
32
|
-
(0, __1.isSelectResourceWithObjectValue)(conditionTriggerComponent.component) &&
|
|
33
|
-
((_b = conditionTriggerComponent.component) === null || _b === void 0 ? void 0 : _b.template)) {
|
|
34
|
-
return (0, __1.compareSelectResourceWithObjectTypeValues)(value, comparedValue, conditionTriggerComponent.component);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
27
|
//special check for select boxes
|
|
38
28
|
if (lodash_1.default.isObject(value) && comparedValue && lodash_1.default.isBoolean(value[comparedValue])) {
|
|
39
29
|
return value[comparedValue];
|
|
40
30
|
}
|
|
41
|
-
|
|
31
|
+
const valuesAreObjects = typeof comparedValue === 'object' &&
|
|
32
|
+
comparedValue !== null &&
|
|
33
|
+
typeof value === 'object' &&
|
|
34
|
+
value !== null;
|
|
35
|
+
return valuesAreObjects ? lodash_1.default.isMatch(value, comparedValue) : lodash_1.default.isEqual(comparedValue, value);
|
|
42
36
|
}
|
|
43
37
|
}
|
|
44
38
|
exports.default = IsEqualTo;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export default ConditionOperators;
|
|
2
2
|
declare const ConditionOperators: {
|
|
3
|
-
[x: string]: typeof IsEqualTo | typeof DateGreaterThan;
|
|
3
|
+
[x: string]: typeof IsEqualTo | typeof IsEmptyValue | typeof DateGreaterThan;
|
|
4
4
|
};
|
|
5
5
|
import IsEqualTo from './IsEqualTo';
|
|
6
|
+
import IsEmptyValue from './IsEmptyValue';
|
|
6
7
|
import DateGreaterThan from './DateGreaterThan';
|
package/lib/cjs/utils/i18n.d.ts
CHANGED
package/lib/cjs/utils/i18n.js
CHANGED
|
@@ -19,6 +19,7 @@ class I18n {
|
|
|
19
19
|
constructor(languages = {}) {
|
|
20
20
|
this.languages = i18Defaults;
|
|
21
21
|
this.language = 'en';
|
|
22
|
+
this.originalLanguage = 'en';
|
|
22
23
|
this.currentLanguage = i18Defaults.en;
|
|
23
24
|
this.setLanguages(languages);
|
|
24
25
|
this.changeLanguage(this.language);
|
|
@@ -72,6 +73,7 @@ class I18n {
|
|
|
72
73
|
return new I18n();
|
|
73
74
|
}
|
|
74
75
|
changeLanguage(language, ready = null) {
|
|
76
|
+
this.originalLanguage = language;
|
|
75
77
|
if (!this.languages[language]) {
|
|
76
78
|
language = 'en';
|
|
77
79
|
}
|
package/lib/cjs/utils/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ declare const FormioUtils: {
|
|
|
5
5
|
Evaluator: DefaultEvaluator;
|
|
6
6
|
interpolate: typeof interpolate;
|
|
7
7
|
ConditionOperators: {
|
|
8
|
-
[x: string]: typeof import("./conditionOperators/IsEqualTo").default | typeof import("./conditionOperators/DateGreaterThan").default;
|
|
8
|
+
[x: string]: typeof import("./conditionOperators/IsEqualTo").default | typeof import("./conditionOperators/IsEmptyValue").default | typeof import("./conditionOperators/DateGreaterThan").default;
|
|
9
9
|
};
|
|
10
10
|
_: any;
|
|
11
11
|
moment: typeof moment;
|
|
@@ -150,6 +150,7 @@ declare const FormioUtils: {
|
|
|
150
150
|
getFocusableElements(element: HTMLElement): NodeList<HTMLElement>;
|
|
151
151
|
getComponentSavedTypes(fullSchema: import("@formio/core").Component): string[] | null;
|
|
152
152
|
hasEncodedTimezone(value: string): boolean;
|
|
153
|
+
announceScreenReaderMessage(component: any, value: any, index?: any, forFocus?: any): undefined;
|
|
153
154
|
screenReaderSpeech(text: string): void;
|
|
154
155
|
firstNonNil: any;
|
|
155
156
|
componentValueTypes: {
|
package/lib/cjs/utils/utils.d.ts
CHANGED
|
@@ -499,6 +499,15 @@ export function getComponentSavedTypes(fullSchema: import('@formio/core').Compon
|
|
|
499
499
|
* @returns {boolean} if value has encoded timezone
|
|
500
500
|
*/
|
|
501
501
|
export function hasEncodedTimezone(value: string): boolean;
|
|
502
|
+
/**
|
|
503
|
+
* The function for announcing messages via a screen reader
|
|
504
|
+
* @param {component} component - The component instance
|
|
505
|
+
* @param {value} value - The current component value
|
|
506
|
+
* @param {index} index - The component index
|
|
507
|
+
* @param {forFocus} forFocus - Whether the component is focused or not
|
|
508
|
+
* @returns {undefined}
|
|
509
|
+
*/
|
|
510
|
+
export function announceScreenReaderMessage(component: any, value: any, index?: any, forFocus?: any): undefined;
|
|
502
511
|
/**
|
|
503
512
|
* Outputs text to screen reader
|
|
504
513
|
* @param {string} text The text to output to screen readers
|
package/lib/cjs/utils/utils.js
CHANGED
|
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getContextComponents = exports.observeOverload = exports.withSwitch = exports.firstNonNil = exports.unfold = exports.bootstrapVersion = exports.uniqueKey = exports.iterateKey = exports.delay = exports.fieldData = exports.getCurrencyAffixes = exports.getNumberDecimalLimit = exports.getNumberSeparators = exports.matchInputMask = exports.unmaskValue = exports.getInputMask = exports.convertFormatToMask = exports.convertFormatToMoment = exports.convertFormatToFlatpickr = exports.getLocaleDateFormatInfo = exports.formatOffset = exports.formatDate = exports.momentDate = exports.loadZones = exports.shouldLoadZones = exports.zonesLoaded = exports.offsetDate = exports.currentTimezone = exports.isValidDate = exports.getDateSetting = exports.guid = exports.uniqueName = exports.convertStringToHTMLElement = exports.unescapeHTML = exports.removeHTML = exports.setActionProperty = exports.checkTrigger = exports.checkCondition = exports.checkJsonConditional = exports.checkCustomConditional = exports.getComponentActualValue = exports.checkSimpleConditional = exports.checkCalculated = exports.isMongoId = exports.boolValue = exports.getScriptPlugin = exports.getElementRect = exports.getPropertyValue = exports.getRandomComponentId = exports.evaluate = void 0;
|
|
7
|
-
exports.screenReaderSpeech = exports.hasEncodedTimezone = exports.interpolateErrors = exports.getComponentSavedTypes = exports.componentValueTypes = exports.getFocusableElements = exports.isPromise = exports.getDataParentComponent = exports.getComponentPath = exports.getComponentPathWithoutIndicies = exports.getBrowserInfo = exports.getIEBrowserVersion = exports.round = exports.getStringFromComponentPath = exports.isChildOf = exports.getArrayFromComponentPath = exports.isInputComponent = exports.fastCloneDeep = exports.sanitize = exports.translateHTMLTemplate = exports.getContextButtons = void 0;
|
|
7
|
+
exports.screenReaderSpeech = exports.announceScreenReaderMessage = exports.hasEncodedTimezone = exports.interpolateErrors = exports.getComponentSavedTypes = exports.componentValueTypes = exports.getFocusableElements = exports.isPromise = exports.getDataParentComponent = exports.getComponentPath = exports.getComponentPathWithoutIndicies = exports.getBrowserInfo = exports.getIEBrowserVersion = exports.round = exports.getStringFromComponentPath = exports.isChildOf = exports.getArrayFromComponentPath = exports.isInputComponent = exports.fastCloneDeep = exports.sanitize = exports.translateHTMLTemplate = exports.getContextButtons = void 0;
|
|
8
8
|
const lodash_1 = __importDefault(require("lodash"));
|
|
9
9
|
const moment_timezone_1 = __importDefault(require("moment-timezone/moment-timezone"));
|
|
10
10
|
const jstimezonedetect_1 = __importDefault(require("jstimezonedetect"));
|
|
@@ -150,7 +150,7 @@ function getConditionalPathsRecursive(conditionPaths, data) {
|
|
|
150
150
|
if (currentData.some((element) => typeof element !== 'object')) {
|
|
151
151
|
return;
|
|
152
152
|
}
|
|
153
|
-
const hasInnerDataArray = currentData.find((x) => Array.isArray(x[conditionPaths[currentLocalIndex]]));
|
|
153
|
+
const hasInnerDataArray = currentData.find((x) => x && conditionPaths && Array.isArray(x[conditionPaths[currentLocalIndex]]));
|
|
154
154
|
if (hasInnerDataArray) {
|
|
155
155
|
currentData.forEach((_, indexOutside) => {
|
|
156
156
|
const innerCompDataPath = `${currentPath}[${indexOutside}].${conditionPaths[currentLocalIndex]}`;
|
|
@@ -1691,6 +1691,136 @@ function hasEncodedTimezone(value) {
|
|
|
1691
1691
|
value.match(/[+|-][0-9]{2}:[0-9]{2}$/));
|
|
1692
1692
|
}
|
|
1693
1693
|
exports.hasEncodedTimezone = hasEncodedTimezone;
|
|
1694
|
+
// Types for min max validation if value = string
|
|
1695
|
+
const TYPES = new Map([["char", "Length"], ["word", "Words"]]);
|
|
1696
|
+
// The number from which the remaining character(words) count message starts being read
|
|
1697
|
+
const REMAIN_COUNT = new Map([["char", 10], ["word", 5]]);
|
|
1698
|
+
function getWordOrCharacterLabel(isWordType, count) {
|
|
1699
|
+
const base = isWordType ? "word" : "character";
|
|
1700
|
+
return Math.abs(count) === 1 ? base : `${base}s`;
|
|
1701
|
+
}
|
|
1702
|
+
/**
|
|
1703
|
+
* The function calculates the message values depending on the type and the current component settings.
|
|
1704
|
+
* @param {component} component - The component instance
|
|
1705
|
+
* @param {type} type - The type of validation max and min
|
|
1706
|
+
* @param {value} value - The current component value
|
|
1707
|
+
* @param {forFocus} forFocus - Whether the component is focused or not
|
|
1708
|
+
* @returns {string} - The messsage string
|
|
1709
|
+
*/
|
|
1710
|
+
function getScreenReaderMessage(component, type, value) {
|
|
1711
|
+
const isWordType = type === "word";
|
|
1712
|
+
const maxKey = typeof value === "string" && (type === "char" || isWordType)
|
|
1713
|
+
? `validate.max${TYPES.get(type)}`
|
|
1714
|
+
: "validate.max";
|
|
1715
|
+
const minKey = typeof value === "string" && (type === "char" || isWordType)
|
|
1716
|
+
? `validate.min${TYPES.get(type)}`
|
|
1717
|
+
: "validate.min";
|
|
1718
|
+
const max = lodash_1.default.parseInt(lodash_1.default.get(component.component, maxKey), 10);
|
|
1719
|
+
const min = lodash_1.default.parseInt(lodash_1.default.get(component.component, minKey), 10);
|
|
1720
|
+
let message = "";
|
|
1721
|
+
if (typeof value === "string") {
|
|
1722
|
+
const currentLength = isWordType ? component.getWordCount(value) : value.length;
|
|
1723
|
+
if (!isNaN(max)) {
|
|
1724
|
+
const remains = max - currentLength;
|
|
1725
|
+
if (value) {
|
|
1726
|
+
const threshold = REMAIN_COUNT.get(type) || max;
|
|
1727
|
+
if (remains > 0 && remains < threshold) {
|
|
1728
|
+
message += `${remains} ${getWordOrCharacterLabel(isWordType, remains)} remaining. `;
|
|
1729
|
+
}
|
|
1730
|
+
else if (remains < 0) {
|
|
1731
|
+
const removeCount = Math.abs(remains);
|
|
1732
|
+
message += `${removeCount} ${getWordOrCharacterLabel(isWordType, removeCount)} should be removed. `;
|
|
1733
|
+
}
|
|
1734
|
+
else if (remains === 0) {
|
|
1735
|
+
message += `No ${getWordOrCharacterLabel(isWordType, 0)} remaining.`;
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
else {
|
|
1739
|
+
message += `Maximum ${max} ${getWordOrCharacterLabel(isWordType, max)}. `;
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
if (!isNaN(min)) {
|
|
1743
|
+
if (value) {
|
|
1744
|
+
const remains = min - currentLength;
|
|
1745
|
+
if (remains > 0) {
|
|
1746
|
+
message += `${remains} ${getWordOrCharacterLabel(isWordType, remains)} should be added.`;
|
|
1747
|
+
}
|
|
1748
|
+
if (remains === 0) {
|
|
1749
|
+
message += ``;
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
else {
|
|
1753
|
+
message += `Minimum ${min} ${getWordOrCharacterLabel(isWordType, min)}. `;
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1757
|
+
else if (typeof value === "number" || value === null) {
|
|
1758
|
+
if (value != null && value !== "") {
|
|
1759
|
+
if (!isNaN(max) && value > max) {
|
|
1760
|
+
message += `Number cannot be greater than ${max}. `;
|
|
1761
|
+
}
|
|
1762
|
+
if (!isNaN(min) && value < min) {
|
|
1763
|
+
message += `Number cannot be less than ${min}.`;
|
|
1764
|
+
}
|
|
1765
|
+
}
|
|
1766
|
+
else {
|
|
1767
|
+
if (!isNaN(min))
|
|
1768
|
+
message += `Minimum value ${min}. `;
|
|
1769
|
+
if (!isNaN(max))
|
|
1770
|
+
message += `Maximum value ${max}. `;
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
return message.trim();
|
|
1774
|
+
}
|
|
1775
|
+
/**
|
|
1776
|
+
* The function for announcing messages via a screen reader
|
|
1777
|
+
* @param {component} component - The component instance
|
|
1778
|
+
* @param {value} value - The current component value
|
|
1779
|
+
* @param {index} index - The component index
|
|
1780
|
+
* @param {forFocus} forFocus - Whether the component is focused or not
|
|
1781
|
+
* @returns {undefined}
|
|
1782
|
+
*/
|
|
1783
|
+
function announceScreenReaderMessage(component, value, index = 0, forFocus = false) {
|
|
1784
|
+
if (typeof value !== "string" && typeof value !== "number" && value !== null) {
|
|
1785
|
+
return;
|
|
1786
|
+
}
|
|
1787
|
+
// The ref for announcing messages
|
|
1788
|
+
const messageSpan = "announceMessage";
|
|
1789
|
+
if (!component.refs[messageSpan])
|
|
1790
|
+
return;
|
|
1791
|
+
const el = component.refs[messageSpan][index];
|
|
1792
|
+
if (!el)
|
|
1793
|
+
return;
|
|
1794
|
+
// Define types for validation
|
|
1795
|
+
const typesToCheck = [];
|
|
1796
|
+
if (typeof value === "string")
|
|
1797
|
+
typesToCheck.push("char", "word");
|
|
1798
|
+
if (typeof value === "number" || value === null)
|
|
1799
|
+
typesToCheck.push("number");
|
|
1800
|
+
// Construct the combined message
|
|
1801
|
+
const combinedMessage = typesToCheck
|
|
1802
|
+
.map(type => getScreenReaderMessage(component, type, value))
|
|
1803
|
+
.filter(msg => msg)
|
|
1804
|
+
.join(" ")
|
|
1805
|
+
.trim();
|
|
1806
|
+
if (forFocus) {
|
|
1807
|
+
setTimeout(() => {
|
|
1808
|
+
el.textContent = "";
|
|
1809
|
+
requestAnimationFrame(() => {
|
|
1810
|
+
el.textContent = combinedMessage;
|
|
1811
|
+
});
|
|
1812
|
+
}, 150);
|
|
1813
|
+
return;
|
|
1814
|
+
}
|
|
1815
|
+
clearTimeout(el._announceTimer);
|
|
1816
|
+
el._announceTimer = setTimeout(() => {
|
|
1817
|
+
el.textContent = "";
|
|
1818
|
+
requestAnimationFrame(() => {
|
|
1819
|
+
el.textContent = combinedMessage;
|
|
1820
|
+
});
|
|
1821
|
+
}, 500);
|
|
1822
|
+
}
|
|
1823
|
+
exports.announceScreenReaderMessage = announceScreenReaderMessage;
|
|
1694
1824
|
/**
|
|
1695
1825
|
* Outputs text to screen reader
|
|
1696
1826
|
* @param {string} text The text to output to screen readers
|
|
@@ -452,7 +452,8 @@ class CalendarWidget extends InputWidget_1.default {
|
|
|
452
452
|
// If other fields are used to calculate disabled dates, we need to redraw calendar to refresh disabled dates
|
|
453
453
|
if (this.settings.disableFunction && this.componentInstance && this.componentInstance.root) {
|
|
454
454
|
this.changeHandler = (e) => {
|
|
455
|
-
|
|
455
|
+
var _a;
|
|
456
|
+
if (e.changed && ((_a = this.calendar) === null || _a === void 0 ? void 0 : _a.config)) {
|
|
456
457
|
this.calendar.redraw();
|
|
457
458
|
}
|
|
458
459
|
};
|
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-api98.1';
|
|
18
18
|
static setLicense(license, norecurse = false) {
|
|
19
19
|
Formio.license = license;
|
|
20
20
|
if (!norecurse && Formio.FormioClass) {
|
|
@@ -148,6 +148,34 @@ export class Formio {
|
|
|
148
148
|
if (successMessage && successMessage.toLowerCase() !== 'false' && instance.element) {
|
|
149
149
|
instance.element.innerHTML = `<div class="alert-success" role="alert">${successMessage}</div>`;
|
|
150
150
|
}
|
|
151
|
+
const announcementMessage = successMessage && successMessage.toLowerCase() !== 'false'
|
|
152
|
+
? successMessage
|
|
153
|
+
: 'Form submission complete';
|
|
154
|
+
let liveRegion = document.getElementById('formio-announcements');
|
|
155
|
+
if (!liveRegion) {
|
|
156
|
+
liveRegion = Formio.createElement('div', {
|
|
157
|
+
id: 'formio-announcements',
|
|
158
|
+
'role': 'status',
|
|
159
|
+
'aria-live': 'polite',
|
|
160
|
+
'aria-atomic': 'true',
|
|
161
|
+
style: 'position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; clip: rect(0, 0, 0, 0);'
|
|
162
|
+
});
|
|
163
|
+
document.body.appendChild(liveRegion);
|
|
164
|
+
}
|
|
165
|
+
// Announce the submission completion using VPAT clear-and-reset technique
|
|
166
|
+
liveRegion.textContent = '';
|
|
167
|
+
liveRegion.setAttribute('aria-live', 'off');
|
|
168
|
+
requestAnimationFrame(() => {
|
|
169
|
+
setTimeout(() => {
|
|
170
|
+
liveRegion.setAttribute('aria-live', 'polite');
|
|
171
|
+
liveRegion.textContent = announcementMessage;
|
|
172
|
+
setTimeout(() => {
|
|
173
|
+
if (liveRegion) {
|
|
174
|
+
liveRegion.textContent = '';
|
|
175
|
+
}
|
|
176
|
+
}, 1000);
|
|
177
|
+
}, 100);
|
|
178
|
+
});
|
|
151
179
|
let returnUrl = Formio.config.redirect;
|
|
152
180
|
// Allow form based configuration for return url.
|
|
153
181
|
if (!returnUrl &&
|
|
@@ -326,6 +354,12 @@ export class Formio {
|
|
|
326
354
|
mode: 'open',
|
|
327
355
|
});
|
|
328
356
|
options.shadowRoot = wrapper;
|
|
357
|
+
// Due to an issue with quill not loading styles in the shadowdom, we need to add quill styles and js to the shadowdom
|
|
358
|
+
const quill = {
|
|
359
|
+
js: `${Formio.cdn.quill}/quill.min.js`,
|
|
360
|
+
css: `${Formio.cdn.quill}/quill.snow.css`
|
|
361
|
+
};
|
|
362
|
+
await Formio.addLibrary(wrapper, quill, 'quill');
|
|
329
363
|
}
|
|
330
364
|
element.parentNode.removeChild(element);
|
|
331
365
|
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.
|
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-api98.1';
|
|
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}`);
|
|
@@ -279,7 +281,15 @@ if (typeof window !== 'undefined') {
|
|
|
279
281
|
eventData.name &&
|
|
280
282
|
eventData.formId &&
|
|
281
283
|
Formio.forms.hasOwnProperty(eventData.formId)) {
|
|
282
|
-
|
|
284
|
+
if (eventData.compPath) {
|
|
285
|
+
const comp = Formio.forms[eventData.formId].getComponent(eventData.compPath);
|
|
286
|
+
if (comp) {
|
|
287
|
+
comp.emit(eventData.name, eventData.data);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
Formio.forms[eventData.formId].emit(`iframe-${eventData.name}`, eventData.data);
|
|
292
|
+
}
|
|
283
293
|
}
|
|
284
294
|
});
|
|
285
295
|
}
|
package/lib/mjs/Webform.d.ts
CHANGED
|
@@ -259,6 +259,7 @@ declare class Webform extends NestedDataComponent {
|
|
|
259
259
|
* @returns {Promise} - The promise that is triggered when the submission is set.
|
|
260
260
|
*/
|
|
261
261
|
setSubmission(submission: any, flags?: any): Promise<any>;
|
|
262
|
+
_submission: any;
|
|
262
263
|
handleDraftError(errName: any, errDetails: any, restoreDraft: any): void;
|
|
263
264
|
saveDraft(): void;
|
|
264
265
|
/**
|
|
@@ -269,7 +270,6 @@ declare class Webform extends NestedDataComponent {
|
|
|
269
270
|
get schema(): any;
|
|
270
271
|
mergeData(_this: any, _that: any): void;
|
|
271
272
|
editing: boolean | undefined;
|
|
272
|
-
_submission: any;
|
|
273
273
|
/**
|
|
274
274
|
* Build the form.
|
|
275
275
|
* @returns {Promise} - The promise that is triggered when the form is built.
|
|
@@ -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
|
@@ -227,7 +227,7 @@ export default class Webform extends NestedDataComponent {
|
|
|
227
227
|
if (err) {
|
|
228
228
|
return;
|
|
229
229
|
}
|
|
230
|
-
this.
|
|
230
|
+
this.redraw();
|
|
231
231
|
this.emit('languageChanged');
|
|
232
232
|
});
|
|
233
233
|
}
|
|
@@ -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();
|
|
@@ -656,6 +658,8 @@ export default class Webform extends NestedDataComponent {
|
|
|
656
658
|
...resolveFlags,
|
|
657
659
|
};
|
|
658
660
|
}
|
|
661
|
+
this._submission = {};
|
|
662
|
+
this._data = {};
|
|
659
663
|
this.onSetSubmission(submission, flags);
|
|
660
664
|
return this.submissionReadyResolve(submission);
|
|
661
665
|
}, (err) => this.submissionReadyReject(err))
|
|
@@ -1112,6 +1116,7 @@ export default class Webform extends NestedDataComponent {
|
|
|
1112
1116
|
this.setPristine(true);
|
|
1113
1117
|
// We want to return the submitted submission and setValue will mutate the submission so cloneDeep it here.
|
|
1114
1118
|
this.setValue(fastCloneDeep(submission), {
|
|
1119
|
+
noDefault: true,
|
|
1115
1120
|
noValidate: true,
|
|
1116
1121
|
noCheck: true,
|
|
1117
1122
|
});
|
|
@@ -1120,6 +1125,32 @@ export default class Webform extends NestedDataComponent {
|
|
|
1120
1125
|
if (this.draftEnabled && this.triggerSaveDraft?.cancel) {
|
|
1121
1126
|
this.triggerSaveDraft.cancel();
|
|
1122
1127
|
}
|
|
1128
|
+
if (typeof document !== 'undefined' && document.body) {
|
|
1129
|
+
const announcementMessage = this.t ? this.t('complete') : 'Form submission complete';
|
|
1130
|
+
// Get or create ARIA live region for announcements
|
|
1131
|
+
let liveRegion = document.getElementById('formio-announcements');
|
|
1132
|
+
if (!liveRegion) {
|
|
1133
|
+
liveRegion = document.createElement('div');
|
|
1134
|
+
liveRegion.id = 'formio-announcements';
|
|
1135
|
+
liveRegion.setAttribute('role', 'status');
|
|
1136
|
+
liveRegion.setAttribute('aria-live', 'polite');
|
|
1137
|
+
liveRegion.setAttribute('aria-atomic', 'true');
|
|
1138
|
+
liveRegion.style.cssText = 'position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; clip: rect(0, 0, 0, 0);';
|
|
1139
|
+
document.body.appendChild(liveRegion);
|
|
1140
|
+
}
|
|
1141
|
+
// Announce the submission completion using VPAT clear-and-reset technique
|
|
1142
|
+
liveRegion.textContent = '';
|
|
1143
|
+
liveRegion.setAttribute('aria-live', 'off');
|
|
1144
|
+
requestAnimationFrame(() => {
|
|
1145
|
+
setTimeout(() => {
|
|
1146
|
+
liveRegion.setAttribute('aria-live', 'polite');
|
|
1147
|
+
liveRegion.textContent = announcementMessage;
|
|
1148
|
+
setTimeout(() => {
|
|
1149
|
+
liveRegion.textContent = '';
|
|
1150
|
+
}, 1000);
|
|
1151
|
+
}, 100);
|
|
1152
|
+
});
|
|
1153
|
+
}
|
|
1123
1154
|
this.emit('submit', submission, saved);
|
|
1124
1155
|
if (saved) {
|
|
1125
1156
|
this.emit('submitDone', submission);
|
|
@@ -1487,6 +1518,49 @@ export default class Webform extends NestedDataComponent {
|
|
|
1487
1518
|
captchaComponent[0].verify(`${this.form.name ? this.form.name : 'form'}Load`);
|
|
1488
1519
|
}
|
|
1489
1520
|
}
|
|
1521
|
+
loadTranslations() {
|
|
1522
|
+
// We only need a resolve since if translations cannot load, we still want to proceed and render the for
|
|
1523
|
+
let translationsLoadResolve;
|
|
1524
|
+
const promise = new Promise((resolve) => {
|
|
1525
|
+
translationsLoadResolve = resolve;
|
|
1526
|
+
});
|
|
1527
|
+
const translationsUrl = typeof this.options.i18n?.translationsUrl === 'string'
|
|
1528
|
+
? this.options.i18n.translationsUrl
|
|
1529
|
+
: null;
|
|
1530
|
+
if (translationsUrl) {
|
|
1531
|
+
const url = this.sanitize(this.interpolate(translationsUrl, {}), this.shouldSanitizeValue);
|
|
1532
|
+
Formio.makeStaticRequest(url, 'GET')
|
|
1533
|
+
.then((response) => {
|
|
1534
|
+
let languages = response;
|
|
1535
|
+
try {
|
|
1536
|
+
if (typeof languages == 'string') {
|
|
1537
|
+
languages = JSON.parse(languages);
|
|
1538
|
+
}
|
|
1539
|
+
this.i18next.setLanguages(languages);
|
|
1540
|
+
this.i18next.changeLanguage(this.i18next.originalLanguage, (err) => {
|
|
1541
|
+
if (err) {
|
|
1542
|
+
return;
|
|
1543
|
+
}
|
|
1544
|
+
this.emit('languageChanged');
|
|
1545
|
+
});
|
|
1546
|
+
this.redraw();
|
|
1547
|
+
translationsLoadResolve();
|
|
1548
|
+
}
|
|
1549
|
+
catch (err) {
|
|
1550
|
+
console.warn(err.message);
|
|
1551
|
+
translationsLoadResolve();
|
|
1552
|
+
}
|
|
1553
|
+
})
|
|
1554
|
+
.catch((err) => {
|
|
1555
|
+
console.warn(err);
|
|
1556
|
+
translationsLoadResolve();
|
|
1557
|
+
});
|
|
1558
|
+
}
|
|
1559
|
+
else {
|
|
1560
|
+
translationsLoadResolve();
|
|
1561
|
+
}
|
|
1562
|
+
return promise;
|
|
1563
|
+
}
|
|
1490
1564
|
set nosubmit(value) {
|
|
1491
1565
|
this._nosubmit = !!value;
|
|
1492
1566
|
this.emit('nosubmit', this._nosubmit);
|
|
@@ -932,7 +932,22 @@ export default class WebformBuilder extends Component {
|
|
|
932
932
|
rebuild = Promise.resolve();
|
|
933
933
|
}
|
|
934
934
|
return rebuild.then(() => {
|
|
935
|
+
// Get the updated `toIndex` after the component has been inserted/rebuilt
|
|
936
|
+
const toIndex = _.findIndex(target.formioContainer, { key: info.key });
|
|
935
937
|
this.emit('addComponent', info, parent, path, index, isNew && !this.options.noNewEdit && !info.noNewEdit);
|
|
938
|
+
// If this is not a new component — it means it was moved
|
|
939
|
+
if (!isNew) {
|
|
940
|
+
const payload = {
|
|
941
|
+
component: info,
|
|
942
|
+
parent,
|
|
943
|
+
path,
|
|
944
|
+
fromIndex: index,
|
|
945
|
+
toIndex,
|
|
946
|
+
timestamp: new Date()
|
|
947
|
+
};
|
|
948
|
+
// New event that allows explicit tracking of reordering
|
|
949
|
+
this.emit('moveComponent', payload);
|
|
950
|
+
}
|
|
936
951
|
if (!isNew || this.options.noNewEdit || info.noNewEdit) {
|
|
937
952
|
this.emit('change', this.form);
|
|
938
953
|
}
|
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;
|