@formio/js 5.0.0-rc.36 → 5.0.0-rc.38
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/fonts/bootstrap-icons.woff +0 -0
- package/dist/fonts/bootstrap-icons.woff2 +0 -0
- 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.js +854 -133
- package/dist/formio.form.min.js +1 -1
- package/dist/formio.form.min.js.LICENSE.txt +5 -3
- package/dist/formio.full.css +4 -4
- package/dist/formio.full.js +828 -137
- package/dist/formio.full.min.css +3 -3
- package/dist/formio.full.min.js +1 -1
- package/dist/formio.full.min.js.LICENSE.txt +5 -3
- package/dist/formio.js +5 -5
- package/dist/formio.min.js +1 -1
- package/dist/formio.min.js.LICENSE.txt +1 -1
- package/dist/formio.utils.js +25 -14
- package/dist/formio.utils.min.js +1 -1
- package/dist/formio.utils.min.js.LICENSE.txt +5 -3
- package/lib/cjs/Element.js +2 -2
- package/lib/cjs/Embed.js +19 -14
- package/lib/cjs/Formio.js +3 -0
- package/lib/cjs/components/_classes/component/Component.js +21 -7
- package/lib/cjs/components/_classes/component/fixtures/comp5.js +2 -2
- package/lib/cjs/components/_classes/list/ListComponent.js +5 -12
- package/lib/cjs/components/_classes/nested/NestedComponent.js +17 -9
- package/lib/cjs/components/columns/editForm/Columns.edit.display.js +1 -1
- package/lib/cjs/components/editgrid/EditGrid.js +11 -4
- package/lib/cjs/components/form/Form.js +3 -1
- package/lib/cjs/components/html/HTML.js +2 -2
- package/lib/cjs/components/html/fixtures/comp3.js +31 -0
- package/lib/cjs/components/html/fixtures/index.js +3 -1
- package/lib/cjs/components/radio/Radio.js +2 -1
- package/lib/cjs/components/radio/fixtures/comp10.js +23 -0
- package/lib/cjs/components/radio/fixtures/index.js +3 -1
- package/lib/cjs/components/recaptcha/ReCaptcha.js +3 -0
- package/lib/cjs/components/select/Select.js +84 -9
- package/lib/cjs/components/survey/Survey.js +10 -0
- package/lib/cjs/utils/conditionOperators/IsEqualTo.js +19 -1
- package/lib/cjs/utils/conditionOperators/IsNotEqualTo.js +4 -5
- package/lib/cjs/utils/utils.js +40 -2
- package/lib/mjs/Element.js +2 -2
- package/lib/mjs/Embed.js +17 -14
- package/lib/mjs/Formio.js +3 -0
- package/lib/mjs/components/_classes/component/Component.js +24 -8
- package/lib/mjs/components/_classes/component/fixtures/comp5.js +2 -2
- package/lib/mjs/components/_classes/list/ListComponent.js +5 -12
- package/lib/mjs/components/_classes/nested/NestedComponent.js +17 -9
- package/lib/mjs/components/columns/editForm/Columns.edit.display.js +1 -1
- package/lib/mjs/components/editgrid/EditGrid.js +11 -4
- package/lib/mjs/components/form/Form.js +3 -1
- package/lib/mjs/components/html/HTML.js +2 -2
- package/lib/mjs/components/html/fixtures/comp3.js +29 -0
- package/lib/mjs/components/html/fixtures/index.js +2 -1
- package/lib/mjs/components/radio/Radio.js +2 -1
- package/lib/mjs/components/radio/fixtures/comp10.js +21 -0
- package/lib/mjs/components/radio/fixtures/index.js +2 -1
- package/lib/mjs/components/recaptcha/ReCaptcha.js +3 -0
- package/lib/mjs/components/select/Select.js +83 -10
- package/lib/mjs/components/survey/Survey.js +10 -0
- package/lib/mjs/utils/conditionOperators/IsEqualTo.js +18 -1
- package/lib/mjs/utils/conditionOperators/IsNotEqualTo.js +4 -5
- package/lib/mjs/utils/utils.js +35 -0
- package/package.json +2 -2
- package/types/formio.d.ts +4 -0
@@ -5,6 +5,7 @@ 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 utils_1 = require("../utils");
|
8
9
|
class IsEqualTo extends ConditionOperator_1.default {
|
9
10
|
static get operatorKey() {
|
10
11
|
return 'isEqual';
|
@@ -12,7 +13,8 @@ class IsEqualTo extends ConditionOperator_1.default {
|
|
12
13
|
static get displayedName() {
|
13
14
|
return 'Is Equal To';
|
14
15
|
}
|
15
|
-
execute({ value, comparedValue }) {
|
16
|
+
execute({ value, comparedValue, instance, conditionComponentPath }) {
|
17
|
+
var _a;
|
16
18
|
if (value && comparedValue && typeof value !== typeof comparedValue && lodash_1.default.isString(comparedValue)) {
|
17
19
|
try {
|
18
20
|
comparedValue = JSON.parse(comparedValue);
|
@@ -20,6 +22,22 @@ class IsEqualTo extends ConditionOperator_1.default {
|
|
20
22
|
// eslint-disable-next-line no-empty
|
21
23
|
catch (e) { }
|
22
24
|
}
|
25
|
+
if (instance && instance.root) {
|
26
|
+
const conditionTriggerComponent = instance.root.getComponent(conditionComponentPath);
|
27
|
+
if (conditionTriggerComponent
|
28
|
+
&& (0, utils_1.isSelectResourceWithObjectValue)(conditionTriggerComponent.component)
|
29
|
+
&& ((_a = conditionTriggerComponent.component) === null || _a === void 0 ? void 0 : _a.template)) {
|
30
|
+
if (!value || !lodash_1.default.isPlainObject(value)) {
|
31
|
+
return false;
|
32
|
+
}
|
33
|
+
const { template, valueProperty } = conditionTriggerComponent.component;
|
34
|
+
if (valueProperty === 'data') {
|
35
|
+
value = { data: value };
|
36
|
+
comparedValue = { data: comparedValue };
|
37
|
+
}
|
38
|
+
return lodash_1.default.every((0, utils_1.getItemTemplateKeys)(template) || [], k => lodash_1.default.isEqual(lodash_1.default.get(value, k), lodash_1.default.get(comparedValue, k)));
|
39
|
+
}
|
40
|
+
}
|
23
41
|
//special check for select boxes
|
24
42
|
if (lodash_1.default.isObject(value) && comparedValue && lodash_1.default.isString(comparedValue)) {
|
25
43
|
return value[comparedValue];
|
@@ -3,17 +3,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
4
|
};
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
const
|
7
|
-
|
8
|
-
class IsNotEqualTo extends ConditionOperator_1.default {
|
6
|
+
const IsEqualTo_1 = __importDefault(require("./IsEqualTo"));
|
7
|
+
class IsNotEqualTo extends IsEqualTo_1.default {
|
9
8
|
static get operatorKey() {
|
10
9
|
return 'isNotEqual';
|
11
10
|
}
|
12
11
|
static get displayedName() {
|
13
12
|
return 'Is Not Equal To';
|
14
13
|
}
|
15
|
-
execute(
|
16
|
-
return !
|
14
|
+
execute(options) {
|
15
|
+
return !super.execute(options);
|
17
16
|
}
|
18
17
|
}
|
19
18
|
exports.default = IsNotEqualTo;
|
package/lib/cjs/utils/utils.js
CHANGED
@@ -30,8 +30,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
30
30
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
31
31
|
};
|
32
32
|
Object.defineProperty(exports, "__esModule", { value: true });
|
33
|
-
exports.
|
34
|
-
exports.interpolateErrors = exports.getComponentSavedTypes = exports.componentValueTypes = exports._ = exports.getFocusableElements = exports.isInsideScopingComponent = exports.isPromise = exports.getDataParentComponent = exports.getComponentPath = exports.getComponentPathWithoutIndicies = exports.getBrowserInfo = exports.getIEBrowserVersion = exports.round = exports.getStringFromComponentPath = exports.isChildOf = exports.getArrayFromComponentPath = exports.isInputComponent = exports.interpolate = exports.Evaluator = exports.fastCloneDeep = exports.sanitize = exports.translateHTMLTemplate = exports.getContextButtons = exports.getContextComponents = void 0;
|
33
|
+
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.escapeHTML = exports.unescapeHTML = exports.setActionProperty = exports.checkTrigger = exports.checkCondition = exports.checkJsonConditional = exports.checkCustomConditional = exports.getComponentActualValue = exports.checkSimpleConditional = exports.checkCalculated = exports.isMongoId = exports.boolValue = exports.getElementRect = exports.getPropertyValue = exports.getRandomComponentId = exports.evaluate = exports.moment = exports.ConditionOperators = exports.jsonLogic = void 0;
|
34
|
+
exports.isSelectResourceWithObjectValue = exports.getItemTemplateKeys = exports.interpolateErrors = exports.getComponentSavedTypes = exports.componentValueTypes = exports._ = exports.getFocusableElements = exports.isInsideScopingComponent = exports.isPromise = exports.getDataParentComponent = exports.getComponentPath = exports.getComponentPathWithoutIndicies = exports.getBrowserInfo = exports.getIEBrowserVersion = exports.round = exports.getStringFromComponentPath = exports.isChildOf = exports.getArrayFromComponentPath = exports.isInputComponent = exports.interpolate = exports.Evaluator = exports.fastCloneDeep = exports.sanitize = exports.translateHTMLTemplate = exports.getContextButtons = exports.getContextComponents = exports.observeOverload = void 0;
|
35
35
|
const lodash_1 = __importDefault(require("lodash"));
|
36
36
|
exports._ = lodash_1.default;
|
37
37
|
const fetch_ponyfill_1 = __importDefault(require("fetch-ponyfill"));
|
@@ -447,6 +447,22 @@ function unescapeHTML(str) {
|
|
447
447
|
return doc.documentElement.textContent;
|
448
448
|
}
|
449
449
|
exports.unescapeHTML = unescapeHTML;
|
450
|
+
/**
|
451
|
+
* Escape HTML characters like <, >, & and etc.
|
452
|
+
* @param str
|
453
|
+
* @returns {string}
|
454
|
+
*/
|
455
|
+
function escapeHTML(html) {
|
456
|
+
if (html) {
|
457
|
+
return html.replace(/&/g, '&')
|
458
|
+
.replace(/</g, '<')
|
459
|
+
.replace(/>/g, '>')
|
460
|
+
.replace(/"/g, '"')
|
461
|
+
.replace(/'/g, ''');
|
462
|
+
}
|
463
|
+
return '';
|
464
|
+
}
|
465
|
+
exports.escapeHTML = escapeHTML;
|
450
466
|
/**
|
451
467
|
* Make HTML element from string
|
452
468
|
* @param str
|
@@ -1509,3 +1525,25 @@ const interpolateErrors = (component, errors, interpolateFn) => {
|
|
1509
1525
|
});
|
1510
1526
|
};
|
1511
1527
|
exports.interpolateErrors = interpolateErrors;
|
1528
|
+
function getItemTemplateKeys(template) {
|
1529
|
+
const templateKeys = [];
|
1530
|
+
if (!template) {
|
1531
|
+
return templateKeys;
|
1532
|
+
}
|
1533
|
+
const keys = template.match(/({{\s*(.*?)\s*}})/g);
|
1534
|
+
if (keys) {
|
1535
|
+
keys.forEach((key) => {
|
1536
|
+
const propKey = key.match(/{{\s*item\.(.*?)\s*}}/);
|
1537
|
+
if (propKey && propKey.length > 1) {
|
1538
|
+
templateKeys.push(propKey[1]);
|
1539
|
+
}
|
1540
|
+
});
|
1541
|
+
}
|
1542
|
+
return templateKeys;
|
1543
|
+
}
|
1544
|
+
exports.getItemTemplateKeys = getItemTemplateKeys;
|
1545
|
+
function isSelectResourceWithObjectValue(comp = {}) {
|
1546
|
+
const { reference, dataSrc, valueProperty } = comp;
|
1547
|
+
return reference || (dataSrc === 'resource' && (!valueProperty || valueProperty === 'data'));
|
1548
|
+
}
|
1549
|
+
exports.isSelectResourceWithObjectValue = isSelectResourceWithObjectValue;
|
package/lib/mjs/Element.js
CHANGED
@@ -179,7 +179,7 @@ export default class Element {
|
|
179
179
|
* @param persistent
|
180
180
|
* If this listener should persist beyond "destroy" commands.
|
181
181
|
*/
|
182
|
-
addEventListener(obj, type, func, persistent) {
|
182
|
+
addEventListener(obj, type, func, persistent, capture) {
|
183
183
|
if (!obj) {
|
184
184
|
return;
|
185
185
|
}
|
@@ -187,7 +187,7 @@ export default class Element {
|
|
187
187
|
this.eventHandlers.push({ id: this.id, obj, type, func });
|
188
188
|
}
|
189
189
|
if ('addEventListener' in obj) {
|
190
|
-
obj.addEventListener(type, func,
|
190
|
+
obj.addEventListener(type, func, !!capture);
|
191
191
|
}
|
192
192
|
else if ('attachEvent' in obj) {
|
193
193
|
obj.attachEvent(`on${type}`, func);
|
package/lib/mjs/Embed.js
CHANGED
@@ -201,6 +201,22 @@ class Formio {
|
|
201
201
|
}
|
202
202
|
}
|
203
203
|
}
|
204
|
+
static async addLoader(wrapper) {
|
205
|
+
wrapper.appendChild(Formio.createElement('div', {
|
206
|
+
'class': 'formio-loader'
|
207
|
+
}, [{
|
208
|
+
tag: 'div',
|
209
|
+
attrs: {
|
210
|
+
class: 'loader-wrapper'
|
211
|
+
},
|
212
|
+
children: [{
|
213
|
+
tag: 'div',
|
214
|
+
attrs: {
|
215
|
+
class: 'loader text-center'
|
216
|
+
}
|
217
|
+
}]
|
218
|
+
}]));
|
219
|
+
}
|
204
220
|
// eslint-disable-next-line max-statements
|
205
221
|
static async init(element, options = {}, builder = false) {
|
206
222
|
Formio.cdn = new CDN(Formio.config.cdn, Formio.config.cdnUrls || {});
|
@@ -244,20 +260,7 @@ class Formio {
|
|
244
260
|
// Load the renderer styles.
|
245
261
|
await Formio.addStyles(wrapper, Formio.config.embedCSS || `${Formio.cdn.js}/formio.embed.css`);
|
246
262
|
// Add a loader.
|
247
|
-
|
248
|
-
'class': 'formio-loader'
|
249
|
-
}, [{
|
250
|
-
tag: 'div',
|
251
|
-
attrs: {
|
252
|
-
class: 'loader-wrapper'
|
253
|
-
},
|
254
|
-
children: [{
|
255
|
-
tag: 'div',
|
256
|
-
attrs: {
|
257
|
-
class: 'loader text-center'
|
258
|
-
}
|
259
|
-
}]
|
260
|
-
}]));
|
263
|
+
Formio.addLoader(wrapper);
|
261
264
|
const formioSrc = Formio.config.full ? 'formio.full' : 'formio.form';
|
262
265
|
const renderer = Formio.config.debug ? formioSrc : `${formioSrc}.min`;
|
263
266
|
Formio.FormioClass = await Formio.addScript(wrapper, Formio.formioScript(Formio.config.script || `${Formio.cdn.js}/${renderer}.js`, builder), 'Formio', builder ? 'isBuilder' : 'isRenderer');
|
package/lib/mjs/Formio.js
CHANGED
@@ -104,4 +104,7 @@ FormioCore.Form = FormioEmbed.Form;
|
|
104
104
|
FormioCore.FormBuilder = FormioEmbed.FormBuilder;
|
105
105
|
FormioCore.use = FormioEmbed.use;
|
106
106
|
FormioCore.createForm = FormioEmbed.createForm;
|
107
|
+
FormioCore.submitDone = FormioEmbed.submitDone;
|
108
|
+
FormioCore.addLibrary = FormioEmbed.addLibrary;
|
109
|
+
FormioCore.addLoader = FormioEmbed.addLoader;
|
107
110
|
export { FormioCore as Formio };
|
@@ -3,7 +3,7 @@ import { conformToMask } from '@formio/vanilla-text-mask';
|
|
3
3
|
import tippy from 'tippy.js';
|
4
4
|
import _ from 'lodash';
|
5
5
|
import isMobile from 'ismobilejs';
|
6
|
-
import { processOne, processOneSync,
|
6
|
+
import { processOne, processOneSync, validateProcessInfo } from '@formio/core/process';
|
7
7
|
import { Formio } from '../../../Formio';
|
8
8
|
import * as FormioUtils from '../../../utils/utils';
|
9
9
|
import { fastCloneDeep, boolValue, getComponentPath, isInsideScopingComponent, currentTimezone } from '../../../utils/utils';
|
@@ -819,7 +819,13 @@ export default class Component extends Element {
|
|
819
819
|
renderTemplate(name, data = {}, modeOption) {
|
820
820
|
// Need to make this fall back to form if renderMode is not found similar to how we search templates.
|
821
821
|
const mode = modeOption || this.options.renderMode || 'form';
|
822
|
-
data.component =
|
822
|
+
data.component = {
|
823
|
+
...this.component,
|
824
|
+
};
|
825
|
+
// Escape HTML provided in component description and render it as a string instead
|
826
|
+
if (this.component.description) {
|
827
|
+
data.component.description = FormioUtils.escapeHTML(this.component.description);
|
828
|
+
}
|
823
829
|
data.self = this;
|
824
830
|
data.options = this.options;
|
825
831
|
data.readOnly = this.options.readOnly;
|
@@ -1030,12 +1036,12 @@ export default class Component extends Element {
|
|
1030
1036
|
const tooltipText = this.interpolate(tooltipDataTitle || tooltipAttribute)
|
1031
1037
|
.replace(/(?:\r\n|\r|\n)/g, '<br />');
|
1032
1038
|
this.tooltips[index] = tippy(tooltip, {
|
1033
|
-
allowHTML:
|
1039
|
+
allowHTML: false,
|
1034
1040
|
trigger: 'mouseenter click focus',
|
1035
1041
|
placement: 'right',
|
1036
1042
|
zIndex: 10000,
|
1037
1043
|
interactive: true,
|
1038
|
-
content: this.t(
|
1044
|
+
content: this.t(tooltipText, { _userInput: true }),
|
1039
1045
|
});
|
1040
1046
|
}
|
1041
1047
|
});
|
@@ -2574,7 +2580,7 @@ export default class Component extends Element {
|
|
2574
2580
|
scope: validationScope,
|
2575
2581
|
instance: this,
|
2576
2582
|
processors: [
|
2577
|
-
|
2583
|
+
validateProcessInfo
|
2578
2584
|
]
|
2579
2585
|
});
|
2580
2586
|
const errors = validationScope.errors;
|
@@ -2655,7 +2661,7 @@ export default class Component extends Element {
|
|
2655
2661
|
instance: this,
|
2656
2662
|
scope: { errors: [] },
|
2657
2663
|
processors: [
|
2658
|
-
|
2664
|
+
validateProcessInfo
|
2659
2665
|
]
|
2660
2666
|
};
|
2661
2667
|
if (async) {
|
@@ -2684,7 +2690,12 @@ export default class Component extends Element {
|
|
2684
2690
|
return this.validateComponent(data, row, flags).then((errors) => {
|
2685
2691
|
allErrors.push(...errors);
|
2686
2692
|
if (this.parent && this.parent.childErrors) {
|
2687
|
-
|
2693
|
+
if (errors.length) {
|
2694
|
+
this.parent.childErrors.push(...errors);
|
2695
|
+
}
|
2696
|
+
else {
|
2697
|
+
_.remove(this.parent.childErrors, (err) => err.component.key === this.component.key);
|
2698
|
+
}
|
2688
2699
|
}
|
2689
2700
|
this.showValidationErrors(errors, data, row, flags);
|
2690
2701
|
return errors.length === 0;
|
@@ -2695,7 +2706,12 @@ export default class Component extends Element {
|
|
2695
2706
|
this.showValidationErrors(errors, data, row, flags);
|
2696
2707
|
allErrors.push(...errors);
|
2697
2708
|
if (this.parent && this.parent.childErrors) {
|
2698
|
-
|
2709
|
+
if (errors.length) {
|
2710
|
+
this.parent.childErrors.push(...errors);
|
2711
|
+
}
|
2712
|
+
else {
|
2713
|
+
_.remove(this.parent.childErrors, (err) => err.component.key === this.component.key);
|
2714
|
+
}
|
2699
2715
|
}
|
2700
2716
|
return errors.length === 0;
|
2701
2717
|
}
|
@@ -4,8 +4,8 @@ export default {
|
|
4
4
|
components: [
|
5
5
|
{
|
6
6
|
label: 'Text Field',
|
7
|
-
description: "<img
|
8
|
-
tooltip: "<img src='https://somesite' onerror='var _ee = 1 >",
|
7
|
+
description: "<img src='https://somesite' onerror='var _ee = 2' >",
|
8
|
+
tooltip: "<img src='https://somesite' onerror='var _ee = 1' >",
|
9
9
|
applyMaskOn: 'change',
|
10
10
|
tableView: true,
|
11
11
|
key: 'textField',
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import Field from '../field/Field';
|
2
2
|
import { Formio } from '../../../Formio';
|
3
3
|
import _ from 'lodash';
|
4
|
+
import { getItemTemplateKeys } from '../../../utils/utils';
|
4
5
|
export default class ListComponent extends Field {
|
5
6
|
static schema(...extend) {
|
6
7
|
return Field.schema({
|
@@ -43,18 +44,10 @@ export default class ListComponent extends Field {
|
|
43
44
|
return true;
|
44
45
|
}
|
45
46
|
getTemplateKeys() {
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
keys.forEach((key) => {
|
51
|
-
const propKey = key.match(/{{\s*item\.(.*?)\s*}}/);
|
52
|
-
if (propKey && propKey.length > 1) {
|
53
|
-
this.templateKeys.push(propKey[1]);
|
54
|
-
}
|
55
|
-
});
|
56
|
-
}
|
57
|
-
}
|
47
|
+
const template = this.component.template;
|
48
|
+
this.templateKeys = this.options.readOnly && template
|
49
|
+
? getItemTemplateKeys(template)
|
50
|
+
: [];
|
58
51
|
}
|
59
52
|
get requestHeaders() {
|
60
53
|
// Create the headers object.
|
@@ -582,6 +582,16 @@ export default class NestedComponent extends Field {
|
|
582
582
|
components = components || this.component.components;
|
583
583
|
data = data || this.rootValue;
|
584
584
|
const { async, dirty, process } = flags;
|
585
|
+
const validationProcessorProcess = (context) => this.validationProcessor(context, flags);
|
586
|
+
const checkModalProcessorProcess = ({ instance, component, components }) => {
|
587
|
+
// If we just validated the last component, and there are errors from our parent, then we need to show a model of those errors.
|
588
|
+
if (instance &&
|
589
|
+
instance.parent &&
|
590
|
+
(component === components[components.length - 1]) &&
|
591
|
+
instance.parent.componentModal) {
|
592
|
+
instance.parent.checkModal(instance.parent.childErrors, dirty);
|
593
|
+
}
|
594
|
+
};
|
585
595
|
const processorContext = {
|
586
596
|
process: process || 'unknown',
|
587
597
|
components,
|
@@ -589,15 +599,13 @@ export default class NestedComponent extends Field {
|
|
589
599
|
data: data,
|
590
600
|
scope: { errors: [] },
|
591
601
|
processors: [
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
instance.parent.checkModal(instance.parent.childErrors, dirty);
|
600
|
-
}
|
602
|
+
{
|
603
|
+
process: validationProcessorProcess,
|
604
|
+
processSync: validationProcessorProcess
|
605
|
+
},
|
606
|
+
{
|
607
|
+
process: checkModalProcessorProcess,
|
608
|
+
processSync: checkModalProcessorProcess
|
601
609
|
}
|
602
610
|
]
|
603
611
|
};
|
@@ -56,7 +56,7 @@ export default [
|
|
56
56
|
key: 'columns',
|
57
57
|
label: 'Column Properties',
|
58
58
|
addAnother: 'Add Column',
|
59
|
-
tooltip: 'The
|
59
|
+
tooltip: 'The size and width settings for each column. One row is equal to 12. (e.g., a row with two columns spanning the entire page should be 6 and 6)',
|
60
60
|
reorder: true,
|
61
61
|
components: [
|
62
62
|
{
|
@@ -467,7 +467,7 @@ export default class EditGridComponent extends NestedArrayComponent {
|
|
467
467
|
].forEach(({ className, event, action, }) => {
|
468
468
|
const elements = row.getElementsByClassName(className);
|
469
469
|
Array.prototype.forEach.call(elements, (element) => {
|
470
|
-
if (this.options.
|
470
|
+
if (this.options.pdf && _.intersection(element.classList, ['editRow', 'removeRow']).length) {
|
471
471
|
element.style.display = 'none';
|
472
472
|
}
|
473
473
|
else {
|
@@ -599,6 +599,9 @@ export default class EditGridComponent extends NestedArrayComponent {
|
|
599
599
|
const dataObj = {};
|
600
600
|
const rowIndex = this.editRows.length;
|
601
601
|
const editRow = this.createRow(dataObj, rowIndex);
|
602
|
+
if (editRow.state === EditRowState.New) {
|
603
|
+
this.emptyRow = fastCloneDeep(editRow.data);
|
604
|
+
}
|
602
605
|
if (this.inlineEditMode) {
|
603
606
|
this.triggerChange();
|
604
607
|
}
|
@@ -669,7 +672,7 @@ export default class EditGridComponent extends NestedArrayComponent {
|
|
669
672
|
}
|
670
673
|
showDialog(rowIndex) {
|
671
674
|
const editRow = this.editRows[rowIndex];
|
672
|
-
if (_.isEqual(editRow.backup, editRow.data)) {
|
675
|
+
if (editRow.state === EditRowState.New ? _.isEqual(this.emptyRow, editRow.data) : _.isEqual(editRow.backup, editRow.data)) {
|
673
676
|
return Promise.resolve();
|
674
677
|
}
|
675
678
|
const wrapper = this.ce('div', { ref: 'confirmationDialog' });
|
@@ -969,6 +972,7 @@ export default class EditGridComponent extends NestedArrayComponent {
|
|
969
972
|
const editGridValue = _.get(rootValue, this.path, []);
|
970
973
|
editGridValue[editRow.rowIndex] = editRow.data;
|
971
974
|
_.set(rootValue, this.path, editGridValue);
|
975
|
+
const validationProcessorProcess = (context) => this.validationProcessor(context, { dirty, silentCheck });
|
972
976
|
editRow.errors = processSync({
|
973
977
|
components: fastCloneDeep(this.component.components).map((component) => {
|
974
978
|
component.parentPath = `${this.path}[${editRow.rowIndex}]`;
|
@@ -980,7 +984,10 @@ export default class EditGridComponent extends NestedArrayComponent {
|
|
980
984
|
instances: this.componentsMap,
|
981
985
|
scope: { errors: [] },
|
982
986
|
processors: [
|
983
|
-
|
987
|
+
{
|
988
|
+
process: validationProcessorProcess,
|
989
|
+
processSync: validationProcessorProcess
|
990
|
+
}
|
984
991
|
]
|
985
992
|
}).errors;
|
986
993
|
}
|
@@ -1070,7 +1077,7 @@ export default class EditGridComponent extends NestedArrayComponent {
|
|
1070
1077
|
this.setCustomValidity(this.t(this.errorMessage('unsavedRowsError')), dirty);
|
1071
1078
|
return false;
|
1072
1079
|
}
|
1073
|
-
const message = this.invalid || this.invalidMessage(data, dirty);
|
1080
|
+
const message = this.invalid || this.invalidMessage(data, dirty, false, row);
|
1074
1081
|
if (allRowErrors.length && this.root?.submitted && !message) {
|
1075
1082
|
this._errors = this.setCustomValidity(message, dirty);
|
1076
1083
|
errors.push(...this._errors);
|
@@ -600,7 +600,9 @@ export default class FormComponent extends Component {
|
|
600
600
|
const formId = submission.form || this.formObj.form || this.component.form;
|
601
601
|
const submissionUrl = `${this.subForm.formio.formsUrl}/${formId}/submission/${submission._id}`;
|
602
602
|
this.subForm.setUrl(submissionUrl, this.options);
|
603
|
-
this.subForm.loadSubmission()
|
603
|
+
this.subForm.loadSubmission().catch((err) => {
|
604
|
+
console.error(`Unable to load subform submission ${submission._id}:`, err);
|
605
|
+
});
|
604
606
|
}
|
605
607
|
else {
|
606
608
|
this.subForm.setValue(submission, flags);
|
@@ -38,13 +38,13 @@ export default class HTMLComponent extends Component {
|
|
38
38
|
return ` ${this.component.content} `;
|
39
39
|
}
|
40
40
|
const submission = _.get(this.root, 'submission', {});
|
41
|
-
const content = this.component.content ? this.interpolate(this.component.content, {
|
41
|
+
const content = this.component.content ? this.interpolate(this.sanitize(this.component.content, this.shouldSanitizeValue), {
|
42
42
|
metadata: submission.metadata || {},
|
43
43
|
submission: submission,
|
44
44
|
data: this.rootValue,
|
45
45
|
row: this.data
|
46
46
|
}) : '';
|
47
|
-
return
|
47
|
+
return content;
|
48
48
|
}
|
49
49
|
get singleTags() {
|
50
50
|
return ['br', 'img', 'hr'];
|
@@ -0,0 +1,29 @@
|
|
1
|
+
export default {
|
2
|
+
type: 'form',
|
3
|
+
display: 'form',
|
4
|
+
components: [
|
5
|
+
{
|
6
|
+
label: 'HTML',
|
7
|
+
attrs: [
|
8
|
+
{
|
9
|
+
attr: '',
|
10
|
+
value: '',
|
11
|
+
},
|
12
|
+
],
|
13
|
+
content: '<img src=1 onerror=alert("htmlContent")>',
|
14
|
+
refreshOnChange: false,
|
15
|
+
key: 'html',
|
16
|
+
type: 'htmlelement',
|
17
|
+
input: false,
|
18
|
+
tableView: false,
|
19
|
+
},
|
20
|
+
{
|
21
|
+
type: 'button',
|
22
|
+
label: 'Submit',
|
23
|
+
key: 'submit',
|
24
|
+
disableOnInvalid: true,
|
25
|
+
input: true,
|
26
|
+
tableView: false,
|
27
|
+
},
|
28
|
+
],
|
29
|
+
};
|
@@ -349,7 +349,8 @@ export default class RadioComponent extends ListComponent {
|
|
349
349
|
if (value === this.emptyValue) {
|
350
350
|
return value;
|
351
351
|
}
|
352
|
-
|
352
|
+
const isEquivalent = _.toString(value) === Number(value).toString();
|
353
|
+
if (!isNaN(parseFloat(value)) && isFinite(value) && isEquivalent) {
|
353
354
|
value = +value;
|
354
355
|
}
|
355
356
|
if (value === 'true') {
|
@@ -0,0 +1,21 @@
|
|
1
|
+
export default {
|
2
|
+
'label': 'Radio',
|
3
|
+
'optionsLabelPosition': 'right',
|
4
|
+
'inline': false,
|
5
|
+
'tableView': false,
|
6
|
+
'values': [
|
7
|
+
{
|
8
|
+
'label': '01',
|
9
|
+
'value': '01',
|
10
|
+
'shortcut': ''
|
11
|
+
},
|
12
|
+
{
|
13
|
+
'label': '1',
|
14
|
+
'value': '1',
|
15
|
+
'shortcut': ''
|
16
|
+
}
|
17
|
+
],
|
18
|
+
'key': 'radio',
|
19
|
+
'type': 'radio',
|
20
|
+
'input': true
|
21
|
+
};
|
@@ -7,4 +7,5 @@ import comp6 from './comp6';
|
|
7
7
|
import comp7 from './comp7';
|
8
8
|
import comp8 from './comp8';
|
9
9
|
import comp9 from './comp9';
|
10
|
-
|
10
|
+
import comp10 from './comp10';
|
11
|
+
export { comp1, comp2, comp3, comp4, comp5, comp6, comp7, comp8, comp9, comp10 };
|