@formio/js 5.2.0 → 5.2.1-rc.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 +15 -17
- 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 +15 -17
- package/dist/formio.form.js +31 -31
- package/dist/formio.form.min.css +1 -1
- package/dist/formio.form.min.js +1 -1
- package/dist/formio.form.min.js.LICENSE.txt +3 -3
- package/dist/formio.full.css +15 -17
- package/dist/formio.full.js +32 -32
- package/dist/formio.full.min.css +1 -1
- package/dist/formio.full.min.js +1 -1
- package/dist/formio.full.min.js.LICENSE.txt +3 -3
- package/dist/formio.js +6 -6
- package/dist/formio.min.js +1 -1
- package/dist/formio.min.js.LICENSE.txt +1 -1
- package/dist/formio.utils.js +5 -5
- package/dist/formio.utils.min.js +1 -1
- package/dist/formio.utils.min.js.LICENSE.txt +1 -1
- package/lib/cjs/Embed.js +1 -1
- package/lib/cjs/Formio.js +1 -1
- package/lib/cjs/Webform.js +2 -1
- package/lib/cjs/WebformBuilder.js +18 -11
- package/lib/cjs/Wizard.d.ts +1 -2
- package/lib/cjs/Wizard.js +17 -23
- package/lib/cjs/components/Components.js +1 -1
- package/lib/cjs/components/_classes/component/Component.d.ts +23 -2
- package/lib/cjs/components/_classes/component/Component.js +61 -35
- package/lib/cjs/components/_classes/nested/NestedComponent.js +2 -2
- package/lib/cjs/components/file/File.d.ts +1 -1
- package/lib/cjs/components/file/File.js +6 -1
- package/lib/cjs/components/form/Form.d.ts +0 -2
- package/lib/cjs/components/form/Form.js +12 -20
- package/lib/cjs/components/select/Select.d.ts +0 -1
- package/lib/cjs/components/select/Select.js +3 -23
- package/lib/cjs/components/tags/Tags.d.ts +1 -1
- package/lib/cjs/components/tags/Tags.js +2 -2
- package/lib/cjs/formio.form.js +1 -0
- package/lib/cjs/utils/ChoicesWrapper.d.ts +4 -25
- package/lib/cjs/utils/ChoicesWrapper.js +47 -124
- package/lib/cjs/utils/formUtils.d.ts +2 -2
- package/lib/cjs/utils/index.d.ts +4 -4
- package/lib/cjs/utils/utils.d.ts +4 -4
- package/lib/cjs/utils/utils.js +2 -2
- package/lib/cjs/widgets/CalendarWidget.d.ts +1 -1
- package/lib/cjs/widgets/CalendarWidget.js +1 -1
- package/lib/mjs/Embed.js +1 -1
- package/lib/mjs/Formio.js +1 -1
- package/lib/mjs/Webform.js +1 -1
- package/lib/mjs/WebformBuilder.js +19 -12
- package/lib/mjs/Wizard.d.ts +1 -2
- package/lib/mjs/Wizard.js +16 -22
- package/lib/mjs/components/Components.js +1 -1
- package/lib/mjs/components/_classes/component/Component.d.ts +23 -2
- package/lib/mjs/components/_classes/component/Component.js +61 -35
- package/lib/mjs/components/_classes/nested/NestedComponent.js +2 -2
- package/lib/mjs/components/file/File.d.ts +1 -1
- package/lib/mjs/components/file/File.js +6 -1
- package/lib/mjs/components/form/Form.d.ts +0 -2
- package/lib/mjs/components/form/Form.js +12 -20
- package/lib/mjs/components/select/Select.d.ts +0 -1
- package/lib/mjs/components/select/Select.js +3 -22
- package/lib/mjs/components/tags/Tags.d.ts +1 -1
- package/lib/mjs/components/tags/Tags.js +2 -2
- package/lib/mjs/formio.form.js +1 -0
- package/lib/mjs/utils/ChoicesWrapper.d.ts +4 -25
- package/lib/mjs/utils/ChoicesWrapper.js +26 -119
- package/lib/mjs/utils/formUtils.d.ts +2 -2
- package/lib/mjs/utils/index.d.ts +4 -4
- package/lib/mjs/utils/utils.d.ts +4 -4
- package/lib/mjs/utils/utils.js +2 -2
- package/lib/mjs/widgets/CalendarWidget.d.ts +1 -1
- package/lib/mjs/widgets/CalendarWidget.js +1 -1
- package/package.json +5 -5
@@ -420,12 +420,14 @@ export default class Component extends Element {
|
|
420
420
|
}
|
421
421
|
/**
|
422
422
|
* Returns if the parent should conditionally clear.
|
423
|
+
*
|
423
424
|
* @returns {boolean} - If the parent should conditionally clear.
|
424
425
|
*/
|
425
426
|
parentShouldConditionallyClear() {
|
426
427
|
let currentParent = this.parent;
|
427
428
|
while (currentParent) {
|
428
|
-
if (currentParent.
|
429
|
+
if ((currentParent.allowData && currentParent._conditionallyClear) ||
|
430
|
+
(!currentParent.allowData && currentParent._conditionallyHidden)) {
|
429
431
|
return true;
|
430
432
|
}
|
431
433
|
currentParent = currentParent.parent;
|
@@ -435,7 +437,21 @@ export default class Component extends Element {
|
|
435
437
|
parentConditionallyHidden() {
|
436
438
|
let currentParent = this.parent;
|
437
439
|
while (currentParent) {
|
438
|
-
if (currentParent.
|
440
|
+
if (currentParent._conditionallyHidden) {
|
441
|
+
return true;
|
442
|
+
}
|
443
|
+
currentParent = currentParent.parent;
|
444
|
+
}
|
445
|
+
return false;
|
446
|
+
}
|
447
|
+
/**
|
448
|
+
* Returns true if any of the parents default their component "hidden" property to true.
|
449
|
+
* @returns {boolean} - If any parent defaults the hidden property to true.
|
450
|
+
*/
|
451
|
+
anyParentDefaultsHidden() {
|
452
|
+
let currentParent = this.parent;
|
453
|
+
while (currentParent) {
|
454
|
+
if (currentParent.component.hidden) {
|
439
455
|
return true;
|
440
456
|
}
|
441
457
|
currentParent = currentParent.parent;
|
@@ -650,48 +666,58 @@ export default class Component extends Element {
|
|
650
666
|
}
|
651
667
|
return this._logicallyHidden;
|
652
668
|
}
|
653
|
-
|
669
|
+
/**
|
670
|
+
* Determines if the component should clear its value when the root form is pristine.
|
671
|
+
* @returns {boolean} - If the component should clear its value when the root form is pristine.
|
672
|
+
*/
|
673
|
+
shouldConditionallyClearOnPristine() {
|
674
|
+
// If the form is pristine, we should NOT clear the value of a conditionally hidden child component
|
675
|
+
// of a layout component that defaults to hidden using the "hidden" component property.
|
676
|
+
return !this.anyParentDefaultsHidden();
|
677
|
+
}
|
678
|
+
/**
|
679
|
+
* Returns if the component should clear its value when conditionally hidden.
|
680
|
+
* @returns {boolean} - If the component should clear its value when conditionally hidden.
|
681
|
+
*/
|
682
|
+
shouldConditionallyClear() {
|
654
683
|
// Skip if this component has clearOnHide set to false.
|
655
684
|
if (this.component.clearOnHide === false) {
|
656
|
-
|
685
|
+
this._conditionallyClear = false;
|
686
|
+
return this._conditionallyClear;
|
657
687
|
}
|
658
688
|
// If the component is logically hidden, then it is conditionally hidden and should clear.
|
659
689
|
if (this.logicallyHidden) {
|
660
|
-
|
690
|
+
this._conditionallyClear = true;
|
691
|
+
return this._conditionallyClear;
|
661
692
|
}
|
662
693
|
// If we have a condition and it is not conditionally visible, the it should conditionally clear.
|
663
|
-
if (this.hasCondition() &&
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
return false;
|
669
|
-
}
|
670
|
-
// If this component has a set value, then it should ONLY clear if a parent is hidden
|
671
|
-
// and has the clearOnHide set to true.
|
672
|
-
if (this.hasSetValue) {
|
673
|
-
return this.parentShouldConditionallyClear();
|
694
|
+
if (this.hasCondition() &&
|
695
|
+
!this.conditionallyVisible() &&
|
696
|
+
(!this.rootPristine || this.shouldConditionallyClearOnPristine())) {
|
697
|
+
this._conditionallyClear = true;
|
698
|
+
return this._conditionallyClear;
|
674
699
|
}
|
675
|
-
|
676
|
-
return this.
|
700
|
+
this._conditionallyClear = this.hasSetValue ? false : this.parentShouldConditionallyClear();
|
701
|
+
return this._conditionallyClear;
|
677
702
|
}
|
678
|
-
|
703
|
+
/**
|
704
|
+
* Returns if the component is conditionally hidden.
|
705
|
+
* @returns {boolean} - If the component is conditionally hidden.
|
706
|
+
*/
|
707
|
+
conditionallyHidden() {
|
708
|
+
// If it is logically hidden, then it is conditionally hidden.
|
679
709
|
if (this.logicallyHidden) {
|
680
|
-
|
710
|
+
this._conditionallyHidden = true;
|
711
|
+
return this._conditionallyHidden;
|
681
712
|
}
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
if (!this.conditionallyVisible()) {
|
687
|
-
return true;
|
688
|
-
}
|
689
|
-
if (skipParent) {
|
690
|
-
// Stop recurrsion for the parent checks.
|
691
|
-
return false;
|
713
|
+
// If it has a condition, and is not conditionally visible, then it is conditionally hidden.
|
714
|
+
if (this.hasCondition() && !this.conditionallyVisible()) {
|
715
|
+
this._conditionallyHidden = true;
|
716
|
+
return this._conditionallyHidden;
|
692
717
|
}
|
693
|
-
//
|
694
|
-
|
718
|
+
// It is conditionally hidden if its parent is conditionally hidden.
|
719
|
+
this._conditionallyHidden = this.parentConditionallyHidden();
|
720
|
+
return this._conditionallyHidden;
|
695
721
|
}
|
696
722
|
get currentForm() {
|
697
723
|
return this._currentForm;
|
@@ -3162,6 +3188,9 @@ export default class Component extends Element {
|
|
3162
3188
|
data = data || this.rootValue;
|
3163
3189
|
flags = flags || {};
|
3164
3190
|
row = row || this.data;
|
3191
|
+
if (flags.noCheck) {
|
3192
|
+
return true;
|
3193
|
+
}
|
3165
3194
|
// Some components (for legacy reasons) have calls to "checkData" in inappropriate places such
|
3166
3195
|
// as setValue. Historically, this was bypassed by a series of cached states around the data model
|
3167
3196
|
// which caused its own problems. We need to ensure that premium and custom components do not fall into
|
@@ -3176,9 +3205,6 @@ export default class Component extends Element {
|
|
3176
3205
|
if (!flags.fromBlur) {
|
3177
3206
|
this.checkRefreshOn(flags.changes, flags);
|
3178
3207
|
}
|
3179
|
-
if (flags.noCheck) {
|
3180
|
-
return true;
|
3181
|
-
}
|
3182
3208
|
this.checkComponentConditions(data, flags, row);
|
3183
3209
|
if (this.id !== flags.triggeredComponentId) {
|
3184
3210
|
this.calculateComponentValue(data, flags, row);
|
@@ -667,7 +667,7 @@ export default class NestedComponent extends Field {
|
|
667
667
|
}
|
668
668
|
validationProcessor({ scope, data, row, instance, paths }, flags) {
|
669
669
|
const { dirty } = flags;
|
670
|
-
if (this.root.
|
670
|
+
if (this.root && this.root.hasSubWizards && this.page !== this.root.page) {
|
671
671
|
instance = this.componentsMap?.hasOwnProperty(paths.dataPath)
|
672
672
|
? this.componentsMap[paths.dataPath]
|
673
673
|
: this.getComponent(paths.dataPath);
|
@@ -816,7 +816,7 @@ export default class NestedComponent extends Field {
|
|
816
816
|
return false;
|
817
817
|
}
|
818
818
|
if (component.type === 'components') {
|
819
|
-
if (component.tree && component.hasValue(value)) {
|
819
|
+
if ((component.tree || component.hasInput) && component.hasValue(value)) {
|
820
820
|
return component.setValue(_.get(value, component.key), flags);
|
821
821
|
}
|
822
822
|
return component.setValue(value, flags);
|
@@ -33,7 +33,7 @@ export default class FileComponent extends Field {
|
|
33
33
|
get dataReady(): Promise<any>;
|
34
34
|
loadImage(fileInfo: any): any;
|
35
35
|
get emptyValue(): never[];
|
36
|
-
getValueAsString(value: any): any;
|
36
|
+
getValueAsString(value: any, options: any): any;
|
37
37
|
get defaultValue(): any[];
|
38
38
|
get hasTypes(): any;
|
39
39
|
_fileBrowseHidden: any;
|
@@ -103,7 +103,12 @@ export default class FileComponent extends Field {
|
|
103
103
|
get emptyValue() {
|
104
104
|
return [];
|
105
105
|
}
|
106
|
-
getValueAsString(value) {
|
106
|
+
getValueAsString(value, options) {
|
107
|
+
if (options?.review && !this.component.uploadOnly) {
|
108
|
+
return _.map(value, (val, index) => {
|
109
|
+
return `<a href="${val.url || '#'}" target="_blank" data-path='${this.path}' data-fileindex='${index}'>${val.originalName}</a>`;
|
110
|
+
}).join(', ');
|
111
|
+
}
|
107
112
|
if (_.isArray(value)) {
|
108
113
|
return _.map(value, 'originalName').join(', ');
|
109
114
|
}
|
@@ -98,8 +98,6 @@ export default class FormComponent extends Component {
|
|
98
98
|
* @returns {void}
|
99
99
|
*/
|
100
100
|
onSetSubFormValue(submission: object | null | undefined, flags: object | null | undefined): void;
|
101
|
-
areAllComponentsEmpty(data: any): boolean;
|
102
|
-
conditionallyHidden(): boolean;
|
103
101
|
updateSubFormVisibility(): void;
|
104
102
|
/**
|
105
103
|
* Determines if this form is a Nested Wizard
|
@@ -96,6 +96,9 @@ export default class FormComponent extends Component {
|
|
96
96
|
}
|
97
97
|
return this.createSubForm();
|
98
98
|
}
|
99
|
+
shouldConditionallyClearOnPristine() {
|
100
|
+
return !this.hasSetValue && super.shouldConditionallyClearOnPristine();
|
101
|
+
}
|
99
102
|
get dataReady() {
|
100
103
|
return this.subFormReady || Promise.resolve();
|
101
104
|
}
|
@@ -289,11 +292,13 @@ export default class FormComponent extends Component {
|
|
289
292
|
}
|
290
293
|
this.subForm.attach(element);
|
291
294
|
this.valueChanged = this.hasSetValue;
|
292
|
-
if (!this.
|
293
|
-
this.
|
294
|
-
|
295
|
-
|
296
|
-
|
295
|
+
if (!this.shouldConditionallyClear()) {
|
296
|
+
if (!this.valueChanged && this.dataValue.state !== 'submitted') {
|
297
|
+
this.setDefaultValue();
|
298
|
+
}
|
299
|
+
else {
|
300
|
+
this.restoreValue();
|
301
|
+
}
|
297
302
|
}
|
298
303
|
}
|
299
304
|
if (!this.builderMode && this.component.modalEdit) {
|
@@ -409,7 +414,7 @@ export default class FormComponent extends Component {
|
|
409
414
|
this.component.components = this.subForm._form?.components;
|
410
415
|
this.component.display = this.subForm._form?.display;
|
411
416
|
this.subForm.on('change', () => {
|
412
|
-
if (this.subForm) {
|
417
|
+
if (this.subForm && !this.shouldConditionallyClear()) {
|
413
418
|
this.dataValue = this.subForm.getValue();
|
414
419
|
this.triggerChange({
|
415
420
|
noEmit: true
|
@@ -669,20 +674,7 @@ export default class FormComponent extends Component {
|
|
669
674
|
this.subForm.setValue(submission, flags);
|
670
675
|
}
|
671
676
|
isEmpty(value = this.dataValue) {
|
672
|
-
return value === null || _.isEqual(value, this.emptyValue)
|
673
|
-
}
|
674
|
-
areAllComponentsEmpty(data) {
|
675
|
-
let res = true;
|
676
|
-
if (this.subForm) {
|
677
|
-
this.subForm.everyComponent((comp) => {
|
678
|
-
const componentValue = _.get(data, comp.key);
|
679
|
-
res &= comp.isEmpty(componentValue);
|
680
|
-
});
|
681
|
-
}
|
682
|
-
else {
|
683
|
-
res = false;
|
684
|
-
}
|
685
|
-
return res;
|
677
|
+
return value === null || _.isEqual(value, this.emptyValue);
|
686
678
|
}
|
687
679
|
getValue() {
|
688
680
|
if (this.subForm) {
|
@@ -126,7 +126,6 @@ export default class SelectComponent extends ListComponent {
|
|
126
126
|
get isLoadingAvailable(): any;
|
127
127
|
onScroll(): void;
|
128
128
|
attachRefreshOnBlur(): void;
|
129
|
-
addPlaceholderItem(placeholderValue: any): void;
|
130
129
|
update(): void;
|
131
130
|
addCurrentChoices(values: any, items: any, keyValue: any): any;
|
132
131
|
getValueAsString(data: any, options: any): any;
|
@@ -773,8 +773,8 @@ export default class SelectComponent extends ListComponent {
|
|
773
773
|
removeItemButton: this.component.disabled ? false : _.get(this.component, 'removeItemButton', true),
|
774
774
|
itemSelectText: '',
|
775
775
|
classNames: {
|
776
|
-
containerOuter: 'choices form-group formio-choices',
|
777
|
-
containerInner: this.transform('class', 'form-control ui fluid selection dropdown')
|
776
|
+
containerOuter: ['choices', 'form-group', 'formio-choices'],
|
777
|
+
containerInner: this.transform('class', 'form-control ui fluid selection dropdown').split(' '),
|
778
778
|
},
|
779
779
|
addItemText: false,
|
780
780
|
allowHTML: true,
|
@@ -802,6 +802,7 @@ export default class SelectComponent extends ListComponent {
|
|
802
802
|
}),
|
803
803
|
valueComparer: _.isEqual,
|
804
804
|
resetScrollPosition: false,
|
805
|
+
duplicateItemsAllowed: false,
|
805
806
|
...customOptions,
|
806
807
|
};
|
807
808
|
}
|
@@ -934,12 +935,6 @@ export default class SelectComponent extends ListComponent {
|
|
934
935
|
this.positionDropdown();
|
935
936
|
});
|
936
937
|
}
|
937
|
-
if (this.choices && choicesOptions.placeholderValue && this.choices._isSelectOneElement) {
|
938
|
-
this.addPlaceholderItem(choicesOptions.placeholderValue);
|
939
|
-
this.addEventListener(input, 'removeItem', () => {
|
940
|
-
this.addPlaceholderItem(choicesOptions.placeholderValue);
|
941
|
-
});
|
942
|
-
}
|
943
938
|
// Add value options.
|
944
939
|
this.addValueOptions();
|
945
940
|
this.setChoicesValue(this.dataValue);
|
@@ -1025,20 +1020,6 @@ export default class SelectComponent extends ListComponent {
|
|
1025
1020
|
});
|
1026
1021
|
}
|
1027
1022
|
}
|
1028
|
-
addPlaceholderItem(placeholderValue) {
|
1029
|
-
const items = this.choices._store.activeItems;
|
1030
|
-
if (!items.length) {
|
1031
|
-
this.choices._addItem({
|
1032
|
-
value: '',
|
1033
|
-
label: placeholderValue,
|
1034
|
-
choiceId: 0,
|
1035
|
-
groupId: -1,
|
1036
|
-
customProperties: null,
|
1037
|
-
placeholder: true,
|
1038
|
-
keyCode: null
|
1039
|
-
});
|
1040
|
-
}
|
1041
|
-
}
|
1042
1023
|
/* eslint-enable max-statements */
|
1043
1024
|
update() {
|
1044
1025
|
if (this.component.dataSrc === 'custom') {
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { componentValueTypes, getComponentSavedTypes } from '../../utils';
|
2
2
|
import Input from '../_classes/input/Input';
|
3
|
-
import Choices from '
|
3
|
+
import Choices from 'choices.js';
|
4
4
|
export default class TagsComponent extends Input {
|
5
5
|
static schema(...extend) {
|
6
6
|
return Input.schema({
|
@@ -127,7 +127,7 @@ export default class TagsComponent extends Input {
|
|
127
127
|
const changed = super.setValue(value, flags);
|
128
128
|
if (this.choices) {
|
129
129
|
let dataValue = this.dataValue;
|
130
|
-
this.choices.
|
130
|
+
this.choices.clearStore();
|
131
131
|
if (dataValue) {
|
132
132
|
if (typeof dataValue === 'string') {
|
133
133
|
dataValue = dataValue.split(this.delimiter).filter(result => result);
|
package/lib/mjs/formio.form.js
CHANGED
@@ -56,6 +56,7 @@ export function registerModule(mod, defaultFn = null, options = {}) {
|
|
56
56
|
case 'templates':
|
57
57
|
for (const framework of Object.keys(mod.templates)) {
|
58
58
|
Formio.Templates.extendTemplate(framework, mod.templates[framework]);
|
59
|
+
Formio.Templates.defaultTemplates = _.defaults(mod.templates[framework], Formio.Templates.defaultTemplates);
|
59
60
|
}
|
60
61
|
if (mod.templates[current]) {
|
61
62
|
Formio.Templates.current = mod.templates[current];
|
@@ -1,38 +1,17 @@
|
|
1
|
-
export namespace KEY_CODES {
|
2
|
-
let BACK_KEY: number;
|
3
|
-
let DELETE_KEY: number;
|
4
|
-
let TAB_KEY: number;
|
5
|
-
let ENTER_KEY: number;
|
6
|
-
let A_KEY: number;
|
7
|
-
let ESC_KEY: number;
|
8
|
-
let UP_KEY: number;
|
9
|
-
let DOWN_KEY: number;
|
10
|
-
let PAGE_UP_KEY: number;
|
11
|
-
let PAGE_DOWN_KEY: number;
|
12
|
-
}
|
13
1
|
export default ChoicesWrapper;
|
14
2
|
declare class ChoicesWrapper extends Choices {
|
15
3
|
constructor(...args: any[]);
|
16
|
-
_onTabKey(
|
17
|
-
activeItems: any;
|
18
|
-
hasActiveDropdown: any;
|
19
|
-
}): void;
|
4
|
+
_onTabKey(): void;
|
20
5
|
isDirectionUsing: boolean;
|
21
6
|
shouldOpenDropDown: boolean;
|
22
7
|
_onTouchEnd(event: any): void;
|
23
|
-
|
24
|
-
_onEnterKey(args: any): void;
|
8
|
+
_onEnterKey(...args: any[]): void;
|
25
9
|
_onDirectionKey(...args: any[]): void;
|
26
10
|
timeout: NodeJS.Timeout | undefined;
|
27
11
|
_selectHighlightedChoice(): void;
|
28
12
|
_onKeyDown(event: any): void;
|
29
|
-
onSelectValue(
|
30
|
-
event: any;
|
31
|
-
activeItems: any;
|
32
|
-
hasActiveDropdown: any;
|
33
|
-
}): void;
|
13
|
+
onSelectValue(event: any, hasActiveDropdown: any): void;
|
34
14
|
showDropdown(...args: any[]): void;
|
35
15
|
hideDropdown(...args: any[]): void;
|
36
|
-
_onBlur(...args: any[]): void;
|
37
16
|
}
|
38
|
-
import Choices from '
|
17
|
+
import Choices from 'choices.js';
|
@@ -1,41 +1,7 @@
|
|
1
|
-
import Choices from '
|
2
|
-
|
3
|
-
|
4
|
-
*
|
5
|
-
* https://github.com/jshjohnson/Choices/pull/788
|
6
|
-
*
|
7
|
-
* This is intentionally not part of the extended class, since other components use Choices and need this fix as well.
|
8
|
-
* @type {Choices._generatePlaceholderValue}
|
9
|
-
* @private
|
10
|
-
*/
|
11
|
-
Choices.prototype._generatePlaceholderValue = function () {
|
12
|
-
if (this._isSelectElement && this.passedElement.placeholderOption) {
|
13
|
-
const { placeholderOption } = this.passedElement;
|
14
|
-
return placeholderOption ? placeholderOption.text : false;
|
15
|
-
}
|
16
|
-
const { placeholder, placeholderValue } = this.config;
|
17
|
-
const { element: { dataset }, } = this.passedElement;
|
18
|
-
if (placeholder) {
|
19
|
-
if (placeholderValue) {
|
20
|
-
return placeholderValue;
|
21
|
-
}
|
22
|
-
if (dataset.placeholder) {
|
23
|
-
return dataset.placeholder;
|
24
|
-
}
|
25
|
-
}
|
26
|
-
return false;
|
27
|
-
};
|
28
|
-
export const KEY_CODES = {
|
29
|
-
BACK_KEY: 46,
|
30
|
-
DELETE_KEY: 8,
|
1
|
+
import Choices, { KeyCodeMap } from 'choices.js';
|
2
|
+
const ExtendedKeyCodeMap = {
|
3
|
+
...KeyCodeMap,
|
31
4
|
TAB_KEY: 9,
|
32
|
-
ENTER_KEY: 13,
|
33
|
-
A_KEY: 65,
|
34
|
-
ESC_KEY: 27,
|
35
|
-
UP_KEY: 38,
|
36
|
-
DOWN_KEY: 40,
|
37
|
-
PAGE_UP_KEY: 33,
|
38
|
-
PAGE_DOWN_KEY: 34,
|
39
5
|
};
|
40
6
|
class ChoicesWrapper extends Choices {
|
41
7
|
constructor(...args) {
|
@@ -63,24 +29,13 @@ class ChoicesWrapper extends Choices {
|
|
63
29
|
}
|
64
30
|
this._wasTap = true;
|
65
31
|
}
|
66
|
-
|
67
|
-
|
68
|
-
return super._handleButtonAction(activeItems, element);
|
69
|
-
}
|
70
|
-
if (!activeItems ||
|
71
|
-
!element ||
|
72
|
-
!this.config.removeItems ||
|
73
|
-
!this.config.removeItemButton) {
|
74
|
-
return;
|
75
|
-
}
|
76
|
-
super._handleButtonAction(activeItems, element);
|
77
|
-
}
|
78
|
-
_onEnterKey(args) {
|
32
|
+
_onEnterKey(...args) {
|
33
|
+
const [event] = args;
|
79
34
|
// Prevent dropdown form opening when removeItemButton was pressed using 'Enter' on keyboard
|
80
|
-
if (
|
35
|
+
if (event.target.className === 'choices__button') {
|
81
36
|
this.shouldOpenDropDown = false;
|
82
37
|
}
|
83
|
-
super._onEnterKey(args);
|
38
|
+
super._onEnterKey(...args);
|
84
39
|
}
|
85
40
|
_onDirectionKey(...args) {
|
86
41
|
if (!this._isSelectOneElement) {
|
@@ -94,17 +49,18 @@ class ChoicesWrapper extends Choices {
|
|
94
49
|
this.isDirectionUsing = false;
|
95
50
|
}, 250);
|
96
51
|
}
|
97
|
-
_onTabKey(
|
98
|
-
if (
|
99
|
-
this._selectHighlightedChoice(
|
52
|
+
_onTabKey() {
|
53
|
+
if (this.dropdown.isActive) {
|
54
|
+
this._selectHighlightedChoice();
|
100
55
|
}
|
101
56
|
}
|
102
57
|
_selectHighlightedChoice() {
|
103
|
-
const highlightedChoice = this.dropdown.
|
58
|
+
const highlightedChoice = this.dropdown.element.querySelector(`.${this.config.classNames.highlightedState}`);
|
104
59
|
if (highlightedChoice) {
|
105
60
|
const id = highlightedChoice.dataset.id;
|
106
|
-
const choice = id && this._store.getChoiceById(id);
|
61
|
+
const choice = id && this._store.getChoiceById(Number(id));
|
107
62
|
this._addItem({
|
63
|
+
id: choice.id,
|
108
64
|
value: choice.value,
|
109
65
|
label: choice.label,
|
110
66
|
choiceId: choice.id,
|
@@ -115,61 +71,16 @@ class ChoicesWrapper extends Choices {
|
|
115
71
|
});
|
116
72
|
this._triggerChange(choice.value);
|
117
73
|
}
|
118
|
-
event.preventDefault();
|
119
74
|
}
|
120
75
|
_onKeyDown(event) {
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
if (target !== this.input.element &&
|
126
|
-
!this.containerOuter.element.contains(target)) {
|
127
|
-
return;
|
128
|
-
}
|
129
|
-
const activeItems = this._store.activeItems;
|
130
|
-
const hasFocusedInput = this.input.isFocussed;
|
131
|
-
const hasActiveDropdown = this.dropdown.isActive;
|
132
|
-
const hasItems = this.itemList.hasChildren;
|
133
|
-
const keyString = String.fromCharCode(keyCode);
|
134
|
-
const { BACK_KEY, DELETE_KEY, TAB_KEY, ENTER_KEY, A_KEY, ESC_KEY, UP_KEY, DOWN_KEY, PAGE_UP_KEY, PAGE_DOWN_KEY, } = KEY_CODES;
|
135
|
-
const hasCtrlDownKeyPressed = ctrlKey || metaKey;
|
136
|
-
// If a user is typing and the dropdown is not active
|
137
|
-
if (!hasActiveDropdown && !this._isTextElement && /[a-zA-Z0-9-_ ]/.test(keyString)) {
|
138
|
-
const currentValue = this.input.element.value;
|
139
|
-
this.input.element.value = currentValue ? `${currentValue}${keyString}` : keyString;
|
140
|
-
this.showDropdown();
|
141
|
-
}
|
142
|
-
// Map keys to key actions
|
143
|
-
const keyDownActions = {
|
144
|
-
[A_KEY]: this._onAKey,
|
145
|
-
[TAB_KEY]: this._onTabKey,
|
146
|
-
[ENTER_KEY]: this._onEnterKey,
|
147
|
-
[ESC_KEY]: this._onEscapeKey,
|
148
|
-
[UP_KEY]: this._onDirectionKey,
|
149
|
-
[PAGE_UP_KEY]: this._onDirectionKey,
|
150
|
-
[DOWN_KEY]: this._onDirectionKey,
|
151
|
-
[PAGE_DOWN_KEY]: this._onDirectionKey,
|
152
|
-
[DELETE_KEY]: this._onDeleteKey,
|
153
|
-
[BACK_KEY]: this._onDeleteKey,
|
154
|
-
};
|
155
|
-
// If keycode has a function, run it
|
156
|
-
if (keyDownActions[keyCode]) {
|
157
|
-
keyDownActions[keyCode]({
|
158
|
-
event,
|
159
|
-
target,
|
160
|
-
keyCode,
|
161
|
-
metaKey,
|
162
|
-
activeItems,
|
163
|
-
hasFocusedInput,
|
164
|
-
hasActiveDropdown,
|
165
|
-
hasItems,
|
166
|
-
hasCtrlDownKeyPressed,
|
167
|
-
});
|
168
|
-
}
|
76
|
+
const keyCode = event.keyCode;
|
77
|
+
return this._isSelectOneElement && keyCode === ExtendedKeyCodeMap.TAB_KEY
|
78
|
+
? this._onTabKey()
|
79
|
+
: super._onKeyDown(event);
|
169
80
|
}
|
170
|
-
onSelectValue(
|
81
|
+
onSelectValue(event, hasActiveDropdown) {
|
171
82
|
if (hasActiveDropdown) {
|
172
|
-
this._selectHighlightedChoice(
|
83
|
+
this._selectHighlightedChoice();
|
173
84
|
}
|
174
85
|
else if (this._isSelectOneElement) {
|
175
86
|
this.showDropdown();
|
@@ -177,11 +88,13 @@ class ChoicesWrapper extends Choices {
|
|
177
88
|
}
|
178
89
|
}
|
179
90
|
showDropdown(...args) {
|
180
|
-
|
181
|
-
this.shouldOpenDropDown
|
182
|
-
|
183
|
-
|
184
|
-
|
91
|
+
setTimeout(() => {
|
92
|
+
if (!this.shouldOpenDropDown) {
|
93
|
+
this.shouldOpenDropDown = true;
|
94
|
+
return;
|
95
|
+
}
|
96
|
+
super.showDropdown(...args);
|
97
|
+
}, 0);
|
185
98
|
}
|
186
99
|
hideDropdown(...args) {
|
187
100
|
if (this.isDirectionUsing) {
|
@@ -189,11 +102,5 @@ class ChoicesWrapper extends Choices {
|
|
189
102
|
}
|
190
103
|
super.hideDropdown(...args);
|
191
104
|
}
|
192
|
-
_onBlur(...args) {
|
193
|
-
if (this._isScrollingOnIe) {
|
194
|
-
return;
|
195
|
-
}
|
196
|
-
super._onBlur(...args);
|
197
|
-
}
|
198
105
|
}
|
199
106
|
export default ChoicesWrapper;
|
@@ -26,8 +26,8 @@ export const getBestMatch: typeof Utils.getBestMatch;
|
|
26
26
|
export const getComponentFromPath: typeof Utils.getComponentFromPath;
|
27
27
|
export const getComponentValue: typeof Utils.getComponentValue;
|
28
28
|
export const findComponents: typeof Utils.findComponents;
|
29
|
-
export const eachComponentDataAsync: (components: import("@formio/core").Component[], data: import("@formio/core").DataObject, fn: import("@formio/core").EachComponentDataAsyncCallback, includeAll?: boolean | undefined, local?: boolean | undefined, parent?: import("@formio/core").Component | undefined, parentPaths?: import("@formio/core").ComponentPaths | undefined) => Promise<void>;
|
30
|
-
export const eachComponentData: (components: import("@formio/core").Component[], data: import("@formio/core").DataObject, fn: import("@formio/core").EachComponentDataCallback, includeAll?: boolean | undefined, local?: boolean | undefined, parent?: import("@formio/core").Component | undefined, parentPaths?: import("@formio/core").ComponentPaths | undefined) => void;
|
29
|
+
export const eachComponentDataAsync: (components: import("@formio/core").Component[], data: import("@formio/core").DataObject, fn: import("@formio/core").EachComponentDataAsyncCallback, includeAll?: boolean | undefined, local?: boolean | undefined, parent?: import("@formio/core").Component | undefined, parentPaths?: import("@formio/core").ComponentPaths | undefined, noScopeReset?: boolean | undefined) => Promise<void>;
|
30
|
+
export const eachComponentData: (components: import("@formio/core").Component[], data: import("@formio/core").DataObject, fn: import("@formio/core").EachComponentDataCallback, includeAll?: boolean | undefined, local?: boolean | undefined, parent?: import("@formio/core").Component | undefined, parentPaths?: import("@formio/core").ComponentPaths | undefined, noScopeReset?: boolean | undefined) => void;
|
31
31
|
export const getComponentKey: typeof Utils.getComponentKey;
|
32
32
|
export const getContextualRowPath: typeof Utils.getContextualRowPath;
|
33
33
|
export const getContextualRowData: typeof Utils.getContextualRowData;
|
package/lib/mjs/utils/index.d.ts
CHANGED
@@ -37,8 +37,8 @@ declare const FormioUtils: {
|
|
37
37
|
getComponentFromPath: typeof import("@formio/core/lib/utils/formUtil").getComponentFromPath;
|
38
38
|
getComponentValue: typeof import("@formio/core/lib/utils/formUtil").getComponentValue;
|
39
39
|
findComponents: typeof import("@formio/core/lib/utils/formUtil").findComponents;
|
40
|
-
eachComponentDataAsync: (components: import("@formio/core").Component[], data: import("@formio/core").DataObject, fn: import("@formio/core").EachComponentDataAsyncCallback, includeAll?: boolean | undefined, local?: boolean | undefined, parent?: import("@formio/core").Component | undefined, parentPaths?: import("@formio/core").ComponentPaths | undefined) => Promise<void>;
|
41
|
-
eachComponentData: (components: import("@formio/core").Component[], data: import("@formio/core").DataObject, fn: import("@formio/core").EachComponentDataCallback, includeAll?: boolean | undefined, local?: boolean | undefined, parent?: import("@formio/core").Component | undefined, parentPaths?: import("@formio/core").ComponentPaths | undefined) => void;
|
40
|
+
eachComponentDataAsync: (components: import("@formio/core").Component[], data: import("@formio/core").DataObject, fn: import("@formio/core").EachComponentDataAsyncCallback, includeAll?: boolean | undefined, local?: boolean | undefined, parent?: import("@formio/core").Component | undefined, parentPaths?: import("@formio/core").ComponentPaths | undefined, noScopeReset?: boolean | undefined) => Promise<void>;
|
41
|
+
eachComponentData: (components: import("@formio/core").Component[], data: import("@formio/core").DataObject, fn: import("@formio/core").EachComponentDataCallback, includeAll?: boolean | undefined, local?: boolean | undefined, parent?: import("@formio/core").Component | undefined, parentPaths?: import("@formio/core").ComponentPaths | undefined, noScopeReset?: boolean | undefined) => void;
|
42
42
|
getComponentKey: typeof import("@formio/core/lib/utils/formUtil").getComponentKey;
|
43
43
|
getContextualRowPath: typeof import("@formio/core/lib/utils/formUtil").getContextualRowPath;
|
44
44
|
getContextualRowData: typeof import("@formio/core/lib/utils/formUtil").getContextualRowData;
|
@@ -137,8 +137,8 @@ declare const FormioUtils: {
|
|
137
137
|
translateHTMLTemplate(template: string, translate: Function): string;
|
138
138
|
sanitize(string: string, options: any): string;
|
139
139
|
fastCloneDeep(obj: any): any;
|
140
|
-
isInputComponent(componentJson: import("@formio/core").Component):
|
141
|
-
getArrayFromComponentPath(pathStr: string):
|
140
|
+
isInputComponent(componentJson: import("@formio/core").Component): boolean;
|
141
|
+
getArrayFromComponentPath(pathStr: string): string[];
|
142
142
|
isChildOf(child: any, parent: any): boolean;
|
143
143
|
getStringFromComponentPath(path: number[]): string;
|
144
144
|
round(number: number, precision: number): string;
|
package/lib/mjs/utils/utils.d.ts
CHANGED
@@ -414,15 +414,15 @@ export function fastCloneDeep(obj: any): any;
|
|
414
414
|
/**
|
415
415
|
* Returns if the component is an input component.
|
416
416
|
* @param {import('@formio/core').Component} componentJson - The JSON of a component.
|
417
|
-
* @returns {
|
417
|
+
* @returns {boolean} - TRUE if the component is an input component; FALSE otherwise.
|
418
418
|
*/
|
419
|
-
export function isInputComponent(componentJson: import('@formio/core').Component):
|
419
|
+
export function isInputComponent(componentJson: import('@formio/core').Component): boolean;
|
420
420
|
/**
|
421
421
|
* Takes a component path, and returns a component path array.
|
422
422
|
* @param {string} pathStr - The path string to convert to an array.
|
423
|
-
* @returns {
|
423
|
+
* @returns {Array<string>} - The array of paths.
|
424
424
|
*/
|
425
|
-
export function getArrayFromComponentPath(pathStr: string):
|
425
|
+
export function getArrayFromComponentPath(pathStr: string): Array<string>;
|
426
426
|
/**
|
427
427
|
* Returns true if the component is a child of the parent.
|
428
428
|
* @param {any} child - The child component to check.
|