@formio/js 5.1.0-dev.6059.845a6e3 → 5.1.0-dev.6060.19e3bfc

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 (196) hide show
  1. package/Changelog.md +131 -13
  2. package/README.md +28 -1
  3. package/dist/formio.builder.css +19 -17
  4. package/dist/formio.builder.min.css +1 -1
  5. package/dist/formio.embed.js +1 -1
  6. package/dist/formio.embed.min.js +1 -1
  7. package/dist/formio.embed.min.js.LICENSE.txt +1 -1
  8. package/dist/formio.form.css +19 -17
  9. package/dist/formio.form.js +102 -176
  10. package/dist/formio.form.min.css +1 -1
  11. package/dist/formio.form.min.js +1 -1
  12. package/dist/formio.form.min.js.LICENSE.txt +3 -3
  13. package/dist/formio.full.css +19 -17
  14. package/dist/formio.full.js +123 -101
  15. package/dist/formio.full.min.css +2 -2
  16. package/dist/formio.full.min.js +1 -1
  17. package/dist/formio.full.min.js.LICENSE.txt +3 -3
  18. package/dist/formio.js +10 -10
  19. package/dist/formio.min.js +1 -1
  20. package/dist/formio.min.js.LICENSE.txt +1 -1
  21. package/dist/formio.utils.js +3 -3
  22. package/dist/formio.utils.min.js +1 -1
  23. package/dist/formio.utils.min.js.LICENSE.txt +1 -1
  24. package/lib/cjs/CDN.d.ts +1 -1
  25. package/lib/cjs/CDN.js +2 -2
  26. package/lib/cjs/Embed.js +1 -1
  27. package/lib/cjs/Form.d.ts +4 -6
  28. package/lib/cjs/Form.js +16 -8
  29. package/lib/cjs/Formio.js +1 -1
  30. package/lib/cjs/PDFBuilder.js +4 -4
  31. package/lib/cjs/Webform.d.ts +16 -13
  32. package/lib/cjs/Webform.js +162 -148
  33. package/lib/cjs/WebformBuilder.js +17 -28
  34. package/lib/cjs/Wizard.js +1 -1
  35. package/lib/cjs/WizardBuilder.js +15 -2
  36. package/lib/cjs/components/Components.d.ts +3 -0
  37. package/lib/cjs/components/_classes/component/Component.d.ts +1 -0
  38. package/lib/cjs/components/_classes/component/Component.js +38 -11
  39. package/lib/cjs/components/_classes/component/editForm/Component.edit.conditional.js +1 -1
  40. package/lib/cjs/components/_classes/component/editForm/Component.edit.data.d.ts +37 -0
  41. package/lib/cjs/components/_classes/component/editForm/Component.edit.data.js +32 -2
  42. package/lib/cjs/components/_classes/component/editForm/utils.d.ts +1 -0
  43. package/lib/cjs/components/_classes/component/editForm/utils.js +3 -0
  44. package/lib/cjs/components/_classes/input/Input.js +23 -1
  45. package/lib/cjs/components/_classes/list/ListComponent.js +4 -4
  46. package/lib/cjs/components/_classes/multivalue/Multivalue.d.ts +1 -1
  47. package/lib/cjs/components/_classes/multivalue/Multivalue.js +10 -3
  48. package/lib/cjs/components/_classes/nested/NestedComponent.form.js +13 -0
  49. package/lib/cjs/components/_classes/nestedarray/NestedArrayComponent.d.ts +2 -0
  50. package/lib/cjs/components/_classes/nestedarray/NestedArrayComponent.js +52 -31
  51. package/lib/cjs/components/address/Address.js +14 -1
  52. package/lib/cjs/components/button/Button.js +6 -6
  53. package/lib/cjs/components/checkbox/Checkbox.d.ts +1 -1
  54. package/lib/cjs/components/checkbox/Checkbox.js +2 -2
  55. package/lib/cjs/components/content/editForm/Content.edit.display.js +8 -0
  56. package/lib/cjs/components/currency/editForm/Currency.edit.display.js +12 -0
  57. package/lib/cjs/components/datagrid/DataGrid.d.ts +2 -0
  58. package/lib/cjs/components/datagrid/DataGrid.js +41 -26
  59. package/lib/cjs/components/day/Day.js +9 -7
  60. package/lib/cjs/components/day/editForm/Day.edit.display.js +8 -0
  61. package/lib/cjs/components/editgrid/EditGrid.d.ts +1 -1
  62. package/lib/cjs/components/editgrid/EditGrid.js +26 -8
  63. package/lib/cjs/components/email/editForm/Email.edit.display.js +12 -0
  64. package/lib/cjs/components/fieldset/editForm/Fieldset.edit.display.js +8 -0
  65. package/lib/cjs/components/file/File.d.ts +1 -1
  66. package/lib/cjs/components/file/File.js +30 -19
  67. package/lib/cjs/components/form/Form.d.ts +1 -1
  68. package/lib/cjs/components/form/Form.js +9 -5
  69. package/lib/cjs/components/form/editForm/Form.edit.form.js +3 -3
  70. package/lib/cjs/components/hidden/Hidden.d.ts +0 -1
  71. package/lib/cjs/components/hidden/Hidden.js +1 -1
  72. package/lib/cjs/components/hidden/editForm/Hidden.edit.display.js +8 -0
  73. package/lib/cjs/components/html/editForm/HTML.edit.display.js +8 -0
  74. package/lib/cjs/components/number/Number.js +12 -5
  75. package/lib/cjs/components/number/editForm/Number.edit.display.js +12 -0
  76. package/lib/cjs/components/password/editForm/Password.edit.display.js +13 -1
  77. package/lib/cjs/components/phonenumber/PhoneNumber.form.js +9 -1
  78. package/lib/cjs/components/radio/Radio.js +10 -0
  79. package/lib/cjs/components/recaptcha/ReCaptcha.js +2 -2
  80. package/lib/cjs/components/select/Select.d.ts +0 -1
  81. package/lib/cjs/components/select/Select.js +12 -33
  82. package/lib/cjs/components/select/editForm/Select.edit.data.d.ts +1 -1
  83. package/lib/cjs/components/select/editForm/Select.edit.data.js +3 -2
  84. package/lib/cjs/components/selectboxes/SelectBoxes.js +2 -2
  85. package/lib/cjs/components/signature/Signature.d.ts +1 -1
  86. package/lib/cjs/components/signature/Signature.js +5 -3
  87. package/lib/cjs/components/signature/editForm/Signature.edit.display.d.ts +0 -6
  88. package/lib/cjs/components/signature/editForm/Signature.edit.display.js +0 -1
  89. package/lib/cjs/components/survey/Survey.js +2 -2
  90. package/lib/cjs/components/tabs/editForm/Tabs.edit.display.js +8 -0
  91. package/lib/cjs/components/tags/Tags.d.ts +1 -1
  92. package/lib/cjs/components/tags/Tags.js +2 -2
  93. package/lib/cjs/components/textarea/TextArea.js +6 -6
  94. package/lib/cjs/components/textarea/editForm/TextArea.edit.display.js +12 -0
  95. package/lib/cjs/components/url/editForm/Url.edit.display.js +12 -0
  96. package/lib/cjs/components/well/editForm/Well.edit.display.js +8 -0
  97. package/lib/cjs/formio.form.js +5 -0
  98. package/lib/cjs/providers/storage/googleDrive.js +3 -2
  99. package/lib/cjs/providers/storage/s3.js +3 -3
  100. package/lib/cjs/providers/storage/xhr.d.ts +1 -0
  101. package/lib/cjs/providers/storage/xhr.js +6 -1
  102. package/lib/cjs/translations/en.d.ts +234 -81
  103. package/lib/cjs/translations/en.js +8 -81
  104. package/lib/cjs/utils/ChoicesWrapper.d.ts +4 -25
  105. package/lib/cjs/utils/ChoicesWrapper.js +47 -124
  106. package/lib/cjs/utils/formUtils.d.ts +2 -2
  107. package/lib/cjs/utils/i18n.d.ts +5 -2
  108. package/lib/cjs/utils/i18n.js +32 -5
  109. package/lib/cjs/widgets/CalendarWidget.js +27 -27
  110. package/lib/mjs/CDN.d.ts +1 -1
  111. package/lib/mjs/CDN.js +2 -2
  112. package/lib/mjs/Embed.js +1 -1
  113. package/lib/mjs/Form.d.ts +4 -6
  114. package/lib/mjs/Form.js +17 -9
  115. package/lib/mjs/Formio.js +1 -1
  116. package/lib/mjs/PDFBuilder.js +4 -4
  117. package/lib/mjs/Webform.d.ts +16 -13
  118. package/lib/mjs/Webform.js +171 -158
  119. package/lib/mjs/WebformBuilder.js +17 -28
  120. package/lib/mjs/Wizard.js +1 -1
  121. package/lib/mjs/WizardBuilder.js +15 -2
  122. package/lib/mjs/components/Components.d.ts +3 -0
  123. package/lib/mjs/components/_classes/component/Component.d.ts +1 -0
  124. package/lib/mjs/components/_classes/component/Component.js +27 -11
  125. package/lib/mjs/components/_classes/component/editForm/Component.edit.conditional.js +1 -1
  126. package/lib/mjs/components/_classes/component/editForm/Component.edit.data.d.ts +37 -0
  127. package/lib/mjs/components/_classes/component/editForm/Component.edit.data.js +32 -2
  128. package/lib/mjs/components/_classes/component/editForm/utils.d.ts +1 -0
  129. package/lib/mjs/components/_classes/component/editForm/utils.js +3 -0
  130. package/lib/mjs/components/_classes/input/Input.js +22 -1
  131. package/lib/mjs/components/_classes/list/ListComponent.js +4 -4
  132. package/lib/mjs/components/_classes/multivalue/Multivalue.d.ts +1 -1
  133. package/lib/mjs/components/_classes/multivalue/Multivalue.js +10 -3
  134. package/lib/mjs/components/_classes/nested/NestedComponent.form.js +13 -0
  135. package/lib/mjs/components/_classes/nestedarray/NestedArrayComponent.d.ts +2 -0
  136. package/lib/mjs/components/_classes/nestedarray/NestedArrayComponent.js +53 -31
  137. package/lib/mjs/components/address/Address.js +14 -1
  138. package/lib/mjs/components/button/Button.js +6 -6
  139. package/lib/mjs/components/checkbox/Checkbox.d.ts +1 -1
  140. package/lib/mjs/components/checkbox/Checkbox.js +2 -2
  141. package/lib/mjs/components/content/editForm/Content.edit.display.js +8 -0
  142. package/lib/mjs/components/currency/editForm/Currency.edit.display.js +12 -0
  143. package/lib/mjs/components/datagrid/DataGrid.d.ts +2 -0
  144. package/lib/mjs/components/datagrid/DataGrid.js +41 -26
  145. package/lib/mjs/components/day/Day.js +9 -7
  146. package/lib/mjs/components/day/editForm/Day.edit.display.js +8 -0
  147. package/lib/mjs/components/editgrid/EditGrid.d.ts +1 -1
  148. package/lib/mjs/components/editgrid/EditGrid.js +25 -7
  149. package/lib/mjs/components/email/editForm/Email.edit.display.js +12 -0
  150. package/lib/mjs/components/fieldset/editForm/Fieldset.edit.display.js +8 -0
  151. package/lib/mjs/components/file/File.d.ts +1 -1
  152. package/lib/mjs/components/file/File.js +30 -19
  153. package/lib/mjs/components/form/Form.d.ts +1 -1
  154. package/lib/mjs/components/form/Form.js +8 -5
  155. package/lib/mjs/components/form/editForm/Form.edit.form.js +3 -3
  156. package/lib/mjs/components/hidden/Hidden.d.ts +0 -1
  157. package/lib/mjs/components/hidden/Hidden.js +1 -1
  158. package/lib/mjs/components/hidden/editForm/Hidden.edit.display.js +8 -0
  159. package/lib/mjs/components/html/editForm/HTML.edit.display.js +8 -0
  160. package/lib/mjs/components/number/Number.js +12 -5
  161. package/lib/mjs/components/number/editForm/Number.edit.display.js +12 -0
  162. package/lib/mjs/components/password/editForm/Password.edit.display.js +13 -1
  163. package/lib/mjs/components/phonenumber/PhoneNumber.form.js +9 -1
  164. package/lib/mjs/components/radio/Radio.js +10 -0
  165. package/lib/mjs/components/recaptcha/ReCaptcha.js +2 -2
  166. package/lib/mjs/components/select/Select.d.ts +0 -1
  167. package/lib/mjs/components/select/Select.js +14 -34
  168. package/lib/mjs/components/select/editForm/Select.edit.data.d.ts +1 -1
  169. package/lib/mjs/components/select/editForm/Select.edit.data.js +3 -2
  170. package/lib/mjs/components/selectboxes/SelectBoxes.js +2 -2
  171. package/lib/mjs/components/signature/Signature.d.ts +1 -1
  172. package/lib/mjs/components/signature/Signature.js +5 -3
  173. package/lib/mjs/components/signature/editForm/Signature.edit.display.d.ts +0 -6
  174. package/lib/mjs/components/signature/editForm/Signature.edit.display.js +0 -1
  175. package/lib/mjs/components/survey/Survey.js +2 -2
  176. package/lib/mjs/components/tabs/editForm/Tabs.edit.display.js +8 -0
  177. package/lib/mjs/components/tags/Tags.d.ts +1 -1
  178. package/lib/mjs/components/tags/Tags.js +2 -2
  179. package/lib/mjs/components/textarea/TextArea.js +6 -6
  180. package/lib/mjs/components/textarea/editForm/TextArea.edit.display.js +12 -0
  181. package/lib/mjs/components/url/editForm/Url.edit.display.js +12 -0
  182. package/lib/mjs/components/well/editForm/Well.edit.display.js +8 -0
  183. package/lib/mjs/formio.form.js +5 -0
  184. package/lib/mjs/providers/storage/googleDrive.js +3 -2
  185. package/lib/mjs/providers/storage/s3.js +3 -3
  186. package/lib/mjs/providers/storage/xhr.d.ts +1 -0
  187. package/lib/mjs/providers/storage/xhr.js +6 -1
  188. package/lib/mjs/translations/en.d.ts +234 -81
  189. package/lib/mjs/translations/en.js +87 -1
  190. package/lib/mjs/utils/ChoicesWrapper.d.ts +4 -25
  191. package/lib/mjs/utils/ChoicesWrapper.js +26 -119
  192. package/lib/mjs/utils/formUtils.d.ts +2 -2
  193. package/lib/mjs/utils/i18n.d.ts +5 -2
  194. package/lib/mjs/utils/i18n.js +32 -5
  195. package/lib/mjs/widgets/CalendarWidget.js +27 -27
  196. package/package.json +27 -11
@@ -2,7 +2,7 @@
2
2
  import _ from 'lodash';
3
3
  import { Utils } from '@formio/core/utils';
4
4
  const { getComponentPaths } = Utils;
5
- import { componentValueTypes } from '../../../utils/utils';
5
+ import { componentValueTypes, isLayoutComponent } from '../../../utils/utils';
6
6
  import Component from '../component/Component';
7
7
  import NestedDataComponent from '../nesteddata/NestedDataComponent';
8
8
  export default class NestedArrayComponent extends NestedDataComponent {
@@ -18,7 +18,7 @@ export default class NestedArrayComponent extends NestedDataComponent {
18
18
  return this.iteratableRows[component.rowIndex].data;
19
19
  }
20
20
  get iteratableRows() {
21
- throw new Error('Getter #iteratableRows() is not implemented');
21
+ throw new Error(this.t('iteratableRowsError'));
22
22
  }
23
23
  get rowIndex() {
24
24
  return this._rowIndex;
@@ -63,7 +63,7 @@ export default class NestedArrayComponent extends NestedDataComponent {
63
63
  return this.validateComponents([this.component], data, flags);
64
64
  }
65
65
  checkRow(...args) {
66
- console.log('Deprecation Warning: checkRow method has been replaced with processRow');
66
+ console.log(this.t('checkRowDeprecation'));
67
67
  return this.processRow.call(this, ...args);
68
68
  }
69
69
  processRow(method, data, opts, row, components, silentCheck) {
@@ -110,38 +110,60 @@ export default class NestedArrayComponent extends NestedDataComponent {
110
110
  }
111
111
  });
112
112
  }
113
+ _getEmailTableHeader(options) {
114
+ let row = '';
115
+ const getHeaderCell = (component) => {
116
+ if (!component.isInputComponent || !component.visible || component.skipInEmail) {
117
+ return '';
118
+ }
119
+ const label = component.label || component.key;
120
+ return `<th style="padding: 5px 10px;">${this.t(label, { _userInput: true })}</th>`;
121
+ };
122
+ const components = this.getComponents(0);
123
+ for (const component of components) {
124
+ if (component.isInputComponent) {
125
+ row += getHeaderCell(component);
126
+ }
127
+ else if (isLayoutComponent(component) && typeof component.everyComponent === 'function') {
128
+ component.everyComponent((comp) => {
129
+ row += getHeaderCell(comp);
130
+ }, options);
131
+ }
132
+ }
133
+ return `<thead><tr>${row}</tr></thead>`;
134
+ }
135
+ _getEmailTableBody(options) {
136
+ const getBodyCell = (component) => {
137
+ if (!component.isInputComponent || !component.visible || component.skipInEmail) {
138
+ return '';
139
+ }
140
+ return `<td style="padding: 5px 10px;">${component.getView(component.dataValue, options)}</td>`;
141
+ };
142
+ const rows = [];
143
+ for (const { components } of this.iteratableRows) {
144
+ let row = '';
145
+ for (const component of components) {
146
+ if (component.isInputComponent) {
147
+ row += getBodyCell(component);
148
+ }
149
+ else if (isLayoutComponent(component) && typeof component.everyComponent === 'function') {
150
+ component.everyComponent((comp) => {
151
+ row += getBodyCell(comp);
152
+ }, options);
153
+ }
154
+ }
155
+ rows.push(`<tr>${row}</tr>`);
156
+ }
157
+ return `<tbody>${rows.join('')}</tbody>`;
158
+ }
113
159
  getValueAsString(value, options) {
114
160
  if (options?.email) {
115
- let result = (`
161
+ return `
116
162
  <table border="1" style="width:100%">
117
- <thead>
118
- <tr>
119
- `);
120
- this.component.components?.forEach((component) => {
121
- const label = component.label || component.key;
122
- result += `<th style="padding: 5px 10px;">${label}</th>`;
123
- });
124
- result += (`
125
- </tr>
126
- </thead>
127
- <tbody>
128
- `);
129
- this.iteratableRows.forEach(({ components }) => {
130
- result += '<tr>';
131
- _.each(components, (component) => {
132
- result += '<td style="padding:5px 10px;">';
133
- if (component.isInputComponent && component.visible && !component.skipInEmail) {
134
- result += component.getView(component.dataValue, options);
135
- }
136
- result += '</td>';
137
- });
138
- result += '</tr>';
139
- });
140
- result += (`
141
- </tbody>
163
+ ${this._getEmailTableHeader(options)}
164
+ ${this._getEmailTableBody(options)}
142
165
  </table>
143
- `);
144
- return result;
166
+ `;
145
167
  }
146
168
  if (!value || !value.length) {
147
169
  return '';
@@ -112,6 +112,19 @@ export default class AddressComponent extends ContainerComponent {
112
112
  NestedComponent.prototype.addComponents.call(this, this.manualMode ? this.address : {});
113
113
  }
114
114
  Field.prototype.init.call(this);
115
+ // Added for backwards compatibility
116
+ if (this.component.providerOptions) {
117
+ const { params, url, queryProperty, responseProperty, displayValueProperty } = this.component.providerOptions;
118
+ const key = params?.key;
119
+ const autocompleteOptions = params?.autocompleteOptions;
120
+ delete this.component.providerOptions;
121
+ this.component.url = url;
122
+ this.component.queryProperty = queryProperty;
123
+ this.component.responseProperty = responseProperty;
124
+ this.component.displayValueProperty = displayValueProperty;
125
+ this.component.apiKey = key;
126
+ this.component.autocompleteOptions = autocompleteOptions;
127
+ }
115
128
  let provider = this.component.provider;
116
129
  const providerOptions = this.providerOptions;
117
130
  const map = this.component.map;
@@ -317,7 +330,7 @@ export default class AddressComponent extends ContainerComponent {
317
330
  return !this.isMultiple && (this.builderMode || this.manualModeEnabled);
318
331
  }
319
332
  get addAnother() {
320
- return this.t(this.component.addAnother || 'Add Another');
333
+ return this.t(this.component.addAnother || 'addAnother');
321
334
  }
322
335
  renderElement(value) {
323
336
  return this.renderTemplate(this.templateName, {
@@ -336,17 +336,17 @@ export default class ButtonComponent extends Field {
336
336
  break;
337
337
  case 'oauth':
338
338
  if (this.root === this) {
339
- console.warn('You must add the OAuth button to a form for it to function properly');
339
+ console.warn(this.t('noOAuthBtn'));
340
340
  return;
341
341
  }
342
342
  // Display Alert if OAuth config is missing
343
343
  if (!this.oauthConfig) {
344
- this.root.setAlert('danger', 'OAuth not configured. You must configure oauth for your project before it will work.');
344
+ this.root.setAlert('danger', this.t('noOAuthConfiguration'));
345
345
  break;
346
346
  }
347
347
  // Display Alert if oAuth has an error is missing
348
348
  if (this.oauthConfig.error) {
349
- this.root.setAlert('danger', `The Following Error Has Occured ${this.oauthConfig.error}`);
349
+ this.root.setAlert('danger', `${this.t('oAuthErrorsTitle')} ${this.t(this.oauthConfig.error)}`);
350
350
  break;
351
351
  }
352
352
  this.openOauth(this.oauthConfig);
@@ -355,7 +355,7 @@ export default class ButtonComponent extends Field {
355
355
  }
356
356
  openOauth(settings) {
357
357
  if (!this.root.formio) {
358
- console.warn('You must attach a Form API url to your form in order to use OAuth buttons.');
358
+ console.warn(this.t('noOAuthFormUrl'));
359
359
  return;
360
360
  }
361
361
  /*eslint-disable camelcase */
@@ -403,7 +403,7 @@ export default class ButtonComponent extends Field {
403
403
  }
404
404
  // TODO: check for error response here
405
405
  if (settings.state !== params.state) {
406
- this.root.setAlert('danger', 'OAuth state does not match. Please try logging in again.');
406
+ this.root.setAlert('danger', this.t('oAuthStateError'));
407
407
  return;
408
408
  }
409
409
  // Depending on where the settings came from, submit to either the submission endpoint (old) or oauth endpoint (new).
@@ -436,7 +436,7 @@ export default class ButtonComponent extends Field {
436
436
  }
437
437
  catch (error) {
438
438
  if (error.name !== 'SecurityError' && (error.name !== 'Error' || error.message !== 'Permission denied')) {
439
- this.root.setAlert('danger', error.message || error);
439
+ this.root.setAlert('danger', this.t(`${error.message || error}`));
440
440
  }
441
441
  }
442
442
  if (!popup || popup.closed || popup.closed === undefined) {
@@ -43,7 +43,7 @@ export default class CheckBoxComponent extends Field {
43
43
  attach(element: any): Promise<void>;
44
44
  input: any;
45
45
  detach(element: any): void;
46
- get emptyValue(): false | null;
46
+ get emptyValue(): false | "";
47
47
  getValueAt(index: any): any;
48
48
  get checked(): boolean;
49
49
  setCheckedState(value: any): any;
@@ -116,7 +116,7 @@ export default class CheckBoxComponent extends Field {
116
116
  super.detach();
117
117
  }
118
118
  get emptyValue() {
119
- return this.component.inputType === 'radio' ? null : false;
119
+ return this.component.inputType === 'radio' ? '' : false;
120
120
  }
121
121
  isEmpty(value = this.dataValue) {
122
122
  return super.isEmpty(value) || value === false;
@@ -187,7 +187,7 @@ export default class CheckBoxComponent extends Field {
187
187
  if (_.isUndefined(value) && this.inDataTable) {
188
188
  return '';
189
189
  }
190
- return this.t(hasValue ? 'Yes' : 'No');
190
+ return this.t(hasValue ? 'yes' : 'no');
191
191
  }
192
192
  updateValue(value, flags) {
193
193
  // If this is a radio and is alredy checked, uncheck it.
@@ -3,6 +3,14 @@ export default [
3
3
  key: 'labelPosition',
4
4
  ignore: true
5
5
  },
6
+ {
7
+ key: 'labelWidth',
8
+ ignore: true
9
+ },
10
+ {
11
+ key: 'labelMargin',
12
+ ignore: true
13
+ },
6
14
  {
7
15
  key: 'placeholder',
8
16
  ignore: true
@@ -7,6 +7,18 @@ export default [
7
7
  key: 'allowMultipleMasks',
8
8
  ignore: true
9
9
  },
10
+ {
11
+ key: 'inputMasks',
12
+ ignore: true
13
+ },
14
+ {
15
+ key: 'widget.type',
16
+ ignore: true
17
+ },
18
+ {
19
+ key: 'widget',
20
+ ignore: true
21
+ },
10
22
  {
11
23
  key: 'showWordCount',
12
24
  ignore: true
@@ -12,6 +12,7 @@ export default class DataGridComponent extends NestedArrayComponent {
12
12
  tabIndex: number;
13
13
  rows: any[] | undefined;
14
14
  columns: any[] | undefined;
15
+ dragulaReady: Promise<any> | undefined;
15
16
  visibleColumns: {} | undefined;
16
17
  set dataValue(value: any[]);
17
18
  get dataValue(): any[];
@@ -70,6 +71,7 @@ export default class DataGridComponent extends NestedArrayComponent {
70
71
  */
71
72
  reorderValues(valuesArr: any, oldPosition: number, newPosition: number, movedBelow: boolean | any): void;
72
73
  onReorder(element: any, _target: any, _source: any, sibling: any): void;
74
+ onCloned(el: any, original: any): void;
73
75
  focusOnNewRowElement(row: any): void;
74
76
  addRow(): void;
75
77
  updateComponentsRowIndex(components: any, rowIndex: any): void;
@@ -1,7 +1,6 @@
1
1
  import _ from 'lodash';
2
2
  import NestedArrayComponent from '../_classes/nestedarray/NestedArrayComponent';
3
3
  import { fastCloneDeep, getFocusableElements } from '../../utils/utils';
4
- import dragula from 'dragula';
5
4
  export default class DataGridComponent extends NestedArrayComponent {
6
5
  static schema(...extend) {
7
6
  return NestedArrayComponent.schema({
@@ -38,6 +37,9 @@ export default class DataGridComponent extends NestedArrayComponent {
38
37
  if (this.initRows || !_.isEqual(this.dataValue, this.emptyValue)) {
39
38
  this.createRows(true);
40
39
  }
40
+ if (this.allowReorder) {
41
+ this.dragulaReady = this.getDragula();
42
+ }
41
43
  this.visibleColumns = {};
42
44
  this.prevHasAddButton = this.hasAddButton();
43
45
  this.checkColumns();
@@ -270,31 +272,25 @@ export default class DataGridComponent extends NestedArrayComponent {
270
272
  this.refs[`${this.datagridKey}-row`].forEach((row, index) => {
271
273
  row.dragInfo = { index };
272
274
  });
273
- this.dragula = dragula([this.refs[`${this.datagridKey}-tbody`]], {
274
- moves: (_draggedElement, _oldParent, clickedElement) => {
275
- const clickedElementKey = clickedElement.getAttribute('data-key');
276
- const oldParentKey = _oldParent.getAttribute('data-key');
277
- //Check if the clicked button belongs to that container, if false, it belongs to the nested container
278
- if (oldParentKey === clickedElementKey) {
279
- return clickedElement.classList.contains('formio-drag-button');
280
- }
275
+ this.dragulaReady.then((dragula) => {
276
+ // The drop event may call redraw twice which calls attach twice and because this block of code is asynchronous
277
+ // BOTH redraws may be called before this block of code runs (which causes this block of code to run twice sequentially).
278
+ // This causes two dragula() calls on the same container which breaks dragula. To fix this the return value must
279
+ // be saved in this.dragula and have its container contents reset if it exists
280
+ if (this.dragula && this.dragula.containers) {
281
+ this.dragula.containers = [];
281
282
  }
282
- }).on('drop', this.onReorder.bind(this));
283
- this.dragula.on('cloned', (el, original) => {
284
- if (el && el.children && original && original.children) {
285
- _.each(original.children, (child, index) => {
286
- const styles = getComputedStyle(child, null);
287
- if (styles.cssText !== '') {
288
- el.children[index].style.cssText = styles.cssText;
283
+ this.dragula = dragula([this.refs[`${this.datagridKey}-tbody`]], {
284
+ moves: (_draggedElement, _oldParent, clickedElement) => {
285
+ const clickedElementKey = clickedElement.getAttribute('data-key');
286
+ const oldParentKey = _oldParent.getAttribute('data-key');
287
+ //Check if the clicked button belongs to that container, if false, it belongs to the nested container
288
+ if (oldParentKey === clickedElementKey) {
289
+ return clickedElement.classList.contains('formio-drag-button');
289
290
  }
290
- else {
291
- const cssText = Object.values(styles).reduce((css, propertyName) => {
292
- return `${css}${propertyName}:${styles.getPropertyValue(propertyName)};`;
293
- }, '');
294
- el.children[index].style.cssText = cssText;
295
- }
296
- });
297
- }
291
+ }
292
+ }).on('drop', this.onReorder.bind(this))
293
+ .on('cloned', this.onCloned.bind(this));
298
294
  });
299
295
  }
300
296
  this.refs[`${this.datagridKey}-addRow`].forEach((addButton) => {
@@ -343,7 +339,7 @@ export default class DataGridComponent extends NestedArrayComponent {
343
339
  }
344
340
  onReorder(element, _target, _source, sibling) {
345
341
  if (!element.dragInfo || (sibling && !sibling.dragInfo)) {
346
- console.warn('There is no Drag Info available for either dragged or sibling element');
342
+ console.warn(this.t('noDragInfoError'));
347
343
  return;
348
344
  }
349
345
  const oldPosition = element.dragInfo.index;
@@ -354,10 +350,29 @@ export default class DataGridComponent extends NestedArrayComponent {
354
350
  this.reorderValues(dataValue, oldPosition, newPosition, movedBelow);
355
351
  //reorder select data
356
352
  this.reorderValues(_.get(this.root, `submission.metadata.selectData.${this.path}`, []), oldPosition, newPosition, movedBelow);
353
+ // When components are reordered we need to set the dataGrid and form pristine properties to false
354
+ this.root.pristine = false;
355
+ this.pristine = false;
357
356
  //need to re-build rows to re-calculate indexes and other indexed fields for component instance (like rows for ex.)
358
357
  this.setValue(dataValue, { isReordered: true });
359
358
  this.rebuild();
360
359
  }
360
+ onCloned(el, original) {
361
+ if (el && el.children && original && original.children) {
362
+ _.each(original.children, (child, index) => {
363
+ const styles = getComputedStyle(child, null);
364
+ if (styles.cssText !== '') {
365
+ el.children[index].style.cssText = styles.cssText;
366
+ }
367
+ else {
368
+ const cssText = Object.values(styles).reduce((css, propertyName) => {
369
+ return `${css}${propertyName}:${styles.getPropertyValue(propertyName)};`;
370
+ }, '');
371
+ el.children[index].style.cssText = cssText;
372
+ }
373
+ });
374
+ }
375
+ }
361
376
  focusOnNewRowElement(row) {
362
377
  Object.keys(row).find((key) => {
363
378
  const element = row[key].element;
@@ -415,7 +430,7 @@ export default class DataGridComponent extends NestedArrayComponent {
415
430
  }
416
431
  removeRow(index) {
417
432
  const makeEmpty = index === 0 && this.rows.length === 1;
418
- const flags = { isReordered: !makeEmpty, resetValue: makeEmpty };
433
+ const flags = { isReordered: !makeEmpty, resetValue: makeEmpty, modified: true };
419
434
  this.splice(index, flags);
420
435
  this.emit('dataGridDeleteRow', { index });
421
436
  const [row] = this.rows.splice(index, 1);
@@ -53,11 +53,13 @@ export default class DayComponent extends Field {
53
53
  // Empty value used before 9.3.x
54
54
  static oldEmptyValue = '00/00/0000';
55
55
  constructor(component, options, data) {
56
- if (component.maxDate && component.maxDate.indexOf('moment(') === -1) {
57
- component.maxDate = moment(component.maxDate, 'YYYY-MM-DD').toISOString();
58
- }
59
- if (component.minDate && component.minDate.indexOf('moment(') === -1) {
60
- component.minDate = moment(component.minDate, 'YYYY-MM-DD').toISOString();
56
+ if (!options.inFormBuilder && !options.building) {
57
+ if (component.maxDate && component.maxDate.indexOf('moment(') === -1) {
58
+ component.maxDate = moment(component.maxDate, 'YYYY-MM-DD').toISOString();
59
+ }
60
+ if (component.minDate && component.minDate.indexOf('moment(') === -1) {
61
+ component.minDate = moment(component.minDate, 'YYYY-MM-DD').toISOString();
62
+ }
61
63
  }
62
64
  super(component, options, data);
63
65
  }
@@ -174,7 +176,7 @@ export default class DayComponent extends Field {
174
176
  this._months = [
175
177
  {
176
178
  value: '',
177
- label: _.get(this.component, 'fields.month.placeholder') || (this.hideInputLabels ? this.t('Month') : '')
179
+ label: _.get(this.component, 'fields.month.placeholder') || (this.hideInputLabels ? this.t('month') : '')
178
180
  },
179
181
  { value: 1, label: 'January' },
180
182
  { value: 2, label: 'February' },
@@ -268,7 +270,7 @@ export default class DayComponent extends Field {
268
270
  this.saveCaretPosition(element, name);
269
271
  }
270
272
  catch (err) {
271
- console.warn('An error occurred while trying to save caret position', err);
273
+ console.warn(this.t('caretPositionSavingError'), err);
272
274
  }
273
275
  this.updateValue(null, {
274
276
  modified: true,
@@ -3,6 +3,14 @@ export default [
3
3
  key: 'labelPosition',
4
4
  ignore: true
5
5
  },
6
+ {
7
+ key: 'labelWidth',
8
+ ignore: true
9
+ },
10
+ {
11
+ key: 'labelMargin',
12
+ ignore: true
13
+ },
6
14
  {
7
15
  weight: 15,
8
16
  type: 'checkbox',
@@ -43,7 +43,7 @@ export default class EditGridComponent extends NestedArrayComponent {
43
43
  get defaultValue(): any[];
44
44
  hasRemoveButtons(): boolean;
45
45
  editRows: any;
46
- checkRowVariableTypeComponents(editRow: any, rowIndex: any): void;
46
+ checkRowVariableTypeComponents(editRow: any, rowIndex: any): boolean;
47
47
  setVariableTypeComponents(): void;
48
48
  variableTypeComponentsIndexes: any[] | undefined;
49
49
  isOpen(editRow: any): boolean;
@@ -115,10 +115,10 @@ export default class EditGridComponent extends NestedArrayComponent {
115
115
  }
116
116
  get defaultDialogTemplate() {
117
117
  return `
118
- <h3 ${this._referenceAttributeName}="dialogHeader">${this.t('Do you want to clear data?')}</h3>
118
+ <h3 ${this._referenceAttributeName}="dialogHeader">${this.t('wantToClearData')}</h3>
119
119
  <div style="display:flex; justify-content: flex-end;">
120
- <button ${this._referenceAttributeName}="dialogCancelButton" class="btn btn-secondary" aria-label="${this.t('Cancel')}">${this.t('Cancel')}</button>
121
- <button ${this._referenceAttributeName}="dialogYesButton" class="btn btn-danger" aria-label="${this.t('Yes, delete it')}">${this.t('Yes, delete it')}</button>
120
+ <button ${this._referenceAttributeName}="dialogCancelButton" class="btn btn-secondary" aria-label="${this.t('cancel')}">${this.t('cancel')}</button>
121
+ <button ${this._referenceAttributeName}="dialogYesButton" class="btn btn-danger" aria-label="${this.t('yesDelete')}">${this.t('yesDelete')}</button>
122
122
  </div>
123
123
  `;
124
124
  }
@@ -289,12 +289,15 @@ export default class EditGridComponent extends NestedArrayComponent {
289
289
  }
290
290
  checkRowVariableTypeComponents(editRow, rowIndex) {
291
291
  const rowComponents = editRow.components;
292
+ let typeChanged = false;
292
293
  if (_.some(this.variableTypeComponentsIndexes, (compIndex) => {
293
294
  const variableTypeComp = rowComponents[compIndex];
294
295
  return variableTypeComp.type !== variableTypeComp.component.type;
295
296
  })) {
296
297
  editRow.components = this.createRowComponents(editRow.data, rowIndex, true);
298
+ typeChanged = true;
297
299
  }
300
+ return typeChanged;
298
301
  }
299
302
  setVariableTypeComponents() {
300
303
  //set components which type is changing within a row (e.g.,by mergeComponentSchema action)
@@ -661,6 +664,11 @@ export default class EditGridComponent extends NestedArrayComponent {
661
664
  }
662
665
  },
663
666
  }, this.component.saveRow || 'Save'));
667
+ this.emit('editGridOpenModal', {
668
+ component: this.component,
669
+ row: editRow,
670
+ instance: this,
671
+ });
664
672
  return this.attachComponents(modalContent, components);
665
673
  }
666
674
  showDialog(rowIndex) {
@@ -718,6 +726,11 @@ export default class EditGridComponent extends NestedArrayComponent {
718
726
  editRow.data = dataSnapshot;
719
727
  this.restoreRowContext(editRow);
720
728
  }
729
+ this.emit('editGridEditRow', {
730
+ component: this.component,
731
+ row: editRow,
732
+ instance: this,
733
+ });
721
734
  if (this.component.modal) {
722
735
  return this.addRowModal(rowIndex);
723
736
  }
@@ -926,8 +939,10 @@ export default class EditGridComponent extends NestedArrayComponent {
926
939
  this.validateRow(editRow, false, false);
927
940
  }
928
941
  if (this.variableTypeComponentsIndexes.length) {
929
- this.checkRowVariableTypeComponents(editRow, rowIndex);
930
- this.redraw();
942
+ const typeChanged = this.checkRowVariableTypeComponents(editRow, rowIndex);
943
+ if (typeChanged) {
944
+ this.redraw();
945
+ }
931
946
  }
932
947
  };
933
948
  const comp = this.createComponent(_.assign({}, column, { row: options.row }), options, row, null, recreatePartially && currentRowComponents ? currentRowComponents[colIndex] : null);
@@ -1008,13 +1023,16 @@ export default class EditGridComponent extends NestedArrayComponent {
1008
1023
  if (valid === null) {
1009
1024
  editRow.errors.push({
1010
1025
  type: 'error',
1011
- message: `Invalid row validation for ${this.key}`
1026
+ message: this.t('componentInvalidRowValidation', { componentKey: this.key })
1012
1027
  });
1013
1028
  }
1014
1029
  }
1015
- if (!this.component.rowDrafts || this.root?.submitted) {
1030
+ if (editRow.alerts && (!this.component.rowDrafts || this.root?.submitted)) {
1016
1031
  this.showRowErrorAlerts(editRow, editRow.errors);
1017
1032
  }
1033
+ else if (editRow.errors?.length) {
1034
+ this.setCustomValidity(editRow.errors, dirty);
1035
+ }
1018
1036
  return editRow.errors;
1019
1037
  }
1020
1038
  showRowErrorAlerts(editRow, errors) {
@@ -7,6 +7,18 @@ export default [
7
7
  key: 'allowMultipleMasks',
8
8
  ignore: true,
9
9
  },
10
+ {
11
+ key: 'inputMasks',
12
+ ignore: true
13
+ },
14
+ {
15
+ key: 'widget.type',
16
+ ignore: true
17
+ },
18
+ {
19
+ key: 'widget',
20
+ ignore: true
21
+ },
10
22
  {
11
23
  key: 'showWordCount',
12
24
  ignore: true
@@ -3,6 +3,14 @@ export default [
3
3
  key: 'labelPosition',
4
4
  ignore: true
5
5
  },
6
+ {
7
+ key: 'labelWidth',
8
+ ignore: true
9
+ },
10
+ {
11
+ key: 'labelMargin',
12
+ ignore: true
13
+ },
6
14
  {
7
15
  key: 'placeholder',
8
16
  ignore: true
@@ -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;