@formio/js 5.4.2 → 5.4.3

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 (56) 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 +23 -23
  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 +25 -25
  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 +5 -5
  11. package/dist/formio.min.js +1 -1
  12. package/dist/formio.min.js.LICENSE.txt +1 -1
  13. package/dist/formio.utils.min.js.LICENSE.txt +1 -1
  14. package/lib/cjs/Element.js +1 -1
  15. package/lib/cjs/Embed.js +1 -1
  16. package/lib/cjs/Formio.js +1 -1
  17. package/lib/cjs/Wizard.d.ts +1 -0
  18. package/lib/cjs/Wizard.js +15 -0
  19. package/lib/cjs/components/datagrid/DataGrid.js +8 -0
  20. package/lib/cjs/components/file/File.js +12 -5
  21. package/lib/cjs/components/file/editForm/File.edit.file.d.ts +9 -3
  22. package/lib/cjs/components/file/editForm/File.edit.file.js +20 -23
  23. package/lib/cjs/components/html/HTML.d.ts +1 -1
  24. package/lib/cjs/components/html/HTML.js +7 -5
  25. package/lib/cjs/components/number/Number.js +5 -1
  26. package/lib/cjs/components/radio/Radio.js +10 -0
  27. package/lib/cjs/components/signature/Signature.js +16 -14
  28. package/lib/cjs/components/signature/editForm/Signature.edit.display.d.ts +4 -10
  29. package/lib/cjs/components/signature/editForm/Signature.edit.display.js +8 -8
  30. package/lib/cjs/package.json +1 -1
  31. package/lib/cjs/providers/storage/indexeddb.js +14 -5
  32. package/lib/cjs/providers/storage/url.js +13 -2
  33. package/lib/cjs/providers/storage/xhr.js +1 -1
  34. package/lib/cjs/templates/index.d.ts +1 -0
  35. package/lib/mjs/Element.js +1 -1
  36. package/lib/mjs/Embed.js +1 -1
  37. package/lib/mjs/Formio.js +1 -1
  38. package/lib/mjs/Wizard.d.ts +1 -0
  39. package/lib/mjs/Wizard.js +15 -0
  40. package/lib/mjs/components/datagrid/DataGrid.js +7 -0
  41. package/lib/mjs/components/file/File.js +12 -5
  42. package/lib/mjs/components/file/editForm/File.edit.file.d.ts +9 -3
  43. package/lib/mjs/components/file/editForm/File.edit.file.js +20 -23
  44. package/lib/mjs/components/html/HTML.d.ts +1 -1
  45. package/lib/mjs/components/html/HTML.js +7 -5
  46. package/lib/mjs/components/number/Number.js +5 -1
  47. package/lib/mjs/components/radio/Radio.js +10 -0
  48. package/lib/mjs/components/signature/Signature.js +15 -13
  49. package/lib/mjs/components/signature/editForm/Signature.edit.display.d.ts +4 -10
  50. package/lib/mjs/components/signature/editForm/Signature.edit.display.js +6 -8
  51. package/lib/mjs/package.json +1 -1
  52. package/lib/mjs/providers/storage/indexeddb.js +14 -5
  53. package/lib/mjs/providers/storage/url.js +13 -2
  54. package/lib/mjs/providers/storage/xhr.js +1 -1
  55. package/lib/mjs/templates/index.d.ts +1 -0
  56. package/package.json +2 -2
@@ -42,6 +42,7 @@ export default class FileComponent extends Field {
42
42
  fileMinSize: '0KB',
43
43
  fileMaxSize: '1GB',
44
44
  uploadOnly: false,
45
+ options: {},
45
46
  }, ...extend);
46
47
  }
47
48
  static get builderInfo() {
@@ -109,7 +110,7 @@ export default class FileComponent extends Field {
109
110
  return [];
110
111
  }
111
112
  getValueAsString(value, options) {
112
- if (options?.review && !this.component.uploadOnly) {
113
+ if (options?.review && !this.component.uploadOnly && !options?.pdf) {
113
114
  return _.map(value, (val, index) => {
114
115
  return `<a href="${val.url || '#'}" target="_blank" data-path='${this.path}' data-fileindex='${index}'>${val.originalName}</a>`;
115
116
  }).join(', ');
@@ -633,7 +634,9 @@ export default class FileComponent extends Field {
633
634
  originalName: escapedFileName,
634
635
  fileKey: this.component.fileKey || 'file',
635
636
  storage: this.component.storage,
636
- options: this.component.options,
637
+ options: this.component.storage === 'url'
638
+ ? (this.component.urlRequestOptions || this.component.options)
639
+ : this.component.options,
637
640
  file,
638
641
  size: file.size,
639
642
  status: 'info',
@@ -862,7 +865,9 @@ export default class FileComponent extends Field {
862
865
  }
863
866
  }
864
867
  async deleteFile(fileInfo) {
865
- const { options = {} } = this.component;
868
+ const options = this.component.storage === 'url'
869
+ ? (this.component.urlRequestOptions || this.component.options || {})
870
+ : (this.component.options || {});
866
871
  if (fileInfo &&
867
872
  ['url', 'indexeddb', 's3', 'azure', 'googledrive'].includes(this.component.storage)) {
868
873
  const { fileService } = this;
@@ -990,7 +995,7 @@ export default class FileComponent extends Field {
990
995
  ? response
991
996
  : response.type === 'abort'
992
997
  ? this.t('requestAborted')
993
- : response.toString();
998
+ : response.message || response.toString();
994
999
  this.emit('fileUploadingEnd', Promise.reject(response));
995
1000
  this.emit(_.get(response, 'type') === 'abort' ? 'fileUploadCanceled' : 'fileUploadError', {
996
1001
  fileToSync,
@@ -1054,7 +1059,9 @@ export default class FileComponent extends Field {
1054
1059
  }
1055
1060
  }
1056
1061
  getFile(fileInfo) {
1057
- const { options = {} } = this.component;
1062
+ const options = this.component.storage === 'url'
1063
+ ? (this.component.urlRequestOptions || this.component.options || {})
1064
+ : (this.component.options || {});
1058
1065
  const { fileService } = this;
1059
1066
  if (!fileService) {
1060
1067
  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;
@@ -79,30 +79,11 @@ export default [
79
79
  },
80
80
  },
81
81
  {
82
- type: 'textfield',
83
- input: true,
84
- key: 'options.indexeddb',
85
- label: 'Database',
82
+ type: 'container',
83
+ key: 'options',
84
+ label: 'IndexedDB options',
86
85
  weight: 10,
87
- placeholder: 'Enter the indexeddb database name',
88
- conditional: {
89
- json: {
90
- in: [
91
- {
92
- var: 'data.storage',
93
- },
94
- ['indexeddb'],
95
- ],
96
- },
97
- },
98
- },
99
- {
100
- type: 'textfield',
101
86
  input: true,
102
- label: 'Table',
103
- key: 'options.indexeddbTable',
104
- weight: 10,
105
- placeholder: 'Enter the name for indexeddb table',
106
87
  conditional: {
107
88
  json: {
108
89
  in: [
@@ -113,10 +94,26 @@ export default [
113
94
  ],
114
95
  },
115
96
  },
97
+ components: [
98
+ {
99
+ type: 'textfield',
100
+ input: true,
101
+ key: 'indexeddb',
102
+ label: 'Database',
103
+ placeholder: 'Enter the indexeddb database name',
104
+ },
105
+ {
106
+ type: 'textfield',
107
+ input: true,
108
+ key: 'indexeddbTable',
109
+ label: 'Table',
110
+ placeholder: 'Enter the name for indexeddb table',
111
+ },
112
+ ],
116
113
  },
117
114
  {
118
115
  type: 'textarea',
119
- key: 'options',
116
+ key: 'urlRequestOptions',
120
117
  label: 'Custom request options',
121
118
  tooltip: 'Pass your custom xhr options(optional)',
122
119
  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>;
@@ -66,7 +66,7 @@ export default class HTMLComponent extends Component {
66
66
  this.setContent(this.element, this.renderContent());
67
67
  }
68
68
  }
69
- renderContent() {
69
+ renderContent(content = this.content) {
70
70
  const submission = _.get(this.root, 'submission', {});
71
71
  return this.renderTemplate('html', {
72
72
  component: this.component,
@@ -82,23 +82,25 @@ export default class HTMLComponent extends Component {
82
82
  }),
83
83
  };
84
84
  }),
85
- content: this.content,
85
+ content,
86
86
  singleTags: this.singleTags,
87
87
  });
88
88
  }
89
89
  render() {
90
- return super.render(this.renderContent());
90
+ return super.render(this.renderContent(''));
91
91
  }
92
92
  get dataReady() {
93
93
  return this.root?.submissionReady || Promise.resolve();
94
94
  }
95
95
  attach(element) {
96
96
  this.loadRefs(element, { html: 'single' });
97
- this.dataReady.then(() => {
97
+ const setHtmlContent = () => {
98
98
  if (this.refs.html) {
99
99
  this.setContent(this.refs.html, this.content);
100
100
  }
101
- });
101
+ };
102
+ setHtmlContent();
103
+ this.dataReady.then(setHtmlContent);
102
104
  return super.attach(element);
103
105
  }
104
106
  }
@@ -185,7 +185,11 @@ export default class NumberComponent extends Input {
185
185
  return null;
186
186
  }
187
187
  const val = this.refs.input[index].value;
188
- return val && val !== '-_' ? this.parseNumber(val) : null;
188
+ const result = val && val !== '-_' ? this.parseNumber(val) : null;
189
+ if (_.isNaN(result)) {
190
+ return null;
191
+ }
192
+ return result;
189
193
  }
190
194
  setValueAt(index, value, flags = {}) {
191
195
  return super.setValueAt(index, this.formatValue(this.parseValue(value)), flags);
@@ -343,6 +343,16 @@ export default class RadioComponent extends ListComponent {
343
343
  }
344
344
  setItems(items) {
345
345
  const listData = [];
346
+ // If the items is a string, then parse as JSON.
347
+ if (typeof items == 'string') {
348
+ try {
349
+ items = JSON.parse(items);
350
+ }
351
+ catch (err) {
352
+ console.warn(err.message);
353
+ items = [];
354
+ }
355
+ }
346
356
  items?.forEach((item, i) => {
347
357
  const valueAtProperty = _.get(item, this.component.valueProperty);
348
358
  this.loadedOptions[i] = {
@@ -45,19 +45,21 @@ export default class SignatureComponent extends Input {
45
45
  super.init();
46
46
  this.currentWidth = 0;
47
47
  this.scale = 1;
48
- if (!this.component.width) {
49
- this.component.width = '100%';
50
- }
51
- if (!this.component.height) {
52
- this.component.height = '200px';
53
- }
54
- if (this.component.keepOverlayRatio &&
55
- this.options.pdf &&
56
- this.component.overlay?.width &&
57
- this.component.overlay?.height) {
58
- this.ratio = this.component.overlay?.width / this.component.overlay?.height;
59
- this.component.width = '100%';
60
- this.component.height = 'auto';
48
+ if (this.options?.inFormBuilder) {
49
+ if (!this.component.width) {
50
+ this.component.width = '100%';
51
+ }
52
+ if (!this.component.height) {
53
+ this.component.height = '200px';
54
+ }
55
+ if (this.component.keepOverlayRatio &&
56
+ this.options.pdf &&
57
+ this.component.overlay?.width &&
58
+ this.component.overlay?.height) {
59
+ this.ratio = this.component.overlay?.width / this.component.overlay?.height;
60
+ this.component.width = '100%';
61
+ this.component.height = 'auto';
62
+ }
61
63
  }
62
64
  }
63
65
  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;
@@ -15,10 +15,9 @@ export default [
15
15
  label: 'Width',
16
16
  tooltip: 'The width of the signature area.',
17
17
  placeholder: 'Width',
18
- conditional: {
19
- json: {
20
- '!': [{ var: 'data.keepOverlayRatio' }],
21
- },
18
+ customConditional: (context) => {
19
+ const isPdf = context.options?.editForm?.display === 'pdf';
20
+ return isPdf ? !context.data?.keepOverlayRatio : true;
22
21
  },
23
22
  weight: 50,
24
23
  },
@@ -29,10 +28,9 @@ export default [
29
28
  label: 'Height',
30
29
  tooltip: 'The height of the signature area.',
31
30
  placeholder: 'Height',
32
- conditional: {
33
- json: {
34
- '!': [{ var: 'data.keepOverlayRatio' }],
35
- },
31
+ customConditional: (context) => {
32
+ const isPdf = context.options?.editForm?.display === 'pdf';
33
+ return isPdf ? !context.data?.keepOverlayRatio : true;
36
34
  },
37
35
  weight: 51,
38
36
  },
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "type": "module",
3
- "version": "5.4.2"
3
+ "version": "5.4.3"
4
4
 
5
5
  }
@@ -61,21 +61,30 @@ function indexeddb() {
61
61
  });
62
62
  },
63
63
  downloadFile(file, options) {
64
+ const opts = options?.options || options || {};
65
+ const dbName = opts.indexeddb;
66
+ const tableName = opts.indexeddbTable;
67
+ if (!dbName || !tableName) {
68
+ return Promise.reject(new Error('IndexedDB storage options (indexeddb, indexeddbTable) are required for download'));
69
+ }
64
70
  return new Promise((resolve) => {
65
- const request = indexedDB.open(options.indexeddb);
71
+ const request = indexedDB.open(dbName);
66
72
  request.onsuccess = function (event) {
67
73
  const db = event.target.result;
68
74
  resolve(db);
69
75
  };
70
76
  }).then((db) => {
71
77
  return new Promise((resolve, reject) => {
72
- const trans = db.transaction([options.indexeddbTable], 'readonly');
73
- const store = trans.objectStore(options.indexeddbTable).get(file.id);
78
+ const trans = db.transaction(tableName, 'readonly');
79
+ const store = trans.objectStore(tableName).get(file.id);
74
80
  store.onsuccess = () => {
75
81
  trans.oncomplete = () => {
76
82
  const result = store.result;
77
- const dbFile = new File([store.result.data], file.name, {
78
- type: store.result.type,
83
+ if (!result || !result.data) {
84
+ return reject(new Error('File not found in IndexedDB'));
85
+ }
86
+ const dbFile = new File([result.data], file.name, {
87
+ type: result.type,
79
88
  });
80
89
  const reader = new FileReader();
81
90
  reader.onload = (event) => {
@@ -64,8 +64,19 @@ function url(formio) {
64
64
  reject(xhr.response || 'Unable to upload file');
65
65
  }
66
66
  };
67
- xhr.onerror = () => reject(xhr);
68
- xhr.onabort = () => reject(xhr);
67
+ xhr.onerror = () => {
68
+ xhr.message =
69
+ xhr.status >= 400
70
+ ? `${xhr.status} ${xhr.statusText || ''}`.trim()
71
+ : xhr.statusText && xhr.statusText.trim()
72
+ ? xhr.statusText.trim()
73
+ : 'Unable to upload file';
74
+ return reject(xhr);
75
+ };
76
+ xhr.onabort = () => {
77
+ xhr.type = 'abort';
78
+ return reject(xhr);
79
+ };
69
80
  let requestUrl = url + (url.indexOf('?') > -1 ? '&' : '?');
70
81
  for (const key in query) {
71
82
  requestUrl += `${key}=${query[key]}&`;
@@ -24,7 +24,7 @@ const XHR = {
24
24
  .join('/');
25
25
  },
26
26
  async upload(formio, type, xhrCallback, file, fileName, dir, progressCallback, groupPermissions, groupId, abortCallback, multipartOptions) {
27
- // Use makeRequest so portal plugins (e.g. x-remote-token) are applied.
27
+ // Use makeRequest so portal plugins (e.g. x-remote-token) are applied. GOTCHA(G-FJS05)
28
28
  let serverResponse;
29
29
  try {
30
30
  serverResponse = await 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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@formio/js",
3
- "version": "5.4.2",
3
+ "version": "5.4.3",
4
4
  "description": "JavaScript powered Forms with JSON Form Builder",
5
5
  "main": "lib/cjs/index.js",
6
6
  "exports": {
@@ -89,7 +89,7 @@
89
89
  "tippy.js": "^6.3.7",
90
90
  "uuid": "^9.0.0",
91
91
  "vanilla-picker": "^2.12.3",
92
- "@formio/bootstrap": "^4.0.2",
92
+ "@formio/bootstrap": "^4.0.3",
93
93
  "@formio/core": "^2.7.1"
94
94
  },
95
95
  "devDependencies": {