@formio/js 5.0.0-dev.5914.479573c → 5.0.0-dev.5914.76c64d9

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.
@@ -901,13 +901,16 @@ class WebformBuilder extends Component_1.default {
901
901
  keyboardActionsEnabled = keyboardActionsEnabled === 'true';
902
902
  }
903
903
  this.keyboardActionsEnabled = keyboardActionsEnabled;
904
- const isSubmitButton = (comp) => {
905
- return (comp.type === 'button') && ((comp.action === 'submit') || !comp.action);
906
- };
907
- const isShowSubmitButton = !this.options.noDefaultSubmitButton
908
- && (!form.components.length || !form.components.find(comp => isSubmitButton(comp)));
904
+ const { display, noAddSubmitButton, noDefaultSubmitButton } = this.options;
905
+ const { _id, components } = form;
906
+ const isSubmitButton = ({ type, action }) => type === 'button' && (action === 'submit' || !action);
907
+ const hasSubmitButton = components.some(isSubmitButton);
908
+ // Add submit button if form display was switched from wizard
909
+ // Don't add if there is noAddSubmitButton flag passed, or the form has id, or the form has a submit button already
910
+ const shouldAddSubmitButton = (display === 'wizard' && !hasSubmitButton) ||
911
+ (!noAddSubmitButton && !_id && !hasSubmitButton);
909
912
  // Ensure there is at least a submit button.
910
- if (isShowSubmitButton) {
913
+ if (!noDefaultSubmitButton && shouldAddSubmitButton) {
911
914
  form.components.push({
912
915
  type: 'button',
913
916
  label: 'Submit',
@@ -1056,6 +1059,7 @@ class WebformBuilder extends Component_1.default {
1056
1059
  'conditional',
1057
1060
  'customConditional',
1058
1061
  'id',
1062
+ 'logic',
1059
1063
  'fields.day.required',
1060
1064
  'fields.month.required',
1061
1065
  'fields.year.required',
@@ -1081,6 +1085,12 @@ class WebformBuilder extends Component_1.default {
1081
1085
  parentComponent.tabs[tabIndex].splice(index, 1, newComp);
1082
1086
  newComp.checkValidity = () => true;
1083
1087
  newComp.build(defaultValueComponent.element);
1088
+ if (this.preview && !this.preview.defaultChanged) {
1089
+ const defaultValue = lodash_1.default.get(this.preview._data, this.editForm._data.key);
1090
+ if (lodash_1.default.isObject(defaultValue) && !lodash_1.default.isArray(defaultValue)) {
1091
+ this.editForm._data.defaultValue = defaultValue;
1092
+ }
1093
+ }
1084
1094
  }
1085
1095
  }
1086
1096
  else {
@@ -1091,6 +1101,7 @@ class WebformBuilder extends Component_1.default {
1091
1101
  path.unshift(component.key);
1092
1102
  dataPath = (0, utils_1.getStringFromComponentPath)(path);
1093
1103
  }
1104
+ this.preview.defaultChanged = true;
1094
1105
  lodash_1.default.set(this.preview._data, dataPath, changed.value);
1095
1106
  lodash_1.default.set(this.webform._data, dataPath, changed.value);
1096
1107
  }
@@ -105,7 +105,6 @@ declare class Wizard extends Webform {
105
105
  pageId(page: any): any;
106
106
  onChange(flags: any, changed: any, modified: any, changes: any): void;
107
107
  checkValidity(data: any, dirty: any, row: any, currentPageOnly: any, childErrors?: any[]): any;
108
- showErrors(errors: any, triggerEvent: any): void | any[];
109
108
  focusOnComponent(key: any): void | Promise<void>;
110
109
  }
111
110
  declare namespace Wizard {
package/lib/cjs/Wizard.js CHANGED
@@ -602,9 +602,10 @@ class Wizard extends Webform_1.default {
602
602
  }
603
603
  this.redraw().then(() => {
604
604
  this.checkData(this.submission.data);
605
- this.validateCurrentPage({
606
- dirty: this.submitted
607
- });
605
+ const errors = this.submitted ? this.validate(this.localData, { dirty: true }) : this.validateCurrentPage();
606
+ if (this.alert) {
607
+ this.showErrors(errors, true, true);
608
+ }
608
609
  });
609
610
  return Promise.resolve();
610
611
  }
@@ -701,9 +702,11 @@ class Wizard extends Webform_1.default {
701
702
  });
702
703
  });
703
704
  }
704
- // Validate the form, before go to the next page
705
- const errors = this.validateCurrentPage({ dirty: true });
706
- if (errors.length === 0) {
705
+ // Validate the form before going to the next page
706
+ const currentPageErrors = this.validateCurrentPage({ dirty: true });
707
+ const errors = this.submitted ? this.validate(this.localData, { dirty: true }) : currentPageErrors;
708
+ // allow going to the next page if the current page is valid, even if there are form level errors
709
+ if (currentPageErrors.length === 0) {
707
710
  this.checkData(this.submission.data);
708
711
  return this.beforePage(true).then(() => {
709
712
  return this.setPage(this.getNextPage()).then(() => {
@@ -718,13 +721,14 @@ class Wizard extends Webform_1.default {
718
721
  else {
719
722
  this.currentPage.components.forEach((comp) => comp.setPristine(false));
720
723
  this.scrollIntoView(this.element, true);
721
- return Promise.reject(super.showErrors(errors, true));
724
+ return Promise.reject(this.showErrors(errors, true));
722
725
  }
723
726
  }
724
727
  validateCurrentPage(flags = {}) {
725
- var _a;
728
+ var _a, _b;
729
+ const components = (_a = this.currentPage) === null || _a === void 0 ? void 0 : _a.components.map((component) => component.component);
726
730
  // Accessing the parent ensures the right instance (whether it's the parent Wizard or a nested Wizard) performs its validation
727
- return (_a = this.currentPage) === null || _a === void 0 ? void 0 : _a.parent.validateComponents(this.currentPage.component.components, this.root.data, flags);
731
+ return (_b = this.currentPage) === null || _b === void 0 ? void 0 : _b.parent.validateComponents(components, this.root.data, flags);
728
732
  }
729
733
  emitPrevPage() {
730
734
  this.emit('prevPage', { page: this.page, submission: this.submission });
@@ -866,7 +870,8 @@ class Wizard extends Webform_1.default {
866
870
  onChange(flags, changed, modified, changes) {
867
871
  var _a, _b;
868
872
  super.onChange(flags, changed, modified, changes);
869
- const errors = this.validate(this.localData, { dirty: false });
873
+ // The onChange loop doesn't need all components for wizards
874
+ const errors = this.submitted ? this.validate(this.localData, { dirty: true }) : this.validateCurrentPage();
870
875
  if (this.alert) {
871
876
  this.showErrors(errors, true, true);
872
877
  }
@@ -914,20 +919,7 @@ class Wizard extends Webform_1.default {
914
919
  return components.reduce((check, comp) => comp.checkValidity(data, dirty, row, currentPageOnly, childErrors) && check, true);
915
920
  }
916
921
  get errors() {
917
- if (!this.isLastPage()) {
918
- return this.currentPage.errors;
919
- }
920
- return super.errors;
921
- }
922
- showErrors(errors, triggerEvent) {
923
- if (this.hasExtraPages) {
924
- this.subWizards.forEach((subWizard) => {
925
- if (Array.isArray(subWizard.errors)) {
926
- errors = [...errors, ...subWizard.errors];
927
- }
928
- });
929
- }
930
- return super.showErrors(errors, triggerEvent);
922
+ return !this.isLastPage() && !this.submitted ? this.currentPage.errors : super.errors;
931
923
  }
932
924
  focusOnComponent(key) {
933
925
  const component = this.getComponent(key);
@@ -22,6 +22,7 @@ export default class ComponentModal {
22
22
  modalOverlay: string;
23
23
  modalContents: string;
24
24
  modalClose: string;
25
+ componentContent: string;
25
26
  openModalWrapper: string;
26
27
  openModal: string;
27
28
  modalSave: string;
@@ -64,6 +64,7 @@ class ComponentModal {
64
64
  modalOverlay: 'single',
65
65
  modalContents: 'single',
66
66
  modalClose: 'single',
67
+ componentContent: 'single',
67
68
  openModalWrapper: 'single',
68
69
  openModal: 'single',
69
70
  modalSave: 'single',
@@ -294,7 +294,7 @@ class FormComponent extends Component_1.default {
294
294
  const modalShouldBeOpened = this.componentModal ? this.componentModal.isOpened : false;
295
295
  const currentValue = modalShouldBeOpened ? this.componentModal.currentValue : this.dataValue;
296
296
  this.componentModal = new ComponentModal_1.default(this, element, modalShouldBeOpened, currentValue, this._referenceAttributeName);
297
- this.subForm.element = this.componentModal.refs.modalContents;
297
+ this.subForm.element = this.componentModal.refs.componentContent || this.subForm.element;
298
298
  this.setOpenModalElement();
299
299
  }
300
300
  this.calculateValue();
@@ -396,6 +396,7 @@ class FormComponent extends Component_1.default {
396
396
  const componentsMap = this.componentsMap;
397
397
  const formComponentsMap = this.subForm.componentsMap;
398
398
  lodash_1.default.assign(componentsMap, formComponentsMap);
399
+ this.component.components = this.subForm.components.map((comp) => comp.component);
399
400
  this.subForm.parent = this;
400
401
  this.subForm.parentVisible = this.visible;
401
402
  this.subForm.on('change', () => {
@@ -139,6 +139,14 @@ class SelectBoxesComponent extends Radio_1.default {
139
139
  checkedValues.forEach((value) => selectData.push(this.templateData[value]));
140
140
  lodash_1.default.set(submission.metadata.selectData, this.path, selectData);
141
141
  }
142
+ // Ensure that for dataSrc == 'values' that there are not any other superfluous values.
143
+ if (this.component.dataSrc === 'values') {
144
+ for (const key in value) {
145
+ if (!this.component.values.find((val) => val.value === key)) {
146
+ delete value[key];
147
+ }
148
+ }
149
+ }
142
150
  return value;
143
151
  }
144
152
  /**
@@ -885,13 +885,16 @@ export default class WebformBuilder extends Component {
885
885
  keyboardActionsEnabled = keyboardActionsEnabled === 'true';
886
886
  }
887
887
  this.keyboardActionsEnabled = keyboardActionsEnabled;
888
- const isSubmitButton = (comp) => {
889
- return (comp.type === 'button') && ((comp.action === 'submit') || !comp.action);
890
- };
891
- const isShowSubmitButton = !this.options.noDefaultSubmitButton
892
- && (!form.components.length || !form.components.find(comp => isSubmitButton(comp)));
888
+ const { display, noAddSubmitButton, noDefaultSubmitButton } = this.options;
889
+ const { _id, components } = form;
890
+ const isSubmitButton = ({ type, action }) => type === 'button' && (action === 'submit' || !action);
891
+ const hasSubmitButton = components.some(isSubmitButton);
892
+ // Add submit button if form display was switched from wizard
893
+ // Don't add if there is noAddSubmitButton flag passed, or the form has id, or the form has a submit button already
894
+ const shouldAddSubmitButton = (display === 'wizard' && !hasSubmitButton) ||
895
+ (!noAddSubmitButton && !_id && !hasSubmitButton);
893
896
  // Ensure there is at least a submit button.
894
- if (isShowSubmitButton) {
897
+ if (!noDefaultSubmitButton && shouldAddSubmitButton) {
895
898
  form.components.push({
896
899
  type: 'button',
897
900
  label: 'Submit',
@@ -1040,6 +1043,7 @@ export default class WebformBuilder extends Component {
1040
1043
  'conditional',
1041
1044
  'customConditional',
1042
1045
  'id',
1046
+ 'logic',
1043
1047
  'fields.day.required',
1044
1048
  'fields.month.required',
1045
1049
  'fields.year.required',
@@ -1065,6 +1069,12 @@ export default class WebformBuilder extends Component {
1065
1069
  parentComponent.tabs[tabIndex].splice(index, 1, newComp);
1066
1070
  newComp.checkValidity = () => true;
1067
1071
  newComp.build(defaultValueComponent.element);
1072
+ if (this.preview && !this.preview.defaultChanged) {
1073
+ const defaultValue = _.get(this.preview._data, this.editForm._data.key);
1074
+ if (_.isObject(defaultValue) && !_.isArray(defaultValue)) {
1075
+ this.editForm._data.defaultValue = defaultValue;
1076
+ }
1077
+ }
1068
1078
  }
1069
1079
  }
1070
1080
  else {
@@ -1075,6 +1085,7 @@ export default class WebformBuilder extends Component {
1075
1085
  path.unshift(component.key);
1076
1086
  dataPath = getStringFromComponentPath(path);
1077
1087
  }
1088
+ this.preview.defaultChanged = true;
1078
1089
  _.set(this.preview._data, dataPath, changed.value);
1079
1090
  _.set(this.webform._data, dataPath, changed.value);
1080
1091
  }
@@ -105,7 +105,6 @@ declare class Wizard extends Webform {
105
105
  pageId(page: any): any;
106
106
  onChange(flags: any, changed: any, modified: any, changes: any): void;
107
107
  checkValidity(data: any, dirty: any, row: any, currentPageOnly: any, childErrors?: any[]): any;
108
- showErrors(errors: any, triggerEvent: any): void | any[];
109
108
  focusOnComponent(key: any): void | Promise<void>;
110
109
  }
111
110
  declare namespace Wizard {
package/lib/mjs/Wizard.js CHANGED
@@ -594,9 +594,10 @@ export default class Wizard extends Webform {
594
594
  }
595
595
  this.redraw().then(() => {
596
596
  this.checkData(this.submission.data);
597
- this.validateCurrentPage({
598
- dirty: this.submitted
599
- });
597
+ const errors = this.submitted ? this.validate(this.localData, { dirty: true }) : this.validateCurrentPage();
598
+ if (this.alert) {
599
+ this.showErrors(errors, true, true);
600
+ }
600
601
  });
601
602
  return Promise.resolve();
602
603
  }
@@ -691,9 +692,11 @@ export default class Wizard extends Webform {
691
692
  });
692
693
  });
693
694
  }
694
- // Validate the form, before go to the next page
695
- const errors = this.validateCurrentPage({ dirty: true });
696
- if (errors.length === 0) {
695
+ // Validate the form before going to the next page
696
+ const currentPageErrors = this.validateCurrentPage({ dirty: true });
697
+ const errors = this.submitted ? this.validate(this.localData, { dirty: true }) : currentPageErrors;
698
+ // allow going to the next page if the current page is valid, even if there are form level errors
699
+ if (currentPageErrors.length === 0) {
697
700
  this.checkData(this.submission.data);
698
701
  return this.beforePage(true).then(() => {
699
702
  return this.setPage(this.getNextPage()).then(() => {
@@ -708,12 +711,13 @@ export default class Wizard extends Webform {
708
711
  else {
709
712
  this.currentPage.components.forEach((comp) => comp.setPristine(false));
710
713
  this.scrollIntoView(this.element, true);
711
- return Promise.reject(super.showErrors(errors, true));
714
+ return Promise.reject(this.showErrors(errors, true));
712
715
  }
713
716
  }
714
717
  validateCurrentPage(flags = {}) {
718
+ const components = this.currentPage?.components.map((component) => component.component);
715
719
  // Accessing the parent ensures the right instance (whether it's the parent Wizard or a nested Wizard) performs its validation
716
- return this.currentPage?.parent.validateComponents(this.currentPage.component.components, this.root.data, flags);
720
+ return this.currentPage?.parent.validateComponents(components, this.root.data, flags);
717
721
  }
718
722
  emitPrevPage() {
719
723
  this.emit('prevPage', { page: this.page, submission: this.submission });
@@ -854,7 +858,8 @@ export default class Wizard extends Webform {
854
858
  }
855
859
  onChange(flags, changed, modified, changes) {
856
860
  super.onChange(flags, changed, modified, changes);
857
- const errors = this.validate(this.localData, { dirty: false });
861
+ // The onChange loop doesn't need all components for wizards
862
+ const errors = this.submitted ? this.validate(this.localData, { dirty: true }) : this.validateCurrentPage();
858
863
  if (this.alert) {
859
864
  this.showErrors(errors, true, true);
860
865
  }
@@ -902,20 +907,7 @@ export default class Wizard extends Webform {
902
907
  return components.reduce((check, comp) => comp.checkValidity(data, dirty, row, currentPageOnly, childErrors) && check, true);
903
908
  }
904
909
  get errors() {
905
- if (!this.isLastPage()) {
906
- return this.currentPage.errors;
907
- }
908
- return super.errors;
909
- }
910
- showErrors(errors, triggerEvent) {
911
- if (this.hasExtraPages) {
912
- this.subWizards.forEach((subWizard) => {
913
- if (Array.isArray(subWizard.errors)) {
914
- errors = [...errors, ...subWizard.errors];
915
- }
916
- });
917
- }
918
- return super.showErrors(errors, triggerEvent);
910
+ return !this.isLastPage() && !this.submitted ? this.currentPage.errors : super.errors;
919
911
  }
920
912
  focusOnComponent(key) {
921
913
  const component = this.getComponent(key);
@@ -22,6 +22,7 @@ export default class ComponentModal {
22
22
  modalOverlay: string;
23
23
  modalContents: string;
24
24
  modalClose: string;
25
+ componentContent: string;
25
26
  openModalWrapper: string;
26
27
  openModal: string;
27
28
  modalSave: string;
@@ -61,6 +61,7 @@ export default class ComponentModal {
61
61
  modalOverlay: 'single',
62
62
  modalContents: 'single',
63
63
  modalClose: 'single',
64
+ componentContent: 'single',
64
65
  openModalWrapper: 'single',
65
66
  openModal: 'single',
66
67
  modalSave: 'single',
@@ -291,7 +291,7 @@ export default class FormComponent extends Component {
291
291
  const modalShouldBeOpened = this.componentModal ? this.componentModal.isOpened : false;
292
292
  const currentValue = modalShouldBeOpened ? this.componentModal.currentValue : this.dataValue;
293
293
  this.componentModal = new ComponentModal(this, element, modalShouldBeOpened, currentValue, this._referenceAttributeName);
294
- this.subForm.element = this.componentModal.refs.modalContents;
294
+ this.subForm.element = this.componentModal.refs.componentContent || this.subForm.element;
295
295
  this.setOpenModalElement();
296
296
  }
297
297
  this.calculateValue();
@@ -392,6 +392,7 @@ export default class FormComponent extends Component {
392
392
  const componentsMap = this.componentsMap;
393
393
  const formComponentsMap = this.subForm.componentsMap;
394
394
  _.assign(componentsMap, formComponentsMap);
395
+ this.component.components = this.subForm.components.map((comp) => comp.component);
395
396
  this.subForm.parent = this;
396
397
  this.subForm.parentVisible = this.visible;
397
398
  this.subForm.on('change', () => {
@@ -141,6 +141,14 @@ export default class SelectBoxesComponent extends RadioComponent {
141
141
  checkedValues.forEach((value) => selectData.push(this.templateData[value]));
142
142
  _.set(submission.metadata.selectData, this.path, selectData);
143
143
  }
144
+ // Ensure that for dataSrc == 'values' that there are not any other superfluous values.
145
+ if (this.component.dataSrc === 'values') {
146
+ for (const key in value) {
147
+ if (!this.component.values.find((val) => val.value === key)) {
148
+ delete value[key];
149
+ }
150
+ }
151
+ }
144
152
  return value;
145
153
  }
146
154
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@formio/js",
3
- "version": "5.0.0-dev.5914.479573c",
3
+ "version": "5.0.0-dev.5914.76c64d9",
4
4
  "description": "JavaScript powered Forms with JSON Form Builder",
5
5
  "main": "lib/cjs/index.js",
6
6
  "exports": {
@@ -80,9 +80,9 @@
80
80
  },
81
81
  "homepage": "https://github.com/formio/formio.js#readme",
82
82
  "dependencies": {
83
- "@formio/bootstrap": "3.0.0-dev.98.17ba6ea",
83
+ "@formio/bootstrap": "3.0.0-dev.111.ae7f187",
84
84
  "@formio/choices.js": "^10.2.1",
85
- "@formio/core": "2.1.0-dev.193.dc60547",
85
+ "@formio/core": "2.1.0-dev.193.68cf8c3",
86
86
  "@formio/text-mask-addons": "3.8.0-formio.4",
87
87
  "@formio/vanilla-text-mask": "^5.1.1-formio.1",
88
88
  "abortcontroller-polyfill": "^1.7.5",