@formio/js 5.4.2 → 5.4.4-api99.0

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.
Files changed (58) hide show
  1. package/dist/formio.embed.js +1 -1
  2. package/dist/formio.embed.min.js +1 -1
  3. package/dist/formio.embed.min.js.LICENSE.txt +1 -1
  4. package/dist/formio.form.js +25 -25
  5. package/dist/formio.form.min.js +1 -1
  6. package/dist/formio.form.min.js.LICENSE.txt +1 -1
  7. package/dist/formio.full.js +27 -27
  8. package/dist/formio.full.min.js +1 -1
  9. package/dist/formio.full.min.js.LICENSE.txt +1 -1
  10. package/dist/formio.js +7 -7
  11. package/dist/formio.min.js +1 -1
  12. package/dist/formio.min.js.LICENSE.txt +1 -1
  13. package/dist/formio.utils.js +2 -2
  14. package/dist/formio.utils.min.js +1 -1
  15. package/dist/formio.utils.min.js.LICENSE.txt +1 -1
  16. package/lib/cjs/Element.js +1 -1
  17. package/lib/cjs/Embed.js +1 -1
  18. package/lib/cjs/Formio.js +1 -1
  19. package/lib/cjs/Wizard.d.ts +1 -0
  20. package/lib/cjs/Wizard.js +15 -0
  21. package/lib/cjs/components/datagrid/DataGrid.js +8 -0
  22. package/lib/cjs/components/file/File.js +12 -5
  23. package/lib/cjs/components/file/editForm/File.edit.file.d.ts +9 -3
  24. package/lib/cjs/components/file/editForm/File.edit.file.js +20 -23
  25. package/lib/cjs/components/html/HTML.d.ts +1 -1
  26. package/lib/cjs/components/html/HTML.js +7 -5
  27. package/lib/cjs/components/number/Number.js +5 -1
  28. package/lib/cjs/components/radio/Radio.js +10 -0
  29. package/lib/cjs/components/signature/Signature.js +16 -14
  30. package/lib/cjs/components/signature/editForm/Signature.edit.display.d.ts +4 -10
  31. package/lib/cjs/components/signature/editForm/Signature.edit.display.js +8 -8
  32. package/lib/cjs/package.json +1 -1
  33. package/lib/cjs/providers/storage/indexeddb.js +14 -5
  34. package/lib/cjs/providers/storage/url.js +13 -2
  35. package/lib/cjs/providers/storage/xhr.js +1 -1
  36. package/lib/cjs/templates/index.d.ts +1 -0
  37. package/lib/mjs/Element.js +1 -1
  38. package/lib/mjs/Embed.js +1 -1
  39. package/lib/mjs/Formio.js +1 -1
  40. package/lib/mjs/Wizard.d.ts +1 -0
  41. package/lib/mjs/Wizard.js +15 -0
  42. package/lib/mjs/components/datagrid/DataGrid.js +7 -0
  43. package/lib/mjs/components/file/File.js +12 -5
  44. package/lib/mjs/components/file/editForm/File.edit.file.d.ts +9 -3
  45. package/lib/mjs/components/file/editForm/File.edit.file.js +20 -23
  46. package/lib/mjs/components/html/HTML.d.ts +1 -1
  47. package/lib/mjs/components/html/HTML.js +7 -5
  48. package/lib/mjs/components/number/Number.js +5 -1
  49. package/lib/mjs/components/radio/Radio.js +10 -0
  50. package/lib/mjs/components/signature/Signature.js +15 -13
  51. package/lib/mjs/components/signature/editForm/Signature.edit.display.d.ts +4 -10
  52. package/lib/mjs/components/signature/editForm/Signature.edit.display.js +6 -8
  53. package/lib/mjs/package.json +1 -1
  54. package/lib/mjs/providers/storage/indexeddb.js +14 -5
  55. package/lib/mjs/providers/storage/url.js +13 -2
  56. package/lib/mjs/providers/storage/xhr.js +1 -1
  57. package/lib/mjs/templates/index.d.ts +1 -0
  58. package/package.json +3 -3
@@ -20,7 +20,7 @@
20
20
 
21
21
  /*! @license DOMPurify 3.4.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.4.11/LICENSE */
22
22
 
23
- /*! formiojs v5.4.2 | https://unpkg.com/formiojs@5.4.2/LICENSE.txt */
23
+ /*! formiojs v5.4.4-api99.0 | https://unpkg.com/formiojs@5.4.4-api99.0/LICENSE.txt */
24
24
 
25
25
  /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
26
26
 
@@ -558,7 +558,7 @@ class Element {
558
558
  interpolate(string, data, options = {}) {
559
559
  if (typeof string !== 'function' &&
560
560
  (this.component.content || this.component.html) &&
561
- !utils_1.default.Evaluator.templateSettings.interpolate.test(string)) {
561
+ !(new RegExp(utils_1.default.Evaluator.templateSettings.interpolate)).test(string)) {
562
562
  string = utils_1.default.translateHTMLTemplate(String(string), (value) => this.t(value));
563
563
  }
564
564
  if (this.component.filter === string && !this.options.building) {
package/lib/cjs/Embed.js CHANGED
@@ -500,7 +500,7 @@ Formio.formioReady = new Promise((ready, reject) => {
500
500
  _a._formioReady = ready;
501
501
  _a._formioReadyReject = reject;
502
502
  });
503
- Formio.version = '5.4.2';
503
+ Formio.version = '5.4.4-api99.0';
504
504
  // Create a report.
505
505
  Formio.Report = {
506
506
  create: (element, submission, options = {}) => __awaiter(void 0, void 0, void 0, function* () {
package/lib/cjs/Formio.js CHANGED
@@ -11,7 +11,7 @@ const CDN_1 = __importDefault(require("./CDN"));
11
11
  const providers_1 = __importDefault(require("./providers"));
12
12
  sdk_1.Formio.cdn = new CDN_1.default();
13
13
  sdk_1.Formio.Providers = providers_1.default;
14
- sdk_1.Formio.version = '5.4.2';
14
+ sdk_1.Formio.version = '5.4.4-api99.0';
15
15
  CDN_1.default.defaultCDN = sdk_1.Formio.version.includes('rc')
16
16
  ? 'https://cdn.test-form.io'
17
17
  : 'https://cdn.form.io';
@@ -84,6 +84,7 @@ declare class Wizard extends Webform {
84
84
  get currentPage(): any;
85
85
  getNextPage(): number | null;
86
86
  getPreviousPage(): number;
87
+ renderTemplate(...args: any[]): any;
87
88
  mergeDefaultsFromSchema(data: any): void;
88
89
  beforeSubmit(): Promise<any[]>;
89
90
  beforePage(next: any): Promise<any>;
package/lib/cjs/Wizard.js CHANGED
@@ -678,6 +678,21 @@ class Wizard extends Webform_1.default {
678
678
  getPreviousPage() {
679
679
  return this.page - 1;
680
680
  }
681
+ renderTemplate(...args) {
682
+ if (args[0] === 'errorsList' && lodash_1.default.isPlainObject(args[1])) {
683
+ const pages = this.getPages({ all: true });
684
+ const errors = args[1].errors;
685
+ if (lodash_1.default.isArray(errors)) {
686
+ lodash_1.default.forEach(errors, (compWithError) => {
687
+ const pageNum = lodash_1.default.findIndex(pages, (page) => page.getComponent(compWithError.keyOrPath));
688
+ if (pageNum >= 0) {
689
+ compWithError.errorPageTitle = lodash_1.default.get(pages[pageNum], 'component.title');
690
+ }
691
+ });
692
+ }
693
+ }
694
+ return super.renderTemplate(...args);
695
+ }
681
696
  mergeDefaultsFromSchema(data) {
682
697
  var _a, _b;
683
698
  const components = (_a = this.form) === null || _a === void 0 ? void 0 : _a.components;
@@ -452,6 +452,7 @@ class DataGridComponent extends NestedArrayComponent_1.default {
452
452
  }
453
453
  removeRow(index) {
454
454
  const makeEmpty = index === 0 && this.rows.length === 1;
455
+ const wasLastRow = index === this.rows.length - 1;
455
456
  const flags = {
456
457
  isReordered: !makeEmpty,
457
458
  resetValue: makeEmpty,
@@ -466,6 +467,13 @@ class DataGridComponent extends NestedArrayComponent_1.default {
466
467
  this.updateRowsComponents(index);
467
468
  this.setValue(this.dataValue, flags);
468
469
  this.redraw().then(() => {
470
+ var _a, _b;
471
+ if (wasLastRow && (!makeEmpty || this.initEmpty)) {
472
+ (_b = (_a = this.refs[`${this.datagridKey}-addRow`]) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.focus();
473
+ }
474
+ else {
475
+ this.focusOnNewRowElement(this.rows[index]);
476
+ }
469
477
  this.announce(this.t('Row has been deleted'));
470
478
  });
471
479
  }
@@ -56,6 +56,7 @@ class FileComponent extends Field_1.default {
56
56
  fileMinSize: '0KB',
57
57
  fileMaxSize: '1GB',
58
58
  uploadOnly: false,
59
+ options: {},
59
60
  }, ...extend);
60
61
  }
61
62
  static get builderInfo() {
@@ -120,7 +121,7 @@ class FileComponent extends Field_1.default {
120
121
  return [];
121
122
  }
122
123
  getValueAsString(value, options) {
123
- if ((options === null || options === void 0 ? void 0 : options.review) && !this.component.uploadOnly) {
124
+ if ((options === null || options === void 0 ? void 0 : options.review) && !this.component.uploadOnly && !(options === null || options === void 0 ? void 0 : options.pdf)) {
124
125
  return lodash_1.default.map(value, (val, index) => {
125
126
  return `<a href="${val.url || '#'}" target="_blank" data-path='${this.path}' data-fileindex='${index}'>${val.originalName}</a>`;
126
127
  }).join(', ');
@@ -635,7 +636,9 @@ class FileComponent extends Field_1.default {
635
636
  originalName: escapedFileName,
636
637
  fileKey: this.component.fileKey || 'file',
637
638
  storage: this.component.storage,
638
- options: this.component.options,
639
+ options: this.component.storage === 'url'
640
+ ? (this.component.urlRequestOptions || this.component.options)
641
+ : this.component.options,
639
642
  file,
640
643
  size: file.size,
641
644
  status: 'info',
@@ -868,7 +871,9 @@ class FileComponent extends Field_1.default {
868
871
  }
869
872
  deleteFile(fileInfo) {
870
873
  return __awaiter(this, void 0, void 0, function* () {
871
- const { options = {} } = this.component;
874
+ const options = this.component.storage === 'url'
875
+ ? (this.component.urlRequestOptions || this.component.options || {})
876
+ : (this.component.options || {});
872
877
  if (fileInfo &&
873
878
  ['url', 'indexeddb', 's3', 'azure', 'googledrive'].includes(this.component.storage)) {
874
879
  const { fileService } = this;
@@ -997,7 +1002,7 @@ class FileComponent extends Field_1.default {
997
1002
  ? response
998
1003
  : response.type === 'abort'
999
1004
  ? this.t('requestAborted')
1000
- : response.toString();
1005
+ : response.message || response.toString();
1001
1006
  this.emit('fileUploadingEnd', Promise.reject(response));
1002
1007
  this.emit(lodash_1.default.get(response, 'type') === 'abort' ? 'fileUploadCanceled' : 'fileUploadError', {
1003
1008
  fileToSync,
@@ -1065,7 +1070,9 @@ class FileComponent extends Field_1.default {
1065
1070
  });
1066
1071
  }
1067
1072
  getFile(fileInfo) {
1068
- const { options = {} } = this.component;
1073
+ const options = this.component.storage === 'url'
1074
+ ? (this.component.urlRequestOptions || this.component.options || {})
1075
+ : (this.component.options || {});
1069
1076
  const { fileService } = this;
1070
1077
  if (!fileService) {
1071
1078
  return alert(this.t('noFileService'));
@@ -131,11 +131,10 @@ declare const _default: ({
131
131
  values?: undefined;
132
132
  } | {
133
133
  type: string;
134
- input: boolean;
135
134
  key: string;
136
135
  label: string;
137
136
  weight: number;
138
- placeholder: string;
137
+ input: boolean;
139
138
  conditional: {
140
139
  json: {
141
140
  in: (string[] | {
@@ -145,12 +144,19 @@ declare const _default: ({
145
144
  '=='?: undefined;
146
145
  };
147
146
  };
147
+ components: {
148
+ type: string;
149
+ input: boolean;
150
+ key: string;
151
+ label: string;
152
+ placeholder: string;
153
+ }[];
154
+ placeholder?: undefined;
148
155
  tooltip?: undefined;
149
156
  valueProperty?: undefined;
150
157
  dataSrc?: undefined;
151
158
  data?: undefined;
152
159
  tableView?: undefined;
153
- components?: undefined;
154
160
  rows?: undefined;
155
161
  editor?: undefined;
156
162
  as?: undefined;
@@ -84,30 +84,11 @@ exports.default = [
84
84
  },
85
85
  },
86
86
  {
87
- type: 'textfield',
88
- input: true,
89
- key: 'options.indexeddb',
90
- label: 'Database',
87
+ type: 'container',
88
+ key: 'options',
89
+ label: 'IndexedDB options',
91
90
  weight: 10,
92
- placeholder: 'Enter the indexeddb database name',
93
- conditional: {
94
- json: {
95
- in: [
96
- {
97
- var: 'data.storage',
98
- },
99
- ['indexeddb'],
100
- ],
101
- },
102
- },
103
- },
104
- {
105
- type: 'textfield',
106
91
  input: true,
107
- label: 'Table',
108
- key: 'options.indexeddbTable',
109
- weight: 10,
110
- placeholder: 'Enter the name for indexeddb table',
111
92
  conditional: {
112
93
  json: {
113
94
  in: [
@@ -118,10 +99,26 @@ exports.default = [
118
99
  ],
119
100
  },
120
101
  },
102
+ components: [
103
+ {
104
+ type: 'textfield',
105
+ input: true,
106
+ key: 'indexeddb',
107
+ label: 'Database',
108
+ placeholder: 'Enter the indexeddb database name',
109
+ },
110
+ {
111
+ type: 'textfield',
112
+ input: true,
113
+ key: 'indexeddbTable',
114
+ label: 'Table',
115
+ placeholder: 'Enter the name for indexeddb table',
116
+ },
117
+ ],
121
118
  },
122
119
  {
123
120
  type: 'textarea',
124
- key: 'options',
121
+ key: 'urlRequestOptions',
125
122
  label: 'Custom request options',
126
123
  tooltip: 'Pass your custom xhr options(optional)',
127
124
  rows: 5,
@@ -12,7 +12,7 @@ export default class HTMLComponent extends Component {
12
12
  get content(): any;
13
13
  get singleTags(): string[];
14
14
  checkRefreshOn(changed: any): void;
15
- renderContent(): any;
15
+ renderContent(content?: any): any;
16
16
  render(): string;
17
17
  get dataReady(): any;
18
18
  attach(element: any): Promise<void>;
@@ -71,7 +71,7 @@ class HTMLComponent extends Component_1.default {
71
71
  this.setContent(this.element, this.renderContent());
72
72
  }
73
73
  }
74
- renderContent() {
74
+ renderContent(content = this.content) {
75
75
  const submission = lodash_1.default.get(this.root, 'submission', {});
76
76
  return this.renderTemplate('html', {
77
77
  component: this.component,
@@ -87,12 +87,12 @@ class HTMLComponent extends Component_1.default {
87
87
  }),
88
88
  };
89
89
  }),
90
- content: this.content,
90
+ content,
91
91
  singleTags: this.singleTags,
92
92
  });
93
93
  }
94
94
  render() {
95
- return super.render(this.renderContent());
95
+ return super.render(this.renderContent(''));
96
96
  }
97
97
  get dataReady() {
98
98
  var _a;
@@ -100,11 +100,13 @@ class HTMLComponent extends Component_1.default {
100
100
  }
101
101
  attach(element) {
102
102
  this.loadRefs(element, { html: 'single' });
103
- this.dataReady.then(() => {
103
+ const setHtmlContent = () => {
104
104
  if (this.refs.html) {
105
105
  this.setContent(this.refs.html, this.content);
106
106
  }
107
- });
107
+ };
108
+ setHtmlContent();
109
+ this.dataReady.then(setHtmlContent);
108
110
  return super.attach(element);
109
111
  }
110
112
  }
@@ -188,7 +188,11 @@ class NumberComponent extends Input_1.default {
188
188
  return null;
189
189
  }
190
190
  const val = this.refs.input[index].value;
191
- return val && val !== '-_' ? this.parseNumber(val) : null;
191
+ const result = val && val !== '-_' ? this.parseNumber(val) : null;
192
+ if (lodash_1.default.isNaN(result)) {
193
+ return null;
194
+ }
195
+ return result;
192
196
  }
193
197
  setValueAt(index, value, flags = {}) {
194
198
  return super.setValueAt(index, this.formatValue(this.parseValue(value)), flags);
@@ -344,6 +344,16 @@ class RadioComponent extends ListComponent_1.default {
344
344
  setItems(items) {
345
345
  var _a;
346
346
  const listData = [];
347
+ // If the items is a string, then parse as JSON.
348
+ if (typeof items == 'string') {
349
+ try {
350
+ items = JSON.parse(items);
351
+ }
352
+ catch (err) {
353
+ console.warn(err.message);
354
+ items = [];
355
+ }
356
+ }
347
357
  items === null || items === void 0 ? void 0 : items.forEach((item, i) => {
348
358
  const valueAtProperty = lodash_1.default.get(item, this.component.valueProperty);
349
359
  this.loadedOptions[i] = {
@@ -44,23 +44,25 @@ class SignatureComponent extends Input_1.default {
44
44
  return (0, utils_1.getComponentSavedTypes)(schema) || [utils_1.componentValueTypes.string];
45
45
  }
46
46
  init() {
47
- var _a, _b, _c, _d;
47
+ var _a, _b, _c, _d, _e;
48
48
  super.init();
49
49
  this.currentWidth = 0;
50
50
  this.scale = 1;
51
- if (!this.component.width) {
52
- this.component.width = '100%';
53
- }
54
- if (!this.component.height) {
55
- this.component.height = '200px';
56
- }
57
- if (this.component.keepOverlayRatio &&
58
- this.options.pdf &&
59
- ((_a = this.component.overlay) === null || _a === void 0 ? void 0 : _a.width) &&
60
- ((_b = this.component.overlay) === null || _b === void 0 ? void 0 : _b.height)) {
61
- this.ratio = ((_c = this.component.overlay) === null || _c === void 0 ? void 0 : _c.width) / ((_d = this.component.overlay) === null || _d === void 0 ? void 0 : _d.height);
62
- this.component.width = '100%';
63
- this.component.height = 'auto';
51
+ if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.inFormBuilder) {
52
+ if (!this.component.width) {
53
+ this.component.width = '100%';
54
+ }
55
+ if (!this.component.height) {
56
+ this.component.height = '200px';
57
+ }
58
+ if (this.component.keepOverlayRatio &&
59
+ this.options.pdf &&
60
+ ((_b = this.component.overlay) === null || _b === void 0 ? void 0 : _b.width) &&
61
+ ((_c = this.component.overlay) === null || _c === void 0 ? void 0 : _c.height)) {
62
+ this.ratio = ((_d = this.component.overlay) === null || _d === void 0 ? void 0 : _d.width) / ((_e = this.component.overlay) === null || _e === void 0 ? void 0 : _e.height);
63
+ this.component.width = '100%';
64
+ this.component.height = 'auto';
65
+ }
64
66
  }
65
67
  }
66
68
  get emptyValue() {
@@ -6,7 +6,7 @@ declare const _default: ({
6
6
  tooltip: string;
7
7
  placeholder: string;
8
8
  weight: number;
9
- conditional?: undefined;
9
+ customConditional?: undefined;
10
10
  ignore?: undefined;
11
11
  } | {
12
12
  type: string;
@@ -15,13 +15,7 @@ declare const _default: ({
15
15
  label: string;
16
16
  tooltip: string;
17
17
  placeholder: string;
18
- conditional: {
19
- json: {
20
- '!': {
21
- var: string;
22
- }[];
23
- };
24
- };
18
+ customConditional: (context: any) => boolean;
25
19
  weight: number;
26
20
  ignore?: undefined;
27
21
  } | {
@@ -32,7 +26,7 @@ declare const _default: ({
32
26
  key: string;
33
27
  input: boolean;
34
28
  placeholder?: undefined;
35
- conditional?: undefined;
29
+ customConditional?: undefined;
36
30
  ignore?: undefined;
37
31
  } | {
38
32
  key: string;
@@ -43,6 +37,6 @@ declare const _default: ({
43
37
  tooltip?: undefined;
44
38
  placeholder?: undefined;
45
39
  weight?: undefined;
46
- conditional?: undefined;
40
+ customConditional?: undefined;
47
41
  })[];
48
42
  export default _default;
@@ -17,10 +17,10 @@ exports.default = [
17
17
  label: 'Width',
18
18
  tooltip: 'The width of the signature area.',
19
19
  placeholder: 'Width',
20
- conditional: {
21
- json: {
22
- '!': [{ var: 'data.keepOverlayRatio' }],
23
- },
20
+ customConditional: (context) => {
21
+ var _a, _b, _c;
22
+ const isPdf = ((_b = (_a = context.options) === null || _a === void 0 ? void 0 : _a.editForm) === null || _b === void 0 ? void 0 : _b.display) === 'pdf';
23
+ return isPdf ? !((_c = context.data) === null || _c === void 0 ? void 0 : _c.keepOverlayRatio) : true;
24
24
  },
25
25
  weight: 50,
26
26
  },
@@ -31,10 +31,10 @@ exports.default = [
31
31
  label: 'Height',
32
32
  tooltip: 'The height of the signature area.',
33
33
  placeholder: 'Height',
34
- conditional: {
35
- json: {
36
- '!': [{ var: 'data.keepOverlayRatio' }],
37
- },
34
+ customConditional: (context) => {
35
+ var _a, _b, _c;
36
+ const isPdf = ((_b = (_a = context.options) === null || _a === void 0 ? void 0 : _a.editForm) === null || _b === void 0 ? void 0 : _b.display) === 'pdf';
37
+ return isPdf ? !((_c = context.data) === null || _c === void 0 ? void 0 : _c.keepOverlayRatio) : true;
38
38
  },
39
39
  weight: 51,
40
40
  },
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "type": "commonjs",
3
- "version": "5.4.2"
3
+ "version": "5.4.4-api99.0"
4
4
  }
@@ -63,21 +63,30 @@ function indexeddb() {
63
63
  });
64
64
  },
65
65
  downloadFile(file, options) {
66
+ const opts = (options === null || options === void 0 ? void 0 : options.options) || options || {};
67
+ const dbName = opts.indexeddb;
68
+ const tableName = opts.indexeddbTable;
69
+ if (!dbName || !tableName) {
70
+ return Promise.reject(new Error('IndexedDB storage options (indexeddb, indexeddbTable) are required for download'));
71
+ }
66
72
  return new Promise((resolve) => {
67
- const request = indexedDB.open(options.indexeddb);
73
+ const request = indexedDB.open(dbName);
68
74
  request.onsuccess = function (event) {
69
75
  const db = event.target.result;
70
76
  resolve(db);
71
77
  };
72
78
  }).then((db) => {
73
79
  return new Promise((resolve, reject) => {
74
- const trans = db.transaction([options.indexeddbTable], 'readonly');
75
- const store = trans.objectStore(options.indexeddbTable).get(file.id);
80
+ const trans = db.transaction(tableName, 'readonly');
81
+ const store = trans.objectStore(tableName).get(file.id);
76
82
  store.onsuccess = () => {
77
83
  trans.oncomplete = () => {
78
84
  const result = store.result;
79
- const dbFile = new File([store.result.data], file.name, {
80
- type: store.result.type,
85
+ if (!result || !result.data) {
86
+ return reject(new Error('File not found in IndexedDB'));
87
+ }
88
+ const dbFile = new File([result.data], file.name, {
89
+ type: result.type,
81
90
  });
82
91
  const reader = new FileReader();
83
92
  reader.onload = (event) => {
@@ -66,8 +66,19 @@ function url(formio) {
66
66
  reject(xhr.response || 'Unable to upload file');
67
67
  }
68
68
  };
69
- xhr.onerror = () => reject(xhr);
70
- xhr.onabort = () => reject(xhr);
69
+ xhr.onerror = () => {
70
+ xhr.message =
71
+ xhr.status >= 400
72
+ ? `${xhr.status} ${xhr.statusText || ''}`.trim()
73
+ : xhr.statusText && xhr.statusText.trim()
74
+ ? xhr.statusText.trim()
75
+ : 'Unable to upload file';
76
+ return reject(xhr);
77
+ };
78
+ xhr.onabort = () => {
79
+ xhr.type = 'abort';
80
+ return reject(xhr);
81
+ };
71
82
  let requestUrl = url + (url.indexOf('?') > -1 ? '&' : '?');
72
83
  for (const key in query) {
73
84
  requestUrl += `${key}=${query[key]}&`;
@@ -41,7 +41,7 @@ const XHR = {
41
41
  },
42
42
  upload(formio, type, xhrCallback, file, fileName, dir, progressCallback, groupPermissions, groupId, abortCallback, multipartOptions) {
43
43
  return __awaiter(this, void 0, void 0, function* () {
44
- // Use makeRequest so portal plugins (e.g. x-remote-token) are applied.
44
+ // Use makeRequest so portal plugins (e.g. x-remote-token) are applied. GOTCHA(G-FJS05)
45
45
  let serverResponse;
46
46
  try {
47
47
  serverResponse = yield formio.makeRequest('file', `${formio.formUrl}/storage/${type}`, 'POST', {
@@ -43,6 +43,7 @@ declare namespace _default {
43
43
  iconClass: (iconset: "fa" | "bi", name: string, spinning: boolean) => string;
44
44
  cssClasses: {
45
45
  'border-default': string;
46
+ 'sr-only': string;
46
47
  'formio-tab-panel-active': string;
47
48
  'formio-tab-link-active': string;
48
49
  'formio-tab-link-container-active': string;
@@ -546,7 +546,7 @@ export default class Element {
546
546
  interpolate(string, data, options = {}) {
547
547
  if (typeof string !== 'function' &&
548
548
  (this.component.content || this.component.html) &&
549
- !FormioUtils.Evaluator.templateSettings.interpolate.test(string)) {
549
+ !(new RegExp(FormioUtils.Evaluator.templateSettings.interpolate)).test(string)) {
550
550
  string = FormioUtils.translateHTMLTemplate(String(string), (value) => this.t(value));
551
551
  }
552
552
  if (this.component.filter === string && !this.options.building) {
package/lib/mjs/Embed.js CHANGED
@@ -14,7 +14,7 @@ export class Formio {
14
14
  Formio._formioReady = ready;
15
15
  Formio._formioReadyReject = reject;
16
16
  });
17
- static version = '5.4.2';
17
+ static version = '5.4.4-api99.0';
18
18
  static setLicense(license, norecurse = false) {
19
19
  Formio.license = license;
20
20
  if (!norecurse && Formio.FormioClass) {
package/lib/mjs/Formio.js CHANGED
@@ -4,7 +4,7 @@ import CDN from './CDN';
4
4
  import Providers from './providers';
5
5
  FormioCore.cdn = new CDN();
6
6
  FormioCore.Providers = Providers;
7
- FormioCore.version = '5.4.2';
7
+ FormioCore.version = '5.4.4-api99.0';
8
8
  CDN.defaultCDN = FormioCore.version.includes('rc')
9
9
  ? 'https://cdn.test-form.io'
10
10
  : 'https://cdn.form.io';
@@ -84,6 +84,7 @@ declare class Wizard extends Webform {
84
84
  get currentPage(): any;
85
85
  getNextPage(): number | null;
86
86
  getPreviousPage(): number;
87
+ renderTemplate(...args: any[]): any;
87
88
  mergeDefaultsFromSchema(data: any): void;
88
89
  beforeSubmit(): Promise<any[]>;
89
90
  beforePage(next: any): Promise<any>;
package/lib/mjs/Wizard.js CHANGED
@@ -664,6 +664,21 @@ export default class Wizard extends Webform {
664
664
  getPreviousPage() {
665
665
  return this.page - 1;
666
666
  }
667
+ renderTemplate(...args) {
668
+ if (args[0] === 'errorsList' && _.isPlainObject(args[1])) {
669
+ const pages = this.getPages({ all: true });
670
+ const errors = args[1].errors;
671
+ if (_.isArray(errors)) {
672
+ _.forEach(errors, (compWithError) => {
673
+ const pageNum = _.findIndex(pages, (page) => page.getComponent(compWithError.keyOrPath));
674
+ if (pageNum >= 0) {
675
+ compWithError.errorPageTitle = _.get(pages[pageNum], 'component.title');
676
+ }
677
+ });
678
+ }
679
+ }
680
+ return super.renderTemplate(...args);
681
+ }
667
682
  mergeDefaultsFromSchema(data) {
668
683
  const components = this.form?.components;
669
684
  if (!components || !data || this.options?.readOnly) {
@@ -446,6 +446,7 @@ export default class DataGridComponent extends NestedArrayComponent {
446
446
  }
447
447
  removeRow(index) {
448
448
  const makeEmpty = index === 0 && this.rows.length === 1;
449
+ const wasLastRow = index === this.rows.length - 1;
449
450
  const flags = {
450
451
  isReordered: !makeEmpty,
451
452
  resetValue: makeEmpty,
@@ -460,6 +461,12 @@ export default class DataGridComponent extends NestedArrayComponent {
460
461
  this.updateRowsComponents(index);
461
462
  this.setValue(this.dataValue, flags);
462
463
  this.redraw().then(() => {
464
+ if (wasLastRow && (!makeEmpty || this.initEmpty)) {
465
+ this.refs[`${this.datagridKey}-addRow`]?.[0]?.focus();
466
+ }
467
+ else {
468
+ this.focusOnNewRowElement(this.rows[index]);
469
+ }
463
470
  this.announce(this.t('Row has been deleted'));
464
471
  });
465
472
  }