@formio/js 5.0.0-rc.40 → 5.0.0-rc.42

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. package/dist/formio.builder.css +2 -2
  2. package/dist/formio.builder.min.css +1 -1
  3. package/dist/formio.embed.js +1 -1
  4. package/dist/formio.embed.min.js +1 -1
  5. package/dist/formio.embed.min.js.LICENSE.txt +1 -1
  6. package/dist/formio.form.css +2 -2
  7. package/dist/formio.form.js +114 -37
  8. package/dist/formio.form.min.css +1 -1
  9. package/dist/formio.form.min.js +1 -1
  10. package/dist/formio.form.min.js.LICENSE.txt +7 -7
  11. package/dist/formio.full.css +2 -2
  12. package/dist/formio.full.js +115 -38
  13. package/dist/formio.full.min.css +1 -1
  14. package/dist/formio.full.min.js +1 -1
  15. package/dist/formio.full.min.js.LICENSE.txt +7 -7
  16. package/dist/formio.js +76 -4
  17. package/dist/formio.min.js +1 -1
  18. package/dist/formio.min.js.LICENSE.txt +13 -1
  19. package/dist/formio.utils.js +48 -4
  20. package/dist/formio.utils.min.js +1 -1
  21. package/dist/formio.utils.min.js.LICENSE.txt +3 -3
  22. package/lib/cjs/Embed.js +11 -11
  23. package/lib/cjs/Form.js +32 -1
  24. package/lib/cjs/Webform.js +1 -1
  25. package/lib/cjs/WebformBuilder.js +18 -2
  26. package/lib/cjs/components/datagrid/DataGrid.js +1 -1
  27. package/lib/cjs/components/datetime/fixtures/comp13.js +118 -0
  28. package/lib/cjs/components/datetime/fixtures/index.js +3 -1
  29. package/lib/cjs/components/form/Form.js +27 -3
  30. package/lib/cjs/components/radio/Radio.js +13 -0
  31. package/lib/cjs/providers/storage/util.js +2 -2
  32. package/lib/cjs/utils/conditionOperators/IsEqualTo.js +1 -1
  33. package/lib/cjs/widgets/CalendarWidget.js +8 -0
  34. package/lib/mjs/Form.js +32 -1
  35. package/lib/mjs/Webform.js +1 -1
  36. package/lib/mjs/WebformBuilder.js +17 -1
  37. package/lib/mjs/components/datagrid/DataGrid.js +1 -1
  38. package/lib/mjs/components/datetime/fixtures/comp13.js +116 -0
  39. package/lib/mjs/components/datetime/fixtures/index.js +2 -1
  40. package/lib/mjs/components/form/Form.js +25 -2
  41. package/lib/mjs/components/radio/Radio.js +16 -0
  42. package/lib/mjs/utils/conditionOperators/IsEqualTo.js +1 -1
  43. package/lib/mjs/widgets/CalendarWidget.js +8 -0
  44. package/package.json +11 -11
@@ -10,11 +10,11 @@
10
10
  * MIT licensed
11
11
  */
12
12
 
13
- /*! @license DOMPurify 3.0.8 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.0.8/LICENSE */
13
+ /*! @license DOMPurify 3.0.11 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.0.11/LICENSE */
14
14
 
15
- /*! @license DOMPurify 3.0.9 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.0.9/LICENSE */
15
+ /*! @license DOMPurify 3.0.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.0.6/LICENSE */
16
16
 
17
- /*! formiojs v5.0.0-rc.40 | https://unpkg.com/formiojs@5.0.0-rc.40/LICENSE.txt */
17
+ /*! formiojs v5.0.0-rc.42 | https://unpkg.com/formiojs@5.0.0-rc.42/LICENSE.txt */
18
18
 
19
19
  /**
20
20
  * @license
package/lib/cjs/Embed.js CHANGED
@@ -88,8 +88,8 @@ class Formio {
88
88
  });
89
89
  return element;
90
90
  }
91
- static addScript(wrapper_1, src_1, name_1) {
92
- return __awaiter(this, arguments, void 0, function* (wrapper, src, name, flag = '') {
91
+ static addScript(wrapper, src, name, flag = '') {
92
+ return __awaiter(this, void 0, void 0, function* () {
93
93
  if (!src) {
94
94
  return Promise.resolve();
95
95
  }
@@ -229,8 +229,8 @@ class Formio {
229
229
  });
230
230
  }
231
231
  // eslint-disable-next-line max-statements
232
- static init(element_1) {
233
- return __awaiter(this, arguments, void 0, function* (element, options = {}, builder = false) {
232
+ static init(element, options = {}, builder = false) {
233
+ return __awaiter(this, void 0, void 0, function* () {
234
234
  _a.cdn = new CDN_js_1.default(_a.config.cdn, _a.config.cdnUrls || {});
235
235
  _a.config.libs = _a.config.libs || {
236
236
  uswds: {
@@ -334,8 +334,8 @@ class Formio {
334
334
  });
335
335
  }
336
336
  // Create a new form.
337
- static createForm(element_1, form_1) {
338
- return __awaiter(this, arguments, void 0, function* (element, form, options = {}) {
337
+ static createForm(element, form, options = {}) {
338
+ return __awaiter(this, void 0, void 0, function* () {
339
339
  if (_a.FormioClass) {
340
340
  return _a.FormioClass.createForm(element, form, Object.assign(Object.assign({}, options), { noLoader: true }));
341
341
  }
@@ -353,10 +353,10 @@ class Formio {
353
353
  });
354
354
  }
355
355
  // Create a form builder.
356
- static builder(element_1, form_1) {
357
- return __awaiter(this, arguments, void 0, function* (element, form, options = {}) {
358
- var _a;
359
- if ((_a = _a.FormioClass) === null || _a === void 0 ? void 0 : _a.builder) {
356
+ static builder(element, form, options = {}) {
357
+ var _b;
358
+ return __awaiter(this, void 0, void 0, function* () {
359
+ if ((_b = _a.FormioClass) === null || _b === void 0 ? void 0 : _b.builder) {
360
360
  return _a.FormioClass.builder(element, form, options);
361
361
  }
362
362
  const wrapper = yield _a.init(element, options, true);
@@ -381,7 +381,7 @@ Formio.formioReady = new Promise((ready, reject) => {
381
381
  Formio.version = 'FORMIO_VERSION';
382
382
  // Create a report.
383
383
  Formio.Report = {
384
- create: (element_1, submission_1, ...args_1) => __awaiter(void 0, [element_1, submission_1, ...args_1], void 0, function* (element, submission, options = {}) {
384
+ create: (element, submission, options = {}) => __awaiter(void 0, void 0, void 0, function* () {
385
385
  var _b;
386
386
  if ((_b = _a.FormioClass) === null || _b === void 0 ? void 0 : _b.Report) {
387
387
  return _a.FormioClass.Report.create(element, submission, options);
package/lib/cjs/Form.js CHANGED
@@ -178,6 +178,36 @@ class Form extends Element_1.default {
178
178
  ]
179
179
  };
180
180
  }
181
+ /**
182
+ * Check Subdirectories path and provide correct options
183
+ *
184
+ * @param {string} url - The the URL of the form json.
185
+ * @param {form} object - The form json.
186
+ * @return {object} The initial options with base and project.
187
+ */
188
+ getFormInitOptions(url, form) {
189
+ const options = {};
190
+ const index = url.indexOf(form === null || form === void 0 ? void 0 : form.path);
191
+ // form url doesn't include form path
192
+ if (index === -1) {
193
+ return options;
194
+ }
195
+ const projectUrl = url.substring(0, index - 1);
196
+ const urlParts = Formio_1.Formio.getUrlParts(projectUrl);
197
+ // project url doesn't include subdirectories path
198
+ if (!urlParts || urlParts.filter(part => !!part).length < 4) {
199
+ return options;
200
+ }
201
+ const baseUrl = `${urlParts[1]}${urlParts[2]}`;
202
+ // Skip if baseUrl has already been set
203
+ if (baseUrl !== Formio_1.Formio.baseUrl) {
204
+ return {
205
+ base: baseUrl,
206
+ project: projectUrl,
207
+ };
208
+ }
209
+ return {};
210
+ }
181
211
  setForm(formParam) {
182
212
  let result;
183
213
  formParam = formParam || this.form;
@@ -202,7 +232,8 @@ class Form extends Element_1.default {
202
232
  }
203
233
  this.loading = false;
204
234
  this.instance = this.instance || this.create(form.display);
205
- this.instance.url = formParam;
235
+ const options = this.getFormInitOptions(formParam, form);
236
+ this.instance.setUrl(formParam, options);
206
237
  this.instance.nosubmit = false;
207
238
  this._form = this.instance.form = form;
208
239
  if (submission) {
@@ -1005,7 +1005,7 @@ class Webform extends NestedDataComponent_1.default {
1005
1005
  if (!Array.isArray(errors)) {
1006
1006
  errors = [errors];
1007
1007
  }
1008
- errors = errors.concat(this.customErrors);
1008
+ errors = errors.concat(this.customErrors).filter((err) => !!err);
1009
1009
  if (!errors.length) {
1010
1010
  this.setAlert(false);
1011
1011
  return;
@@ -123,7 +123,7 @@ class WebformBuilder extends Component_1.default {
123
123
  }
124
124
  this.options.hooks = this.options.hooks || {};
125
125
  this.options.hooks.renderComponent = (html, { component, self }) => {
126
- var _a;
126
+ var _a, _b;
127
127
  if (self.type === 'form' && !self.key) {
128
128
  const template = this.hook('renderComponentFormTemplate', html.replace('formio-component-form', ''));
129
129
  // The main webform shouldn't have this class as it adds extra styles.
@@ -136,6 +136,7 @@ class WebformBuilder extends Component_1.default {
136
136
  html,
137
137
  disableBuilderActions: (_a = self === null || self === void 0 ? void 0 : self.component) === null || _a === void 0 ? void 0 : _a.disableBuilderActions,
138
138
  childComponent: component,
139
+ design: (_b = self === null || self === void 0 ? void 0 : self.options) === null || _b === void 0 ? void 0 : _b.design
139
140
  });
140
141
  };
141
142
  this.options.hooks.renderComponents = (html, { components, self }) => {
@@ -486,6 +487,7 @@ class WebformBuilder extends Component_1.default {
486
487
  attach(element) {
487
488
  this.on('change', (form) => {
488
489
  this.populateRecaptchaSettings(form);
490
+ this.webform.setAlert(false);
489
491
  });
490
492
  return super.attach(element).then(() => {
491
493
  this.loadRefs(element, {
@@ -819,6 +821,20 @@ class WebformBuilder extends Component_1.default {
819
821
  return;
820
822
  }
821
823
  }
824
+ if (draggableComponent.uniqueComponent) {
825
+ let isCompAlreadyExists = false;
826
+ (0, formUtils_1.eachComponent)(this.webform.components, (component) => {
827
+ if (component.key === draggableComponent.schema.key) {
828
+ isCompAlreadyExists = true;
829
+ return;
830
+ }
831
+ }, true);
832
+ if (isCompAlreadyExists) {
833
+ this.webform.redraw();
834
+ this.webform.setAlert('danger', `You cannot add more than one ${draggableComponent.title} component to one page.`);
835
+ return;
836
+ }
837
+ }
822
838
  if (target !== source) {
823
839
  // Ensure the key remains unique in its new container.
824
840
  builder_1.default.uniquify(this.findNamespaceRoot(target.formioComponent), info);
@@ -851,7 +867,7 @@ class WebformBuilder extends Component_1.default {
851
867
  parent.addChildComponent(info, element, target, source, sibling);
852
868
  }
853
869
  const componentInDataGrid = parent.type === 'datagrid';
854
- if (isNew && !this.options.noNewEdit && !info.noNewEdit) {
870
+ if (isNew && !this.options.noNewEdit && !info.noNewEdit && !(this.options.design && info.type === 'reviewpage')) {
855
871
  this.editComponent(info, target, isNew, null, null, { inDataGrid: componentInDataGrid });
856
872
  }
857
873
  // Only rebuild the parts needing to be rebuilt.
@@ -199,7 +199,7 @@ class DataGridComponent extends NestedArrayComponent_1.default {
199
199
  return this.hasAddButton() && ['bottom', 'both'].includes(this.addAnotherPosition);
200
200
  }
201
201
  get canAddColumn() {
202
- return this.builderMode;
202
+ return this.builderMode && !this.options.design;
203
203
  }
204
204
  render() {
205
205
  const columns = this.getColumns();
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = {
4
+ type: 'form',
5
+ display: 'form',
6
+ components: [
7
+ {
8
+ label: 'Min Date',
9
+ tableView: false,
10
+ datePicker: {
11
+ disableWeekends: false,
12
+ disableWeekdays: false
13
+ },
14
+ enableMinDateInput: false,
15
+ enableMaxDateInput: false,
16
+ key: 'minDate',
17
+ type: 'datetime',
18
+ input: true,
19
+ widget: {
20
+ type: 'calendar',
21
+ displayInTimezone: 'viewer',
22
+ locale: 'en',
23
+ useLocaleSettings: false,
24
+ allowInput: true,
25
+ mode: 'single',
26
+ enableTime: true,
27
+ noCalendar: false,
28
+ format: 'yyyy-MM-dd hh:mm a',
29
+ hourIncrement: 1,
30
+ minuteIncrement: 1,
31
+ // eslint-disable-next-line camelcase
32
+ time_24hr: false,
33
+ minDate: null,
34
+ disableWeekends: false,
35
+ disableWeekdays: false,
36
+ maxDate: null
37
+ }
38
+ },
39
+ {
40
+ label: 'Max Date',
41
+ tableView: false,
42
+ enableMinDateInput: false,
43
+ datePicker: {
44
+ disableWeekends: false,
45
+ disableWeekdays: false
46
+ },
47
+ enableMaxDateInput: false,
48
+ validate: {
49
+ custom: "var minDate = moment(data.minDate);\nvar maxDate = moment(data.maxDate);\nvalid = maxDate.isAfter(minDate)? true : 'Max date must be after min date'"
50
+ },
51
+ key: 'maxDate',
52
+ type: 'datetime',
53
+ input: true,
54
+ widget: {
55
+ type: 'calendar',
56
+ displayInTimezone: 'viewer',
57
+ locale: 'en',
58
+ useLocaleSettings: false,
59
+ allowInput: true,
60
+ mode: 'single',
61
+ enableTime: true,
62
+ noCalendar: false,
63
+ format: 'yyyy-MM-dd hh:mm a',
64
+ hourIncrement: 1,
65
+ minuteIncrement: 1,
66
+ // eslint-disable-next-line camelcase
67
+ time_24hr: false,
68
+ minDate: null,
69
+ disableWeekends: false,
70
+ disableWeekdays: false,
71
+ maxDate: null
72
+ }
73
+ },
74
+ {
75
+ label: 'In Between Date',
76
+ tableView: false,
77
+ datePicker: {
78
+ disableFunction: '!moment(date).isBetween(moment(data.minDate), moment(data.maxDate))',
79
+ disableWeekends: false,
80
+ disableWeekdays: false
81
+ },
82
+ enableMinDateInput: false,
83
+ enableMaxDateInput: false,
84
+ key: 'inBetweenDate',
85
+ customConditional: 'show = !!data.minDate && !!data.maxDate',
86
+ type: 'datetime',
87
+ input: true,
88
+ widget: {
89
+ type: 'calendar',
90
+ displayInTimezone: 'viewer',
91
+ locale: 'en',
92
+ useLocaleSettings: false,
93
+ allowInput: true,
94
+ mode: 'single',
95
+ enableTime: true,
96
+ noCalendar: false,
97
+ format: 'yyyy-MM-dd hh:mm a',
98
+ hourIncrement: 1,
99
+ minuteIncrement: 1,
100
+ // eslint-disable-next-line camelcase
101
+ time_24hr: false,
102
+ minDate: null,
103
+ disableWeekends: false,
104
+ disableWeekdays: false,
105
+ disableFunction: '!moment(date).isBetween(moment(data.minDate), moment(data.maxDate))',
106
+ maxDate: null
107
+ }
108
+ },
109
+ {
110
+ type: 'button',
111
+ label: 'Submit',
112
+ key: 'submit',
113
+ disableOnInvalid: true,
114
+ input: true,
115
+ tableView: false
116
+ }
117
+ ],
118
+ };
@@ -3,7 +3,7 @@ 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
- exports.comp9 = exports.comp8 = exports.comp7 = exports.comp6 = exports.comp5 = exports.comp3 = exports.comp2 = exports.comp12 = exports.comp11 = exports.comp10 = exports.comp1 = void 0;
6
+ exports.comp9 = exports.comp8 = exports.comp7 = exports.comp6 = exports.comp5 = exports.comp3 = exports.comp2 = exports.comp13 = exports.comp12 = exports.comp11 = exports.comp10 = exports.comp1 = void 0;
7
7
  const comp1_1 = __importDefault(require("./comp1"));
8
8
  exports.comp1 = comp1_1.default;
9
9
  const comp2_1 = __importDefault(require("./comp2"));
@@ -26,3 +26,5 @@ const comp11_1 = __importDefault(require("./comp11"));
26
26
  exports.comp11 = comp11_1.default;
27
27
  const comp12_1 = __importDefault(require("./comp12"));
28
28
  exports.comp12 = comp12_1.default;
29
+ const comp13_1 = __importDefault(require("./comp13"));
30
+ exports.comp13 = comp13_1.default;
@@ -3,6 +3,7 @@ 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
+ /* eslint-disable max-statements */
6
7
  const lodash_1 = __importDefault(require("lodash"));
7
8
  const Component_1 = __importDefault(require("../_classes/component/Component"));
8
9
  const ComponentModal_1 = __importDefault(require("../_classes/componentModal/ComponentModal"));
@@ -197,6 +198,12 @@ class FormComponent extends Component_1.default {
197
198
  if (this.options.inEditGrid) {
198
199
  options.inEditGrid = this.options.inEditGrid;
199
200
  }
201
+ if (this.options.saveDraft) {
202
+ options.saveDraft = this.options.saveDraft;
203
+ }
204
+ if (this.options.saveDraftThrottle) {
205
+ options.saveDraftThrottle = this.options.saveDraftThrottle;
206
+ }
200
207
  return options;
201
208
  }
202
209
  render() {
@@ -396,6 +403,10 @@ class FormComponent extends Component_1.default {
396
403
  this.subForm.nosubmit = true;
397
404
  this.subForm.root = this.root;
398
405
  this.subForm.localRoot = this.isNestedWizard ? this.localRoot : this.subForm;
406
+ if (this.parent) {
407
+ this.subForm.draftEnabled = this.parent.draftEnabled;
408
+ this.subForm.savingDraft = this.parent.savingDraft;
409
+ }
399
410
  this.restoreValue();
400
411
  this.valueChanged = this.hasSetValue;
401
412
  this.onChange();
@@ -418,7 +429,7 @@ class FormComponent extends Component_1.default {
418
429
  * Load the subform.
419
430
  */
420
431
  loadSubForm(fromAttach) {
421
- var _a;
432
+ var _a, _b, _c;
422
433
  if (this.builderMode || this.isHidden() || (this.isSubFormLazyLoad() && !fromAttach)) {
423
434
  return Promise.resolve();
424
435
  }
@@ -432,7 +443,13 @@ class FormComponent extends Component_1.default {
432
443
  }
433
444
  else if (this.formSrc) {
434
445
  this.subFormLoading = true;
435
- return (new Formio_1.Formio(this.formSrc)).loadForm({ params: { live: 1 } })
446
+ const options = ((_b = this.root.formio) === null || _b === void 0 ? void 0 : _b.base) && ((_c = this.root.formio) === null || _c === void 0 ? void 0 : _c.projectUrl)
447
+ ? {
448
+ base: this.root.formio.base,
449
+ project: this.root.formio.projectUrl,
450
+ }
451
+ : {};
452
+ return (new Formio_1.Formio(this.formSrc, options)).loadForm({ params: { live: 1 } })
436
453
  .then((formObj) => {
437
454
  this.formObj = formObj;
438
455
  if (this.options.pdf && this.component.useOriginalRevision) {
@@ -601,6 +618,7 @@ class FormComponent extends Component_1.default {
601
618
  return changed;
602
619
  }
603
620
  setSubFormValue(submission, flags) {
621
+ var _a, _b;
604
622
  const shouldLoadSubmissionById = submission
605
623
  && submission._id
606
624
  && this.subForm.formio
@@ -608,7 +626,13 @@ class FormComponent extends Component_1.default {
608
626
  if (shouldLoadSubmissionById) {
609
627
  const formId = submission.form || this.formObj.form || this.component.form;
610
628
  const submissionUrl = `${this.subForm.formio.formsUrl}/${formId}/submission/${submission._id}`;
611
- this.subForm.setUrl(submissionUrl, this.options);
629
+ const options = ((_a = this.root.formio) === null || _a === void 0 ? void 0 : _a.base) && ((_b = this.root.formio) === null || _b === void 0 ? void 0 : _b.projectUrl)
630
+ ? {
631
+ base: this.root.formio.base,
632
+ project: this.root.formio.projectUrl,
633
+ }
634
+ : {};
635
+ this.subForm.setUrl(submissionUrl, Object.assign(Object.assign({}, this.options), options));
612
636
  this.subForm.loadSubmission().catch((err) => {
613
637
  console.error(`Unable to load subform submission ${submission._id}:`, err);
614
638
  });
@@ -46,6 +46,19 @@ class RadioComponent extends ListComponent_1.default {
46
46
  };
47
47
  } });
48
48
  }
49
+ static get serverConditionSettings() {
50
+ return Object.assign(Object.assign({}, super.serverConditionSettings), { valueComponent(classComp) {
51
+ return {
52
+ type: 'select',
53
+ dataSrc: 'custom',
54
+ valueProperty: 'value',
55
+ dataType: classComp.dataType || '',
56
+ data: {
57
+ custom: `values = ${classComp && classComp.values ? JSON.stringify(classComp.values) : []}`,
58
+ },
59
+ };
60
+ } });
61
+ }
49
62
  static savedValueTypes(schema) {
50
63
  const { boolean, string, number, object, array } = utils_1.componentValueTypes;
51
64
  const { dataType } = schema;
@@ -10,8 +10,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.withRetries = void 0;
13
- function withRetries(fn_1, args_1) {
14
- return __awaiter(this, arguments, void 0, function* (fn, args, retries = 3, err = null) {
13
+ function withRetries(fn, args, retries = 3, err = null) {
14
+ return __awaiter(this, void 0, void 0, function* () {
15
15
  if (!retries) {
16
16
  throw new Error(err);
17
17
  }
@@ -15,7 +15,7 @@ class IsEqualTo extends ConditionOperator_1.default {
15
15
  }
16
16
  execute({ value, comparedValue, instance, conditionComponentPath }) {
17
17
  var _a;
18
- if (value && comparedValue && typeof value !== typeof comparedValue && lodash_1.default.isString(comparedValue)) {
18
+ if ((value || value === false) && comparedValue && typeof value !== typeof comparedValue && lodash_1.default.isString(comparedValue)) {
19
19
  try {
20
20
  comparedValue = JSON.parse(comparedValue);
21
21
  }
@@ -419,6 +419,14 @@ class CalendarWidget extends InputWidget_1.default {
419
419
  }
420
420
  }
421
421
  });
422
+ // If other fields are used to calculate disabled dates, we need to redraw calendar to refresh disabled dates
423
+ if (this.settings.disableFunction && this.componentInstance && this.componentInstance.root) {
424
+ this.componentInstance.root.on('change', (e) => {
425
+ if (e.changed && this.calendar) {
426
+ this.calendar.redraw();
427
+ }
428
+ });
429
+ }
422
430
  // Restore the calendar value from the component value.
423
431
  this.setValue(this.componentValue);
424
432
  }
package/lib/mjs/Form.js CHANGED
@@ -150,6 +150,36 @@ export default class Form extends Element {
150
150
  ]
151
151
  };
152
152
  }
153
+ /**
154
+ * Check Subdirectories path and provide correct options
155
+ *
156
+ * @param {string} url - The the URL of the form json.
157
+ * @param {form} object - The form json.
158
+ * @return {object} The initial options with base and project.
159
+ */
160
+ getFormInitOptions(url, form) {
161
+ const options = {};
162
+ const index = url.indexOf(form?.path);
163
+ // form url doesn't include form path
164
+ if (index === -1) {
165
+ return options;
166
+ }
167
+ const projectUrl = url.substring(0, index - 1);
168
+ const urlParts = Formio.getUrlParts(projectUrl);
169
+ // project url doesn't include subdirectories path
170
+ if (!urlParts || urlParts.filter(part => !!part).length < 4) {
171
+ return options;
172
+ }
173
+ const baseUrl = `${urlParts[1]}${urlParts[2]}`;
174
+ // Skip if baseUrl has already been set
175
+ if (baseUrl !== Formio.baseUrl) {
176
+ return {
177
+ base: baseUrl,
178
+ project: projectUrl,
179
+ };
180
+ }
181
+ return {};
182
+ }
153
183
  setForm(formParam) {
154
184
  let result;
155
185
  formParam = formParam || this.form;
@@ -174,7 +204,8 @@ export default class Form extends Element {
174
204
  }
175
205
  this.loading = false;
176
206
  this.instance = this.instance || this.create(form.display);
177
- this.instance.url = formParam;
207
+ const options = this.getFormInitOptions(formParam, form);
208
+ this.instance.setUrl(formParam, options);
178
209
  this.instance.nosubmit = false;
179
210
  this._form = this.instance.form = form;
180
211
  if (submission) {
@@ -1005,7 +1005,7 @@ export default class Webform extends NestedDataComponent {
1005
1005
  if (!Array.isArray(errors)) {
1006
1006
  errors = [errors];
1007
1007
  }
1008
- errors = errors.concat(this.customErrors);
1008
+ errors = errors.concat(this.customErrors).filter((err) => !!err);
1009
1009
  if (!errors.length) {
1010
1010
  this.setAlert(false);
1011
1011
  return;
@@ -115,6 +115,7 @@ export default class WebformBuilder extends Component {
115
115
  html,
116
116
  disableBuilderActions: self?.component?.disableBuilderActions,
117
117
  childComponent: component,
118
+ design: self?.options?.design
118
119
  });
119
120
  };
120
121
  this.options.hooks.renderComponents = (html, { components, self }) => {
@@ -472,6 +473,7 @@ export default class WebformBuilder extends Component {
472
473
  attach(element) {
473
474
  this.on('change', (form) => {
474
475
  this.populateRecaptchaSettings(form);
476
+ this.webform.setAlert(false);
475
477
  });
476
478
  return super.attach(element).then(() => {
477
479
  this.loadRefs(element, {
@@ -804,6 +806,20 @@ export default class WebformBuilder extends Component {
804
806
  return;
805
807
  }
806
808
  }
809
+ if (draggableComponent.uniqueComponent) {
810
+ let isCompAlreadyExists = false;
811
+ eachComponent(this.webform.components, (component) => {
812
+ if (component.key === draggableComponent.schema.key) {
813
+ isCompAlreadyExists = true;
814
+ return;
815
+ }
816
+ }, true);
817
+ if (isCompAlreadyExists) {
818
+ this.webform.redraw();
819
+ this.webform.setAlert('danger', `You cannot add more than one ${draggableComponent.title} component to one page.`);
820
+ return;
821
+ }
822
+ }
807
823
  if (target !== source) {
808
824
  // Ensure the key remains unique in its new container.
809
825
  BuilderUtils.uniquify(this.findNamespaceRoot(target.formioComponent), info);
@@ -836,7 +852,7 @@ export default class WebformBuilder extends Component {
836
852
  parent.addChildComponent(info, element, target, source, sibling);
837
853
  }
838
854
  const componentInDataGrid = parent.type === 'datagrid';
839
- if (isNew && !this.options.noNewEdit && !info.noNewEdit) {
855
+ if (isNew && !this.options.noNewEdit && !info.noNewEdit && !(this.options.design && info.type === 'reviewpage')) {
840
856
  this.editComponent(info, target, isNew, null, null, { inDataGrid: componentInDataGrid });
841
857
  }
842
858
  // Only rebuild the parts needing to be rebuilt.
@@ -196,7 +196,7 @@ export default class DataGridComponent extends NestedArrayComponent {
196
196
  return this.hasAddButton() && ['bottom', 'both'].includes(this.addAnotherPosition);
197
197
  }
198
198
  get canAddColumn() {
199
- return this.builderMode;
199
+ return this.builderMode && !this.options.design;
200
200
  }
201
201
  render() {
202
202
  const columns = this.getColumns();