@formio/js 5.0.0-rc.39 → 5.0.0-rc.41
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/formio.builder.css +2 -2
- package/dist/formio.builder.min.css +1 -1
- package/dist/formio.embed.js +1 -1
- package/dist/formio.embed.min.js +1 -1
- package/dist/formio.embed.min.js.LICENSE.txt +1 -1
- package/dist/formio.form.css +2 -2
- package/dist/formio.form.js +5373 -2370
- package/dist/formio.form.min.css +1 -1
- package/dist/formio.form.min.js +1 -1
- package/dist/formio.form.min.js.LICENSE.txt +25 -7
- package/dist/formio.full.css +2 -2
- package/dist/formio.full.js +5715 -2704
- package/dist/formio.full.min.css +1 -1
- package/dist/formio.full.min.js +1 -1
- package/dist/formio.full.min.js.LICENSE.txt +25 -7
- package/dist/formio.js +143 -61
- package/dist/formio.min.js +1 -1
- package/dist/formio.min.js.LICENSE.txt +13 -1
- package/dist/formio.utils.js +149 -96
- package/dist/formio.utils.min.js +1 -1
- package/dist/formio.utils.min.js.LICENSE.txt +4 -4
- package/lib/cjs/Element.js +1 -0
- package/lib/cjs/Embed.js +121 -121
- package/lib/cjs/Webform.js +36 -13
- package/lib/cjs/WebformBuilder.js +4 -2
- package/lib/cjs/Wizard.js +6 -1
- package/lib/cjs/components/_classes/component/Component.js +33 -22
- package/lib/cjs/components/_classes/component/editForm/Component.edit.logic.js +1 -1
- package/lib/cjs/components/_classes/component/editForm/Component.edit.validation.js +8 -0
- package/lib/cjs/components/_classes/component/fixtures/comp5.js +2 -2
- package/lib/cjs/components/_classes/multivalue/Multivalue.js +2 -2
- package/lib/cjs/components/_classes/nested/NestedComponent.js +2 -2
- package/lib/cjs/components/address/fixtures/comp3.js +1 -1
- package/lib/cjs/components/builder.js +0 -2
- package/lib/cjs/components/button/Button.js +7 -1
- package/lib/cjs/components/datagrid/DataGrid.js +16 -3
- package/lib/cjs/components/datagrid/fixtures/comp-with-allow-calculate-override.js +68 -0
- package/lib/cjs/components/datagrid/fixtures/comp6.js +1 -1
- package/lib/cjs/components/datagrid/fixtures/index.js +5 -1
- package/lib/cjs/components/datagrid/fixtures/two-comp-with-allow-calculate-override.js +104 -0
- package/lib/cjs/components/editgrid/EditGrid.js +11 -4
- package/lib/cjs/components/editgrid/fixtures/formsWithEditGridAndConditions.js +923 -0
- package/lib/cjs/components/file/File.js +2 -2
- package/lib/cjs/components/file/editForm/File.edit.file.js +1 -1
- package/lib/cjs/components/form/Form.js +1 -1
- package/lib/cjs/components/html/HTML.js +11 -2
- package/lib/cjs/components/html/fixtures/index.js +1 -3
- package/lib/cjs/components/index.js +0 -2
- package/lib/cjs/components/recaptcha/ReCaptcha.js +46 -46
- package/lib/cjs/components/select/Select.js +3 -1
- package/lib/cjs/components/select/fixtures/comp20.js +46 -0
- package/lib/cjs/components/select/fixtures/comp21.js +106 -0
- package/lib/cjs/components/select/fixtures/index.js +5 -1
- package/lib/cjs/components/selectboxes/SelectBoxes.js +1 -1
- package/lib/cjs/components/textfield/TextField.js +63 -3
- package/lib/cjs/providers/storage/s3.js +5 -3
- package/lib/cjs/providers/storage/uploadAdapter.js +1 -1
- package/lib/cjs/providers/storage/url.js +19 -13
- package/lib/cjs/templates/Templates.js +4 -4
- package/lib/cjs/translations/en.js +10 -6
- package/lib/cjs/utils/Evaluator.js +1 -1
- package/lib/cjs/utils/conditionOperators/IsEqualTo.js +2 -2
- package/lib/cjs/utils/formUtils.js +3 -3
- package/lib/cjs/utils/utils.js +4 -19
- package/lib/cjs/widgets/CalendarWidget.js +1 -1
- package/lib/mjs/Element.js +1 -0
- package/lib/mjs/Embed.js +1 -2
- package/lib/mjs/FormBuilder.js +1 -2
- package/lib/mjs/Webform.js +36 -13
- package/lib/mjs/WebformBuilder.js +4 -2
- package/lib/mjs/Wizard.js +6 -1
- package/lib/mjs/builders/Builders.js +1 -2
- package/lib/mjs/components/Components.js +1 -2
- package/lib/mjs/components/_classes/component/Component.js +33 -24
- package/lib/mjs/components/_classes/component/editForm/Component.edit.logic.js +1 -1
- package/lib/mjs/components/_classes/component/editForm/Component.edit.validation.js +8 -0
- package/lib/mjs/components/_classes/component/fixtures/comp5.js +2 -2
- package/lib/mjs/components/_classes/multivalue/Multivalue.js +2 -2
- package/lib/mjs/components/_classes/nested/NestedComponent.js +2 -2
- package/lib/mjs/components/address/fixtures/comp3.js +1 -1
- package/lib/mjs/components/builder.js +0 -2
- package/lib/mjs/components/button/Button.js +7 -1
- package/lib/mjs/components/datagrid/DataGrid.js +15 -3
- package/lib/mjs/components/datagrid/fixtures/comp-with-allow-calculate-override.js +66 -0
- package/lib/mjs/components/datagrid/fixtures/comp6.js +1 -1
- package/lib/mjs/components/datagrid/fixtures/index.js +3 -1
- package/lib/mjs/components/datagrid/fixtures/two-comp-with-allow-calculate-override.js +102 -0
- package/lib/mjs/components/editgrid/EditGrid.js +11 -4
- package/lib/mjs/components/editgrid/fixtures/formsWithEditGridAndConditions.js +921 -0
- package/lib/mjs/components/file/File.js +2 -2
- package/lib/mjs/components/file/editForm/File.edit.file.js +1 -1
- package/lib/mjs/components/form/Form.js +1 -1
- package/lib/mjs/components/html/HTML.js +10 -2
- package/lib/mjs/components/html/fixtures/index.js +1 -2
- package/lib/mjs/components/index.js +0 -2
- package/lib/mjs/components/recaptcha/ReCaptcha.js +32 -43
- package/lib/mjs/components/select/Select.js +3 -1
- package/lib/mjs/components/select/fixtures/comp20.js +44 -0
- package/lib/mjs/components/select/fixtures/comp21.js +104 -0
- package/lib/mjs/components/select/fixtures/index.js +3 -1
- package/lib/mjs/components/selectboxes/SelectBoxes.js +1 -1
- package/lib/mjs/components/textfield/TextField.js +62 -3
- package/lib/mjs/displays/Displays.js +1 -2
- package/lib/mjs/licenses/Licenses.js +1 -2
- package/lib/mjs/providers/Providers.js +1 -2
- package/lib/mjs/providers/storage/s3.js +5 -3
- package/lib/mjs/providers/storage/uploadAdapter.js +1 -1
- package/lib/mjs/providers/storage/url.js +19 -13
- package/lib/mjs/templates/Templates.js +1 -1
- package/lib/mjs/translations/en.js +10 -6
- package/lib/mjs/utils/Evaluator.js +1 -1
- package/lib/mjs/utils/conditionOperators/IsEqualTo.js +2 -2
- package/lib/mjs/utils/formUtils.js +3 -3
- package/lib/mjs/utils/utils.js +2 -16
- package/lib/mjs/widgets/CalendarWidget.js +1 -1
- package/package.json +23 -22
- package/lib/cjs/components/html/fixtures/comp3.js +0 -31
- package/lib/cjs/components/resource/Resource.form.js +0 -16
- package/lib/cjs/components/resource/Resource.js +0 -39
- package/lib/cjs/components/resource/editForm/Resource.edit.display.js +0 -102
- package/lib/cjs/components/resource/fixtures/comp1.js +0 -30
- package/lib/cjs/components/resource/fixtures/comp2.js +0 -31
- package/lib/cjs/components/resource/fixtures/index.js +0 -10
- package/lib/mjs/components/html/fixtures/comp3.js +0 -29
- package/lib/mjs/components/resource/Resource.form.js +0 -10
- package/lib/mjs/components/resource/Resource.js +0 -33
- package/lib/mjs/components/resource/editForm/Resource.edit.display.js +0 -100
- package/lib/mjs/components/resource/fixtures/comp1.js +0 -28
- package/lib/mjs/components/resource/fixtures/comp2.js +0 -29
- package/lib/mjs/components/resource/fixtures/index.js +0 -3
@@ -579,8 +579,8 @@ export default class FileComponent extends Field {
|
|
579
579
|
}
|
580
580
|
valid = pattern.excludes.reduce((result, excludePattern) => {
|
581
581
|
const exclude = new RegExp(excludePattern, 'i');
|
582
|
-
return result && (_.isNil(file.type) ||
|
583
|
-
(_.isNil(file.name) ||
|
582
|
+
return result && (_.isNil(file.type) || exclude.test(file.type)) &&
|
583
|
+
(_.isNil(file.name) || exclude.test(file.name));
|
584
584
|
}, valid);
|
585
585
|
return valid;
|
586
586
|
}
|
@@ -184,7 +184,7 @@ export default [
|
|
184
184
|
input: true,
|
185
185
|
key: 'fileNameTemplate',
|
186
186
|
label: 'File Name Template',
|
187
|
-
placeholder: '(optional) { {name} }-{ {guid} }
|
187
|
+
placeholder: '(optional) { {name} }-{ {guid} }',
|
188
188
|
tooltip: 'Specify template for name of uploaded file(s). Regular template variables are available (`data`, `component`, `user`, `value`, `moment` etc.), also `fileName`, `guid` variables are available. `guid` part must be present, if not found in template, will be added at the end.',
|
189
189
|
weight: 25
|
190
190
|
},
|
@@ -609,7 +609,7 @@ export default class FormComponent extends Component {
|
|
609
609
|
}
|
610
610
|
}
|
611
611
|
isEmpty(value = this.dataValue) {
|
612
|
-
return value === null || _.isEqual(value, this.emptyValue) || (this.areAllComponentsEmpty(value
|
612
|
+
return value === null || _.isEqual(value, this.emptyValue) || (this.areAllComponentsEmpty(value?.data) && !value?._id);
|
613
613
|
}
|
614
614
|
areAllComponentsEmpty(data) {
|
615
615
|
let res = true;
|
@@ -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.
|
41
|
+
const content = this.component.content ? this.interpolate(this.component.content, {
|
42
42
|
metadata: submission.metadata || {},
|
43
43
|
submission: submission,
|
44
44
|
data: this.rootValue,
|
45
45
|
row: this.data
|
46
46
|
}) : '';
|
47
|
-
return content;
|
47
|
+
return this.sanitize(content, this.shouldSanitizeValue);
|
48
48
|
}
|
49
49
|
get singleTags() {
|
50
50
|
return ['br', 'img', 'hr'];
|
@@ -80,8 +80,16 @@ export default class HTMLComponent extends Component {
|
|
80
80
|
render() {
|
81
81
|
return super.render(this.renderContent());
|
82
82
|
}
|
83
|
+
get dataReady() {
|
84
|
+
return this.root?.submissionReady || Promise.resolve();
|
85
|
+
}
|
83
86
|
attach(element) {
|
84
87
|
this.loadRefs(element, { html: 'single' });
|
88
|
+
this.dataReady.then(() => {
|
89
|
+
if (this.element) {
|
90
|
+
this.setContent(this.elemet, this.content);
|
91
|
+
}
|
92
|
+
});
|
85
93
|
return super.attach(element);
|
86
94
|
}
|
87
95
|
}
|
@@ -31,7 +31,6 @@ import PasswordComponent from './password/Password';
|
|
31
31
|
import PhoneNumberComponent from './phonenumber/PhoneNumber';
|
32
32
|
import RadioComponent from './radio/Radio';
|
33
33
|
import ReCaptchaComponent from './recaptcha/ReCaptcha';
|
34
|
-
import ResourceComponent from './resource/Resource';
|
35
34
|
import SelectBoxesComponent from './selectboxes/SelectBoxes';
|
36
35
|
import SelectComponent from './select/Select';
|
37
36
|
import SignatureComponent from './signature/Signature';
|
@@ -80,7 +79,6 @@ export default {
|
|
80
79
|
phoneNumber: PhoneNumberComponent,
|
81
80
|
radio: RadioComponent,
|
82
81
|
recaptcha: ReCaptchaComponent,
|
83
|
-
resource: ResourceComponent,
|
84
82
|
select: SelectComponent,
|
85
83
|
selectboxes: SelectBoxesComponent,
|
86
84
|
signature: SignatureComponent,
|
@@ -55,7 +55,7 @@ export default class ReCaptchaComponent extends Component {
|
|
55
55
|
get skipInEmail() {
|
56
56
|
return true;
|
57
57
|
}
|
58
|
-
verify(actionName) {
|
58
|
+
async verify(actionName) {
|
59
59
|
const siteKey = _get(this.root.form, 'settings.recaptcha.siteKey');
|
60
60
|
if (!siteKey) {
|
61
61
|
console.warn('There is no Site Key specified in settings in form JSON');
|
@@ -65,40 +65,34 @@ export default class ReCaptchaComponent extends Component {
|
|
65
65
|
const recaptchaApiScriptUrl = `https://www.google.com/recaptcha/api.js?render=${_get(this.root.form, 'settings.recaptcha.siteKey')}`;
|
66
66
|
this.recaptchaApiReady = Formio.requireLibrary('googleRecaptcha', 'grecaptcha', recaptchaApiScriptUrl, true);
|
67
67
|
}
|
68
|
-
|
68
|
+
try {
|
69
|
+
await this.recaptchaApiReady;
|
69
70
|
this.recaptchaVerifiedPromise = new Promise((resolve, reject) => {
|
70
|
-
this.
|
71
|
-
.
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
this.isLoading = false;
|
91
|
-
});
|
92
|
-
}, 1000));
|
93
|
-
}
|
94
|
-
})
|
95
|
-
.catch(() => {
|
96
|
-
return reject();
|
97
|
-
});
|
98
|
-
}).then(() => {
|
99
|
-
this.isLoading = false;
|
71
|
+
if (!this.isLoading) {
|
72
|
+
this.isLoading = true;
|
73
|
+
grecaptcha.ready(_debounce(async () => {
|
74
|
+
try {
|
75
|
+
const token = await grecaptcha.execute(siteKey, { action: actionName });
|
76
|
+
const verificationResult = await this.sendVerificationRequest(token);
|
77
|
+
this.recaptchaResult = {
|
78
|
+
...verificationResult,
|
79
|
+
token,
|
80
|
+
};
|
81
|
+
this.updateValue(this.recaptchaResult);
|
82
|
+
this.isLoading = false;
|
83
|
+
return resolve(verificationResult);
|
84
|
+
}
|
85
|
+
catch (err) {
|
86
|
+
this.isLoading = false;
|
87
|
+
reject(err);
|
88
|
+
}
|
89
|
+
}, 1000));
|
90
|
+
}
|
100
91
|
});
|
101
92
|
}
|
93
|
+
catch (err) {
|
94
|
+
this.loading = false;
|
95
|
+
}
|
102
96
|
}
|
103
97
|
beforeSubmit() {
|
104
98
|
if (this.recaptchaVerifiedPromise) {
|
@@ -108,32 +102,27 @@ export default class ReCaptchaComponent extends Component {
|
|
108
102
|
return super.beforeSubmit();
|
109
103
|
}
|
110
104
|
sendVerificationRequest(token) {
|
111
|
-
return Formio.makeStaticRequest(`${Formio.projectUrl}/recaptcha?recaptchaToken=${token}`)
|
112
|
-
.then((verificationResult) => ({ verificationResult, token }));
|
105
|
+
return Formio.makeStaticRequest(`${Formio.projectUrl}/recaptcha?recaptchaToken=${token}`);
|
113
106
|
}
|
114
107
|
checkComponentValidity(data, dirty, row, options = {}, errors = []) {
|
115
108
|
data = data || this.rootValue;
|
116
109
|
row = row || this.data;
|
117
110
|
const { async = false } = options;
|
118
|
-
// Verification could be async only
|
111
|
+
// Verification could be async only (which for now is only the case for server-side validation)
|
119
112
|
if (!async) {
|
120
113
|
return super.checkComponentValidity(data, dirty, row, options, errors);
|
121
114
|
}
|
122
115
|
const componentData = row[this.component.key];
|
123
116
|
if (!componentData || !componentData.token) {
|
124
|
-
this.setCustomValidity('
|
117
|
+
this.setCustomValidity(this.t('reCaptchaTokenNotSpecifiedError'));
|
125
118
|
return Promise.resolve(false);
|
126
119
|
}
|
127
120
|
if (!componentData.success) {
|
128
|
-
this.setCustomValidity('
|
121
|
+
this.setCustomValidity(this.t('reCaptchaTokenValidationError'));
|
129
122
|
return Promise.resolve(false);
|
130
123
|
}
|
131
|
-
|
132
|
-
|
133
|
-
.catch((err) => {
|
134
|
-
this.setCustomValidity(err.message || err);
|
135
|
-
return false;
|
136
|
-
});
|
124
|
+
// Any further validation will 100% not run on the client
|
125
|
+
return Promise.resolve(true);
|
137
126
|
}
|
138
127
|
normalizeValue(newValue) {
|
139
128
|
// If a recaptcha result has already been established, then do not allow it to be reset.
|
@@ -349,6 +349,7 @@ export default class SelectComponent extends ListComponent {
|
|
349
349
|
}
|
350
350
|
/* eslint-disable max-statements */
|
351
351
|
setItems(items, fromSearch) {
|
352
|
+
this.selectItems = items;
|
352
353
|
// If the items is a string, then parse as JSON.
|
353
354
|
if (typeof items == 'string') {
|
354
355
|
try {
|
@@ -817,7 +818,7 @@ export default class SelectComponent extends ListComponent {
|
|
817
818
|
this.addFocusBlurEvents(input);
|
818
819
|
this.triggerUpdate(null, true);
|
819
820
|
if (this.visible) {
|
820
|
-
this.setItems(this.
|
821
|
+
this.setItems(this.selectItems || []);
|
821
822
|
}
|
822
823
|
this.focusableElement = input;
|
823
824
|
if (this.component.dataSrc === 'custom') {
|
@@ -1190,6 +1191,7 @@ export default class SelectComponent extends ListComponent {
|
|
1190
1191
|
templateData[dataValueItemValue] = this.templateData[dataValueItemValue];
|
1191
1192
|
});
|
1192
1193
|
}
|
1194
|
+
templateData[value] = this.templateData[value];
|
1193
1195
|
}
|
1194
1196
|
_.set(submission.metadata.selectData, this.path, templateData);
|
1195
1197
|
}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
export default {
|
2
|
+
_id: '659fa81f4a40147c0ffb949b',
|
3
|
+
title: '7724',
|
4
|
+
name: '7724',
|
5
|
+
path: '7724',
|
6
|
+
type: 'form',
|
7
|
+
display: 'form',
|
8
|
+
components: [
|
9
|
+
{
|
10
|
+
label: 'Select',
|
11
|
+
widget: 'choicesjs',
|
12
|
+
tableView: true,
|
13
|
+
multiple: true,
|
14
|
+
data: {
|
15
|
+
values: [
|
16
|
+
{
|
17
|
+
label: 'Apple',
|
18
|
+
value: 'apple'
|
19
|
+
},
|
20
|
+
{
|
21
|
+
label: 'Orange',
|
22
|
+
value: 'orange'
|
23
|
+
},
|
24
|
+
{
|
25
|
+
label: 'Pear',
|
26
|
+
value: 'pear'
|
27
|
+
}
|
28
|
+
]
|
29
|
+
},
|
30
|
+
key: 'select',
|
31
|
+
type: 'select',
|
32
|
+
input: true
|
33
|
+
},
|
34
|
+
{
|
35
|
+
type: 'button',
|
36
|
+
label: 'Submit',
|
37
|
+
key: 'submit',
|
38
|
+
disableOnInvalid: true,
|
39
|
+
input: true,
|
40
|
+
tableView: false
|
41
|
+
}
|
42
|
+
],
|
43
|
+
project: '63cead09be0090345b109e22'
|
44
|
+
};
|
@@ -0,0 +1,104 @@
|
|
1
|
+
export default {
|
2
|
+
title: 'FIO-7632',
|
3
|
+
name: 'fio7632',
|
4
|
+
path: 'fio7632',
|
5
|
+
type: 'form',
|
6
|
+
display: 'form',
|
7
|
+
components: [
|
8
|
+
{
|
9
|
+
collapsible: false,
|
10
|
+
key: 'panel',
|
11
|
+
type: 'panel',
|
12
|
+
label: 'Panel',
|
13
|
+
input: false,
|
14
|
+
tableView: false,
|
15
|
+
components: [
|
16
|
+
{
|
17
|
+
label: 'Animals',
|
18
|
+
widget: 'html5',
|
19
|
+
tableView: true,
|
20
|
+
data: {
|
21
|
+
values: [
|
22
|
+
{
|
23
|
+
label: 'Dog',
|
24
|
+
value: 'dog',
|
25
|
+
},
|
26
|
+
{
|
27
|
+
label: 'Cat',
|
28
|
+
value: 'cat',
|
29
|
+
},
|
30
|
+
{
|
31
|
+
label: 'Horse',
|
32
|
+
value: 'horse',
|
33
|
+
},
|
34
|
+
],
|
35
|
+
},
|
36
|
+
key: 'animals',
|
37
|
+
type: 'select',
|
38
|
+
input: true,
|
39
|
+
},
|
40
|
+
{
|
41
|
+
label: 'Checkbox',
|
42
|
+
tableView: false,
|
43
|
+
key: 'checkbox',
|
44
|
+
type: 'checkbox',
|
45
|
+
input: true,
|
46
|
+
},
|
47
|
+
{
|
48
|
+
label: 'Animals2',
|
49
|
+
widget: 'html5',
|
50
|
+
tableView: true,
|
51
|
+
data: {
|
52
|
+
values: [
|
53
|
+
{
|
54
|
+
label: 'Dog',
|
55
|
+
value: 'dog',
|
56
|
+
},
|
57
|
+
{
|
58
|
+
label: 'Cat',
|
59
|
+
value: 'cat',
|
60
|
+
},
|
61
|
+
{
|
62
|
+
label: 'Horse',
|
63
|
+
value: 'horse',
|
64
|
+
},
|
65
|
+
],
|
66
|
+
},
|
67
|
+
calculateValue: 'if (data.checkbox === true) {\n value = data.animals;\n}',
|
68
|
+
key: 'animals2',
|
69
|
+
logic: [
|
70
|
+
{
|
71
|
+
name: 'disable',
|
72
|
+
trigger: {
|
73
|
+
type: 'javascript',
|
74
|
+
javascript: 'result = row.checkbox === true;',
|
75
|
+
},
|
76
|
+
actions: [
|
77
|
+
{
|
78
|
+
name: 'disable',
|
79
|
+
type: 'property',
|
80
|
+
property: {
|
81
|
+
label: 'Disabled',
|
82
|
+
value: 'disabled',
|
83
|
+
type: 'boolean',
|
84
|
+
},
|
85
|
+
state: true,
|
86
|
+
},
|
87
|
+
],
|
88
|
+
},
|
89
|
+
],
|
90
|
+
type: 'select',
|
91
|
+
input: true,
|
92
|
+
},
|
93
|
+
{
|
94
|
+
type: 'button',
|
95
|
+
label: 'Submit',
|
96
|
+
key: 'submit',
|
97
|
+
disableOnInvalid: true,
|
98
|
+
input: true,
|
99
|
+
tableView: false,
|
100
|
+
},
|
101
|
+
],
|
102
|
+
},
|
103
|
+
],
|
104
|
+
};
|
@@ -17,4 +17,6 @@ import comp16 from './comp16';
|
|
17
17
|
import comp17 from './comp17';
|
18
18
|
import comp18 from './comp18';
|
19
19
|
import comp19 from './comp19';
|
20
|
-
|
20
|
+
import comp20 from './comp20';
|
21
|
+
import comp21 from './comp21';
|
22
|
+
export { comp1, comp2, comp4, comp5, comp6, comp7, comp8, comp9, comp10, comp11, comp12, comp13, comp14, comp15, comp16, comp17, comp18, comp19, comp20, comp21 };
|
@@ -31,7 +31,7 @@ export default class SelectBoxesComponent extends RadioComponent {
|
|
31
31
|
type: 'select',
|
32
32
|
dataSrc: 'custom',
|
33
33
|
valueProperty: 'value',
|
34
|
-
|
34
|
+
dataType: 'string',
|
35
35
|
data: {
|
36
36
|
custom: `values = ${classComp && classComp.values ? JSON.stringify(classComp.values) : []}`
|
37
37
|
},
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import Input from '../_classes/input/Input';
|
2
2
|
import { conformToMask } from '@formio/vanilla-text-mask';
|
3
|
+
import Inputmask from 'inputmask';
|
3
4
|
import * as FormioUtils from '../../utils/utils';
|
4
5
|
import _ from 'lodash';
|
5
6
|
export default class TextFieldComponent extends Input {
|
@@ -148,8 +149,14 @@ export default class TextFieldComponent extends Input {
|
|
148
149
|
const maskInput = this.refs.select ? this.refs.select[index] : null;
|
149
150
|
const mask = this.getMaskPattern(value.maskName);
|
150
151
|
if (textInput && maskInput && mask) {
|
151
|
-
|
152
|
-
|
152
|
+
if (textInput.inputmask) {
|
153
|
+
this.setInputMask(textInput, mask);
|
154
|
+
textInput.inputmask.setValue(textValue);
|
155
|
+
}
|
156
|
+
else {
|
157
|
+
const placeholderChar = this.placeholderChar;
|
158
|
+
textInput.value = conformToMask(textValue, FormioUtils.getInputMask(mask), { placeholderChar }).conformedValue;
|
159
|
+
}
|
153
160
|
maskInput.value = value.maskName;
|
154
161
|
}
|
155
162
|
else {
|
@@ -180,7 +187,10 @@ export default class TextFieldComponent extends Input {
|
|
180
187
|
if (displayMask && !valueMask) {
|
181
188
|
return this.unmaskValue(value, displayMask);
|
182
189
|
}
|
183
|
-
if (
|
190
|
+
if (displayMask && displayMask !== valueMask) {
|
191
|
+
return Inputmask.format(Inputmask.unmask(value, displayMask), valueMask);
|
192
|
+
}
|
193
|
+
if (this.refs.valueMaskInput?.mask && this.refs.valueMaskInput.mask.textMaskInputElement) {
|
184
194
|
this.refs.valueMaskInput.mask.textMaskInputElement.update(value);
|
185
195
|
return this.refs.valueMaskInput?.value;
|
186
196
|
}
|
@@ -193,6 +203,55 @@ export default class TextFieldComponent extends Input {
|
|
193
203
|
maskName: maskInput ? maskInput.value : undefined
|
194
204
|
};
|
195
205
|
}
|
206
|
+
checkInputMaskValue(inputMask) {
|
207
|
+
let valid = true;
|
208
|
+
const maskValues = _.values(inputMask.split('').reduce((acc, el, i, mask) => {
|
209
|
+
if (el === '{' || el === '}') {
|
210
|
+
if (mask[i + 1] === '{' || mask[i + 1] === '}') {
|
211
|
+
valid = false;
|
212
|
+
}
|
213
|
+
acc[el] = (acc[el] ?? 0) + 1;
|
214
|
+
}
|
215
|
+
return acc;
|
216
|
+
}, {}));
|
217
|
+
if (maskValues[0] !== maskValues[1]) {
|
218
|
+
valid = false;
|
219
|
+
}
|
220
|
+
return valid;
|
221
|
+
}
|
222
|
+
setInputMask(input, inputMask, usePlaceholder) {
|
223
|
+
if (this.type !== 'textfield') {
|
224
|
+
super.setInputMask(input, inputMask, usePlaceholder);
|
225
|
+
return;
|
226
|
+
}
|
227
|
+
inputMask = inputMask || this.component.displayMask || this.component.inputMask;
|
228
|
+
const mask = FormioUtils.getInputMask(inputMask, this.placeholderChar);
|
229
|
+
this.defaultMask = mask;
|
230
|
+
if (input && inputMask) {
|
231
|
+
try {
|
232
|
+
//remove previous mask
|
233
|
+
if (input.mask) {
|
234
|
+
input.mask.remove();
|
235
|
+
}
|
236
|
+
if (this.checkInputMaskValue(inputMask)) {
|
237
|
+
input.mask = new Inputmask(inputMask, {
|
238
|
+
clearMaskOnLostFocus: !!this.component.placeholder,
|
239
|
+
showMaskOnHover: !this.component.placeholder,
|
240
|
+
placeholder: this.placeholderChar || '',
|
241
|
+
}).mask(input);
|
242
|
+
}
|
243
|
+
}
|
244
|
+
catch (e) {
|
245
|
+
console.warn(e);
|
246
|
+
}
|
247
|
+
if (mask.numeric) {
|
248
|
+
input.setAttribute('pattern', '\\d*');
|
249
|
+
}
|
250
|
+
if (this.component.placeholder) {
|
251
|
+
input.setAttribute('placeholder', this.component.placeholder);
|
252
|
+
}
|
253
|
+
}
|
254
|
+
}
|
196
255
|
isHtmlRenderMode() {
|
197
256
|
return super.isHtmlRenderMode() ||
|
198
257
|
((this.options.readOnly || this.disabled) &&
|
@@ -2,7 +2,7 @@ import _ from 'lodash';
|
|
2
2
|
import pdf from '../PDF';
|
3
3
|
import webform from '../Webform';
|
4
4
|
import wizard from '../Wizard';
|
5
|
-
class Displays {
|
5
|
+
export default class Displays {
|
6
6
|
static displays = {
|
7
7
|
pdf,
|
8
8
|
webform,
|
@@ -21,4 +21,3 @@ class Displays {
|
|
21
21
|
return Displays.displays;
|
22
22
|
}
|
23
23
|
}
|
24
|
-
export default Displays;
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import _ from 'lodash';
|
2
|
-
class Licenses {
|
2
|
+
export default class Licenses {
|
3
3
|
static licenses = {};
|
4
4
|
static addLicense(name, license) {
|
5
5
|
Licenses.licenses[name] = license;
|
@@ -14,4 +14,3 @@ class Licenses {
|
|
14
14
|
return Licenses.licenses;
|
15
15
|
}
|
16
16
|
}
|
17
|
-
export default Licenses;
|
@@ -2,7 +2,7 @@ import _ from 'lodash';
|
|
2
2
|
import address from './address';
|
3
3
|
import auth from './auth';
|
4
4
|
import storage from './storage';
|
5
|
-
class Providers {
|
5
|
+
export default class Providers {
|
6
6
|
static providers = {
|
7
7
|
address,
|
8
8
|
auth,
|
@@ -26,4 +26,3 @@ class Providers {
|
|
26
26
|
}
|
27
27
|
}
|
28
28
|
}
|
29
|
-
export default Providers;
|
@@ -31,9 +31,11 @@ function s3(formio) {
|
|
31
31
|
else {
|
32
32
|
xhr.openAndSetHeaders('PUT', response.signed);
|
33
33
|
xhr.setRequestHeader('Content-Type', file.type);
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
if (response.data.headers) {
|
35
|
+
Object.keys(response.data.headers).forEach((key) => {
|
36
|
+
xhr.setRequestHeader(key, response.data.headers[key]);
|
37
|
+
});
|
38
|
+
}
|
37
39
|
return file;
|
38
40
|
}
|
39
41
|
}
|
@@ -1,4 +1,18 @@
|
|
1
1
|
function url(formio) {
|
2
|
+
function setOptions(options, xhr) {
|
3
|
+
const parsedOptions = typeof options === 'string' ? JSON.parse(options) : options;
|
4
|
+
for (const prop in parsedOptions) {
|
5
|
+
if (prop === 'headers') {
|
6
|
+
const headers = parsedOptions['headers'];
|
7
|
+
for (const header in headers) {
|
8
|
+
xhr.setRequestHeader(header, headers[header]);
|
9
|
+
}
|
10
|
+
}
|
11
|
+
else {
|
12
|
+
xhr[prop] = parsedOptions[prop];
|
13
|
+
}
|
14
|
+
}
|
15
|
+
}
|
2
16
|
const xhrRequest = (url, name, query, data, options, progressCallback, abortCallback) => {
|
3
17
|
return new Promise((resolve, reject) => {
|
4
18
|
const xhr = new XMLHttpRequest();
|
@@ -57,18 +71,7 @@ function url(formio) {
|
|
57
71
|
}
|
58
72
|
//Overrides previous request props
|
59
73
|
if (options) {
|
60
|
-
|
61
|
-
for (const prop in parsedOptions) {
|
62
|
-
if (prop === 'headers') {
|
63
|
-
const headers = parsedOptions['headers'];
|
64
|
-
for (const header in headers) {
|
65
|
-
xhr.setRequestHeader(header, headers[header]);
|
66
|
-
}
|
67
|
-
}
|
68
|
-
else {
|
69
|
-
xhr[prop] = parsedOptions[prop];
|
70
|
-
}
|
71
|
-
}
|
74
|
+
setOptions(options, xhr);
|
72
75
|
}
|
73
76
|
xhr.send(json ? data : fd);
|
74
77
|
});
|
@@ -109,7 +112,7 @@ function url(formio) {
|
|
109
112
|
return uploadRequest();
|
110
113
|
}
|
111
114
|
},
|
112
|
-
deleteFile(fileInfo) {
|
115
|
+
deleteFile(fileInfo, options) {
|
113
116
|
return new Promise((resolve, reject) => {
|
114
117
|
const xhr = new XMLHttpRequest();
|
115
118
|
xhr.open('DELETE', fileInfo.url, true);
|
@@ -121,6 +124,9 @@ function url(formio) {
|
|
121
124
|
reject(xhr.response || 'Unable to delete file');
|
122
125
|
}
|
123
126
|
};
|
127
|
+
if (options) {
|
128
|
+
setOptions(options, xhr);
|
129
|
+
}
|
124
130
|
xhr.send(null);
|
125
131
|
});
|
126
132
|
},
|