@formio/js 5.1.0-dev.5936.fa0f253 → 5.1.0-dev.5939.f5aa9d6

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 (168) hide show
  1. package/README.md +7 -0
  2. package/dist/formio.builder.css +1 -0
  3. package/dist/formio.builder.min.css +1 -1
  4. package/dist/formio.form.css +1 -0
  5. package/dist/formio.form.js +114 -147
  6. package/dist/formio.form.min.css +1 -1
  7. package/dist/formio.form.min.js +1 -1
  8. package/dist/formio.full.css +1 -0
  9. package/dist/formio.full.js +121 -154
  10. package/dist/formio.full.min.css +1 -1
  11. package/dist/formio.full.min.js +1 -1
  12. package/dist/formio.js +65 -54
  13. package/dist/formio.min.js +1 -1
  14. package/dist/formio.utils.js +76 -76
  15. package/dist/formio.utils.min.js +1 -1
  16. package/lib/cjs/Element.d.ts +2 -1
  17. package/lib/cjs/Element.js +18 -39
  18. package/lib/cjs/EventEmitter.js +2 -25
  19. package/lib/cjs/Form.js +2 -25
  20. package/lib/cjs/PDF.js +1 -1
  21. package/lib/cjs/PDFBuilder.d.ts +1 -0
  22. package/lib/cjs/PDFBuilder.js +10 -11
  23. package/lib/cjs/Webform.d.ts +2 -2
  24. package/lib/cjs/Webform.js +9 -9
  25. package/lib/cjs/WebformBuilder.d.ts +1 -1
  26. package/lib/cjs/WebformBuilder.js +45 -21
  27. package/lib/cjs/Wizard.d.ts +1 -2
  28. package/lib/cjs/Wizard.js +18 -24
  29. package/lib/cjs/WizardBuilder.js +1 -1
  30. package/lib/cjs/components/_classes/component/Component.d.ts +0 -1
  31. package/lib/cjs/components/_classes/component/Component.js +41 -57
  32. package/lib/cjs/components/_classes/component/editForm/Component.edit.conditional.js +1 -1
  33. package/lib/cjs/components/_classes/component/editForm/Component.edit.logic.js +1 -1
  34. package/lib/cjs/components/_classes/componentModal/ComponentModal.js +1 -1
  35. package/lib/cjs/components/_classes/input/Input.d.ts +1 -1
  36. package/lib/cjs/components/_classes/input/Input.js +3 -3
  37. package/lib/cjs/components/_classes/list/ListComponent.js +1 -1
  38. package/lib/cjs/components/_classes/nested/NestedComponent.js +10 -8
  39. package/lib/cjs/components/_classes/nestedarray/NestedArrayComponent.js +1 -1
  40. package/lib/cjs/components/_classes/nesteddata/NestedDataComponent.js +1 -1
  41. package/lib/cjs/components/address/Address.js +2 -2
  42. package/lib/cjs/components/alert/Alert.js +1 -1
  43. package/lib/cjs/components/button/Button.js +1 -1
  44. package/lib/cjs/components/checkbox/Checkbox.js +1 -1
  45. package/lib/cjs/components/container/Container.js +1 -1
  46. package/lib/cjs/components/currency/Currency.js +1 -1
  47. package/lib/cjs/components/datagrid/DataGrid.js +1 -1
  48. package/lib/cjs/components/datetime/DateTime.d.ts +1 -1
  49. package/lib/cjs/components/datetime/DateTime.js +15 -13
  50. package/lib/cjs/components/day/Day.js +2 -2
  51. package/lib/cjs/components/editgrid/EditGrid.d.ts +0 -1
  52. package/lib/cjs/components/editgrid/EditGrid.js +1 -9
  53. package/lib/cjs/components/editgrid/editForm/EditGrid.edit.display.js +1 -1
  54. package/lib/cjs/components/file/File.js +1 -1
  55. package/lib/cjs/components/form/Form.js +14 -2
  56. package/lib/cjs/components/form/editForm/Form.edit.form.js +4 -3
  57. package/lib/cjs/components/number/Number.js +1 -1
  58. package/lib/cjs/components/panel/Panel.js +1 -1
  59. package/lib/cjs/components/radio/Radio.d.ts +9 -4
  60. package/lib/cjs/components/radio/Radio.js +40 -76
  61. package/lib/cjs/components/recaptcha/editForm/ReCaptcha.edit.display.js +1 -1
  62. package/lib/cjs/components/select/Select.d.ts +1 -0
  63. package/lib/cjs/components/select/Select.js +20 -4
  64. package/lib/cjs/components/select/editForm/Select.edit.data.js +1 -1
  65. package/lib/cjs/components/selectboxes/SelectBoxes.d.ts +6 -0
  66. package/lib/cjs/components/selectboxes/SelectBoxes.js +1 -1
  67. package/lib/cjs/components/signature/Signature.js +1 -1
  68. package/lib/cjs/components/survey/Survey.js +1 -1
  69. package/lib/cjs/components/tags/Tags.js +1 -1
  70. package/lib/cjs/components/textarea/TextArea.js +3 -3
  71. package/lib/cjs/components/textfield/TextField.js +13 -31
  72. package/lib/cjs/components/time/Time.js +1 -1
  73. package/lib/cjs/formio.form.js +5 -5
  74. package/lib/cjs/providers/storage/uploadAdapter.js +1 -1
  75. package/lib/cjs/translations/en.d.ts +1 -232
  76. package/lib/cjs/translations/en.js +4 -2
  77. package/lib/cjs/utils/Evaluator.d.ts +20 -6
  78. package/lib/cjs/utils/Evaluator.js +38 -15
  79. package/lib/cjs/utils/builder.js +5 -5
  80. package/lib/cjs/utils/conditionOperators/IsEqualTo.js +3 -3
  81. package/lib/cjs/utils/formUtils.d.ts +2 -2
  82. package/lib/cjs/utils/index.d.ts +169 -2
  83. package/lib/cjs/utils/index.js +22 -2
  84. package/lib/cjs/utils/utils.d.ts +22 -37
  85. package/lib/cjs/utils/utils.js +64 -135
  86. package/lib/cjs/widgets/CalendarWidget.d.ts +1 -8
  87. package/lib/cjs/widgets/CalendarWidget.js +17 -43
  88. package/lib/mjs/Element.d.ts +2 -1
  89. package/lib/mjs/Element.js +11 -9
  90. package/lib/mjs/EventEmitter.js +2 -2
  91. package/lib/mjs/Form.js +1 -1
  92. package/lib/mjs/PDF.js +1 -1
  93. package/lib/mjs/PDFBuilder.d.ts +1 -0
  94. package/lib/mjs/PDFBuilder.js +9 -10
  95. package/lib/mjs/Webform.d.ts +2 -2
  96. package/lib/mjs/Webform.js +7 -7
  97. package/lib/mjs/WebformBuilder.d.ts +1 -1
  98. package/lib/mjs/WebformBuilder.js +36 -13
  99. package/lib/mjs/Wizard.d.ts +1 -2
  100. package/lib/mjs/Wizard.js +17 -23
  101. package/lib/mjs/WizardBuilder.js +1 -1
  102. package/lib/mjs/components/_classes/component/Component.d.ts +0 -1
  103. package/lib/mjs/components/_classes/component/Component.js +14 -7
  104. package/lib/mjs/components/_classes/component/editForm/Component.edit.conditional.js +1 -1
  105. package/lib/mjs/components/_classes/component/editForm/Component.edit.logic.js +1 -1
  106. package/lib/mjs/components/_classes/componentModal/ComponentModal.js +1 -1
  107. package/lib/mjs/components/_classes/input/Input.d.ts +1 -1
  108. package/lib/mjs/components/_classes/input/Input.js +3 -3
  109. package/lib/mjs/components/_classes/list/ListComponent.js +1 -1
  110. package/lib/mjs/components/_classes/nested/NestedComponent.js +10 -8
  111. package/lib/mjs/components/_classes/nestedarray/NestedArrayComponent.js +1 -1
  112. package/lib/mjs/components/_classes/nesteddata/NestedDataComponent.js +1 -1
  113. package/lib/mjs/components/address/Address.js +2 -2
  114. package/lib/mjs/components/alert/Alert.js +1 -1
  115. package/lib/mjs/components/button/Button.js +1 -1
  116. package/lib/mjs/components/checkbox/Checkbox.js +1 -1
  117. package/lib/mjs/components/container/Container.js +1 -1
  118. package/lib/mjs/components/currency/Currency.js +1 -1
  119. package/lib/mjs/components/datagrid/DataGrid.js +1 -1
  120. package/lib/mjs/components/datetime/DateTime.d.ts +1 -1
  121. package/lib/mjs/components/datetime/DateTime.js +15 -13
  122. package/lib/mjs/components/day/Day.js +2 -2
  123. package/lib/mjs/components/editgrid/EditGrid.d.ts +0 -1
  124. package/lib/mjs/components/editgrid/EditGrid.js +1 -9
  125. package/lib/mjs/components/editgrid/editForm/EditGrid.edit.display.js +1 -1
  126. package/lib/mjs/components/file/File.js +1 -1
  127. package/lib/mjs/components/form/Form.js +13 -2
  128. package/lib/mjs/components/form/editForm/Form.edit.form.js +3 -2
  129. package/lib/mjs/components/number/Number.js +1 -1
  130. package/lib/mjs/components/panel/Panel.js +1 -1
  131. package/lib/mjs/components/radio/Radio.d.ts +9 -4
  132. package/lib/mjs/components/radio/Radio.js +40 -75
  133. package/lib/mjs/components/recaptcha/editForm/ReCaptcha.edit.display.js +1 -1
  134. package/lib/mjs/components/select/Select.d.ts +1 -0
  135. package/lib/mjs/components/select/Select.js +20 -4
  136. package/lib/mjs/components/select/editForm/Select.edit.data.js +1 -1
  137. package/lib/mjs/components/selectboxes/SelectBoxes.d.ts +6 -0
  138. package/lib/mjs/components/selectboxes/SelectBoxes.js +1 -1
  139. package/lib/mjs/components/signature/Signature.js +1 -1
  140. package/lib/mjs/components/survey/Survey.js +1 -1
  141. package/lib/mjs/components/tags/Tags.js +1 -1
  142. package/lib/mjs/components/textarea/TextArea.js +3 -3
  143. package/lib/mjs/components/textfield/TextField.js +7 -2
  144. package/lib/mjs/components/time/Time.js +1 -1
  145. package/lib/mjs/formio.form.js +3 -3
  146. package/lib/mjs/providers/storage/uploadAdapter.js +1 -1
  147. package/lib/mjs/translations/en.d.ts +1 -232
  148. package/lib/mjs/translations/en.js +8 -47
  149. package/lib/mjs/utils/Evaluator.d.ts +20 -6
  150. package/lib/mjs/utils/Evaluator.js +31 -13
  151. package/lib/mjs/utils/builder.js +1 -1
  152. package/lib/mjs/utils/conditionOperators/IsEqualTo.js +1 -1
  153. package/lib/mjs/utils/formUtils.d.ts +2 -2
  154. package/lib/mjs/utils/index.d.ts +169 -2
  155. package/lib/mjs/utils/index.js +18 -1
  156. package/lib/mjs/utils/utils.d.ts +22 -37
  157. package/lib/mjs/utils/utils.js +57 -109
  158. package/lib/mjs/widgets/CalendarWidget.d.ts +1 -8
  159. package/lib/mjs/widgets/CalendarWidget.js +17 -43
  160. package/package.json +5 -3
  161. package/lib/cjs/i18n.d.ts +0 -13
  162. package/lib/cjs/i18n.js +0 -19
  163. package/lib/cjs/utils/i18n.d.ts +0 -19
  164. package/lib/cjs/utils/i18n.js +0 -120
  165. package/lib/mjs/i18n.d.ts +0 -13
  166. package/lib/mjs/i18n.js +0 -14
  167. package/lib/mjs/utils/i18n.d.ts +0 -19
  168. package/lib/mjs/utils/i18n.js +0 -112
@@ -1,7 +1,7 @@
1
1
  import _ from 'lodash';
2
- import moment from 'moment';
2
+ import dayjs from 'dayjs';
3
3
  import FormioUtils from '../../utils';
4
- import { componentValueTypes, fastCloneDeep, getComponentSavedTypes } from '../../utils/utils';
4
+ import { componentValueTypes, fastCloneDeep, getComponentSavedTypes } from '../../utils';
5
5
  import Input from '../_classes/input/Input';
6
6
  export default class DateTimeComponent extends Input {
7
7
  static schema(...extend) {
@@ -147,8 +147,8 @@ export default class DateTimeComponent extends Input {
147
147
  get emptyValue() {
148
148
  return '';
149
149
  }
150
- get momentFormat() {
151
- return FormioUtils.convertFormatToMoment(this.component.format);
150
+ get dayjsFormat() {
151
+ return FormioUtils.convertFormatToDayjs(this.component.format);
152
152
  }
153
153
  isEmpty(value = this.dataValue) {
154
154
  if (value && (value.toString() === 'Invalid Date')) {
@@ -157,12 +157,14 @@ export default class DateTimeComponent extends Input {
157
157
  return super.isEmpty(value);
158
158
  }
159
159
  formatValue(input) {
160
- const result = moment.utc(input).toISOString();
161
- return result === 'Invalid date' ? input : result;
160
+ if (dayjs(input).isValid()) {
161
+ return dayjs.utc(input).toISOString();
162
+ }
163
+ return input;
162
164
  }
163
165
  isEqual(valueA, valueB = this.dataValue) {
164
166
  return (this.isEmpty(valueA) && this.isEmpty(valueB))
165
- || moment.utc(valueA).format(this.momentFormat) === moment.utc(valueB).format(this.momentFormat);
167
+ || dayjs.utc(valueA).format(this.dayjsFormat) === dayjs.utc(valueB).format(this.dayjsFormat);
166
168
  }
167
169
  createWrapper() {
168
170
  return false;
@@ -178,18 +180,18 @@ export default class DateTimeComponent extends Input {
178
180
  return super.checkValidity(data, dirty, rowData);
179
181
  }
180
182
  getValueAsString(value, options) {
181
- let format = FormioUtils.convertFormatToMoment(this.component.format);
182
- format += format.match(/z$/) ? '' : ' z';
183
+ let format = FormioUtils.convertFormatToDayjs(this.component.format);
183
184
  const timezone = this.timezone;
184
185
  if (value && !this.attached && timezone) {
186
+ format += format.match(/z$/) ? '' : ' z';
185
187
  if (Array.isArray(value) && this.component.multiple) {
186
- return value.map(item => _.trim(FormioUtils.momentDate(item, format, timezone, options).format(format))).join(', ');
188
+ return value.map(item => _.trim(FormioUtils.dayjsDate(item, format, timezone, options).format(format))).join(', ');
187
189
  }
188
- return _.trim(FormioUtils.momentDate(value, format, timezone, options).format(format));
190
+ return _.trim(FormioUtils.dayjsDate(value, format, timezone, options).format(format));
189
191
  }
190
192
  if (Array.isArray(value) && this.component.multiple) {
191
- return value.map(item => _.trim(moment(item).format(format))).join(', ');
193
+ return value.map(item => _.trim(dayjs(item).format(format))).join(', ');
192
194
  }
193
- return (value ? _.trim(moment(value).format(format)) : value) || '';
195
+ return (value ? _.trim(dayjs(value).format(format)) : value) || '';
194
196
  }
195
197
  }
@@ -1,7 +1,7 @@
1
1
  import _ from 'lodash';
2
2
  import moment from 'moment';
3
3
  import Field from '../_classes/field/Field';
4
- import { boolValue, componentValueTypes, getComponentSavedTypes, getLocaleDateFormatInfo } from '../../utils/utils';
4
+ import { boolValue, componentValueTypes, getComponentSavedTypes, getLocaleDateFormatInfo } from '../../utils';
5
5
  import { getDayFormat } from '@formio/core';
6
6
  export default class DayComponent extends Field {
7
7
  static schema(...extend) {
@@ -53,7 +53,7 @@ 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 (!options.inFormBuilder && !options.building) {
56
+ if (options && !options.inFormBuilder && !options.building) {
57
57
  if (component.maxDate && component.maxDate.indexOf('moment(') === -1) {
58
58
  component.maxDate = moment(component.maxDate, 'YYYY-MM-DD').toISOString();
59
59
  }
@@ -101,7 +101,6 @@ export default class EditGridComponent extends NestedArrayComponent {
101
101
  changeState(changed: any, flags: any): void;
102
102
  openWhenEmpty(): void;
103
103
  restoreRowContext(editRow: any, flags?: {}): void;
104
- emptyRows(): void;
105
104
  hasChanged: (newValue: any, oldValue: any) => boolean;
106
105
  }
107
106
  import NestedArrayComponent from '../_classes/nestedarray/NestedArrayComponent';
@@ -4,7 +4,7 @@ import { editgrid as templates } from '@formio/bootstrap/components';
4
4
  import NestedArrayComponent from '../_classes/nestedarray/NestedArrayComponent';
5
5
  import Component from '../_classes/component/Component';
6
6
  import Alert from '../alert/Alert';
7
- import { fastCloneDeep, Evaluator, getArrayFromComponentPath, eachComponent } from '../../utils/utils';
7
+ import { fastCloneDeep, Evaluator, getArrayFromComponentPath, eachComponent } from '../../utils';
8
8
  const EditRowState = {
9
9
  New: 'new',
10
10
  Editing: 'editing',
@@ -1192,13 +1192,5 @@ export default class EditGridComponent extends NestedArrayComponent {
1192
1192
  this.setNestedValue(component, editRow.data, flags);
1193
1193
  });
1194
1194
  }
1195
- emptyRows() {
1196
- this.editRows.forEach((editRow, index) => this.destroyComponents(false, index));
1197
- this.editRows = [];
1198
- }
1199
- resetValue() {
1200
- super.resetValue();
1201
- this.emptyRows();
1202
- }
1203
1195
  }
1204
1196
  EditGridComponent.prototype.hasChanged = Component.prototype.hasChanged;
@@ -33,7 +33,7 @@ export default [
33
33
  weight: 1002,
34
34
  input: false,
35
35
  customConditional() {
36
- return !Evaluator.noeval;
36
+ return !Evaluator.noeval || !Evaluator.protectedEval;
37
37
  },
38
38
  },
39
39
  {
@@ -1,5 +1,5 @@
1
1
  import Field from '../_classes/field/Field';
2
- import { componentValueTypes, getComponentSavedTypes, uniqueName } from '../../utils/utils';
2
+ import { componentValueTypes, getComponentSavedTypes, uniqueName } from '../../utils';
3
3
  import download from 'downloadjs';
4
4
  import _ from 'lodash';
5
5
  import fileProcessor from '../../providers/processor/fileProcessor';
@@ -3,7 +3,7 @@ import _ from 'lodash';
3
3
  import Component from '../_classes/component/Component';
4
4
  import ComponentModal from '../_classes/componentModal/ComponentModal';
5
5
  import EventEmitter from 'eventemitter3';
6
- import { isMongoId, eachComponent, componentValueTypes } from '../../utils/utils';
6
+ import { isMongoId, eachComponent, componentValueTypes } from '../../utils';
7
7
  import { Formio } from '../../Formio';
8
8
  import Form from '../../Form';
9
9
  export default class FormComponent extends Component {
@@ -274,6 +274,9 @@ export default class FormComponent extends Component {
274
274
  if (this.isSubFormLazyLoad() && !this.hasLoadedForm && !this.subFormLoading) {
275
275
  this.createSubForm(true);
276
276
  }
277
+ if (!this.subFormReady) {
278
+ return Promise.resolve();
279
+ }
277
280
  return this.subFormReady.then(() => {
278
281
  this.empty(element);
279
282
  if (this.options.builder) {
@@ -408,7 +411,8 @@ export default class FormComponent extends Component {
408
411
  const componentsMap = this.componentsMap;
409
412
  const formComponentsMap = this.subForm.componentsMap;
410
413
  _.assign(componentsMap, formComponentsMap);
411
- this.component.components = this.subForm.components.map((comp) => comp.component);
414
+ this.component.components = this.subForm._form?.components;
415
+ this.component.display = this.subForm._form?.display;
412
416
  this.subForm.on('change', () => {
413
417
  if (this.subForm && !this.shouldConditionallyClear()) {
414
418
  this.dataValue = this.subForm.getValue();
@@ -688,6 +692,13 @@ export default class FormComponent extends Component {
688
692
  }
689
693
  return errors;
690
694
  }
695
+ conditionallyHidden() {
696
+ const conditionallyHidden = super.conditionallyHidden();
697
+ if (this.subForm) {
698
+ this.subForm._conditionallyHidden = conditionallyHidden;
699
+ }
700
+ return conditionallyHidden;
701
+ }
691
702
  updateSubFormVisibility() {
692
703
  if (this.subForm) {
693
704
  this.subForm.parentVisible = this.visible;
@@ -30,9 +30,10 @@ export default [
30
30
  tooltip: 'if it is checked, the subform is loaded after navigation to the page with this component within the wizard.',
31
31
  input: true,
32
32
  customConditional({ instance, data }) {
33
- const formInfo = instance.root?.getComponent('form')?.defaultDownloadedResources.find(res => res._id === data.form);
33
+ const formComp = instance.root?.getComponent('form');
34
+ const formInfo = formComp?.defaultDownloadedResources.find(res => res._id === data.form);
34
35
  const displayMode = 'wizard';
35
- return instance.options?.editForm?.display === displayMode && formInfo && formInfo.display !== displayMode;
36
+ return instance.options?.editForm?.display === displayMode && ((data.form && !formInfo) || (formInfo && formInfo.display !== displayMode));
36
37
  },
37
38
  },
38
39
  {
@@ -2,7 +2,7 @@ import { createNumberMask } from '@formio/text-mask-addons';
2
2
  import { conformToMask, maskInput } from '@formio/vanilla-text-mask';
3
3
  import _ from 'lodash';
4
4
  import Input from '../_classes/input/Input';
5
- import { getNumberSeparators, getNumberDecimalLimit, componentValueTypes, getComponentSavedTypes } from '../../utils/utils';
5
+ import { getNumberSeparators, getNumberDecimalLimit, componentValueTypes, getComponentSavedTypes } from '../../utils/';
6
6
  export default class NumberComponent extends Input {
7
7
  static schema(...extend) {
8
8
  return Input.schema({
@@ -1,5 +1,5 @@
1
1
  import NestedComponent from '../_classes/nested/NestedComponent';
2
- import { isChildOf } from '../../utils/utils';
2
+ import { isChildOf } from '../../utils';
3
3
  export default class PanelComponent extends NestedComponent {
4
4
  static schema(...extend) {
5
5
  return NestedComponent.schema({
@@ -16,6 +16,7 @@ export default class RadioComponent extends ListComponent {
16
16
  static savedValueTypes(schema: any): any[];
17
17
  constructor(component: any, options: any, data: any);
18
18
  previousValue: any;
19
+ uncheckValue(flags?: {}): void;
19
20
  get inputInfo(): any;
20
21
  get emptyValue(): string;
21
22
  get isRadio(): boolean;
@@ -27,8 +28,8 @@ export default class RadioComponent extends ListComponent {
27
28
  itemsLoadedResolve: ((value: any) => void) | undefined;
28
29
  optionsLoaded: boolean | undefined;
29
30
  loadedOptions: any[] | undefined;
30
- valuesMap: Map<any, any> | undefined;
31
31
  beforeSubmit(): Promise<any>;
32
+ convertValues(values: any): any;
32
33
  render(): string;
33
34
  attach(element: any): Promise<void>;
34
35
  detach(element: any): void;
@@ -36,14 +37,18 @@ export default class RadioComponent extends ListComponent {
36
37
  validateValueAvailability(setting: any, value: any): boolean;
37
38
  getValueAsString(value: any, options?: {}): any;
38
39
  setValueAt(index: any, value: any): void;
39
- prepareValue(item: any, options?: {}): any;
40
- getValueByInput(input: any): any;
41
40
  loadItems(url: any, search: any, headers: any, options: any, method: any, body: any): void;
42
41
  loadItemsFromMetadata(): void;
43
42
  setItems(items: any): void;
44
43
  setSelectedClasses(): void;
45
- setMetadata(value: any): void;
46
44
  updateValue(value: any, flags: any): boolean;
47
45
  currentValue: any;
46
+ /**
47
+ * Normalize values coming into updateValue. For example, depending on the configuration, string value `"true"` will be normalized to boolean `true`.
48
+ * @param {*} value - The value to normalize
49
+ * @returns {*} - Returns the normalized value
50
+ */
51
+ convertByDataType(value: any): any;
52
+ normalizeValue(value: any): any;
48
53
  }
49
54
  import ListComponent from '../_classes/list/ListComponent';
@@ -1,8 +1,7 @@
1
1
  import _ from 'lodash';
2
2
  import ListComponent from '../_classes/list/ListComponent';
3
3
  import { Formio } from '../../Formio';
4
- import { boolValue, componentValueTypes, getComponentSavedTypes } from '../../utils/utils';
5
- import { v4 as uuidv4 } from 'uuid';
4
+ import { boolValue, componentValueTypes, getComponentSavedTypes } from '../../utils';
6
5
  export default class RadioComponent extends ListComponent {
7
6
  static schema(...extend) {
8
7
  return ListComponent.schema({
@@ -81,13 +80,15 @@ export default class RadioComponent extends ListComponent {
81
80
  }
82
81
  return defaultValue;
83
82
  }
84
- resetValue() {
83
+ uncheckValue(flags = {}) {
85
84
  this.unset();
86
85
  this.setValue(this.emptyValue, {
87
86
  noUpdateEvent: true,
88
87
  noValidate: true,
89
88
  resetValue: true
90
89
  });
90
+ this.triggerChange(flags);
91
+ this.setSelectedClasses();
91
92
  }
92
93
  get inputInfo() {
93
94
  const info = super.elementInfo();
@@ -143,7 +144,6 @@ export default class RadioComponent extends ListComponent {
143
144
  });
144
145
  this.optionsLoaded = !this.component.dataSrc || this.component.dataSrc === 'values';
145
146
  this.loadedOptions = [];
146
- this.valuesMap = new Map();
147
147
  if (!this.visible) {
148
148
  this.itemsLoadedResolve();
149
149
  }
@@ -155,6 +155,12 @@ export default class RadioComponent extends ListComponent {
155
155
  this.dataReady.then(() => res(true));
156
156
  });
157
157
  }
158
+ convertValues(values) {
159
+ if (this.options.renderMode === 'html' && this.type === 'radio') {
160
+ return values.map(x => ({ ...x, value: this.convertByDataType(x.value) }));
161
+ }
162
+ return values;
163
+ }
158
164
  render() {
159
165
  if (!this.optionsLoaded) {
160
166
  return super.render(this.renderTemplate('loader'));
@@ -162,7 +168,7 @@ export default class RadioComponent extends ListComponent {
162
168
  return super.render(this.renderTemplate('radio', {
163
169
  input: this.inputInfo,
164
170
  inline: this.component.inline,
165
- values: this.component.dataSrc === 'values' ? this.component.values : this.loadedOptions,
171
+ values: this.component.dataSrc === 'values' ? this.convertValues(this.component.values) : this.loadedOptions,
166
172
  value: this.dataValue,
167
173
  row: this.row,
168
174
  }));
@@ -183,12 +189,9 @@ export default class RadioComponent extends ListComponent {
183
189
  if (!_.isString(this.dataValue)) {
184
190
  dataValue = _.toString(this.dataValue);
185
191
  }
186
- if (this.isSelectURL) {
187
- const valueKey = this.loadedOptions[index].value;
188
- const optionValue = this.valuesMap.has(valueKey)
189
- ? this.valuesMap.get(valueKey)
190
- : valueKey;
191
- input.checked = _.isEqual(this.normalizeValue(optionValue), this.dataValue);
192
+ if (this.isSelectURL && _.isObject(this.loadedOptions[index].value)) {
193
+ const optionValue = this.component.dataType === 'string' ? JSON.stringify(this.loadedOptions[index].value) : this.loadedOptions[index].value;
194
+ input.checked = _.isEqual(optionValue, this.dataValue);
192
195
  }
193
196
  else {
194
197
  input.checked = (dataValue === input.value && (input.value || this.component.dataSrc !== 'url'));
@@ -225,14 +228,9 @@ export default class RadioComponent extends ListComponent {
225
228
  let value = this.component.inputType === 'checkbox' ? '' : this.dataValue;
226
229
  this.refs.input.forEach((input, index) => {
227
230
  if (input.checked) {
228
- if (!this.isSelectURL) {
229
- value = input.value;
230
- return;
231
- }
232
- const optionValue = this.loadedOptions[index].value;
233
- value = this.valuesMap.has(optionValue)
234
- ? this.valuesMap.get(optionValue)
235
- : optionValue;
231
+ value = (this.isSelectURL && _.isObject(this.loadedOptions[index].value)) ?
232
+ this.loadedOptions[index].value :
233
+ input.value;
236
234
  }
237
235
  });
238
236
  return value;
@@ -276,8 +274,8 @@ export default class RadioComponent extends ListComponent {
276
274
  }
277
275
  setValueAt(index, value) {
278
276
  if (this.refs.input && this.refs.input[index] && value !== null && value !== undefined) {
279
- const inputValue = this.getValueByInput(this.refs.input[index]);
280
- this.refs.input[index].checked = _.isEqual(inputValue, value);
277
+ const inputValue = this.refs.input[index].value;
278
+ this.refs.input[index].checked = (inputValue === value.toString());
281
279
  }
282
280
  }
283
281
  get shouldLoad() {
@@ -287,23 +285,6 @@ export default class RadioComponent extends ListComponent {
287
285
  }
288
286
  return super.shouldLoad;
289
287
  }
290
- prepareValue(item, options = {}) {
291
- const value = this.component.valueProperty && !options.skipValueProperty
292
- ? _.get(item, this.component.valueProperty)
293
- : item;
294
- if (this.component.type === 'radio' && typeof value !== 'string') {
295
- const uuid = uuidv4();
296
- this.valuesMap.set(uuid, value);
297
- return uuid;
298
- }
299
- return value;
300
- }
301
- getValueByInput(input) {
302
- const inputValue = input.value;
303
- return this.valuesMap.has(inputValue)
304
- ? this.valuesMap.get(inputValue)
305
- : inputValue;
306
- }
307
288
  loadItems(url, search, headers, options, method, body) {
308
289
  if (this.optionsLoaded) {
309
290
  this.itemsLoadedResolve();
@@ -354,7 +335,7 @@ export default class RadioComponent extends ListComponent {
354
335
  label: this.itemTemplate(item)
355
336
  };
356
337
  if (_.isEqual(item, this.selectData || _.pick(this.dataValue, _.keys(item)))) {
357
- this.loadedOptions[i].value = this.prepareValue(this.dataValue, { skipValueProperty: true });
338
+ this.loadedOptions[i].value = this.dataValue;
358
339
  }
359
340
  });
360
341
  this.optionsLoaded = true;
@@ -364,15 +345,12 @@ export default class RadioComponent extends ListComponent {
364
345
  const listData = [];
365
346
  items?.forEach((item, i) => {
366
347
  const valueAtProperty = _.get(item, this.component.valueProperty);
367
- const value = this.prepareValue(item);
368
- const label = this.component.valueProperty
369
- ? this.itemTemplate(item, valueAtProperty, i)
370
- : this.itemTemplate(item, item, i);
371
- this.loadedOptions[i] = { label, value };
372
- listData.push(this.templateData[i]);
373
- if (this.valuesMap.has(value)) {
374
- this.templateData[value] = this.templateData[i];
375
- }
348
+ this.loadedOptions[i] = {
349
+ value: this.component.valueProperty ? valueAtProperty : item,
350
+ label: this.component.valueProperty ? this.itemTemplate(item, valueAtProperty) : this.itemTemplate(item, item, i)
351
+ };
352
+ listData.push(this.templateData[this.component.valueProperty ? valueAtProperty : i]);
353
+ const value = this.loadedOptions[i].value;
376
354
  if (!this.isRadio && (_.isObject(value) || _.isBoolean(value) || _.isUndefined(value))) {
377
355
  this.loadedOptions[i].invalid = true;
378
356
  }
@@ -395,11 +373,7 @@ export default class RadioComponent extends ListComponent {
395
373
  const value = this.dataValue;
396
374
  this.refs.wrapper.forEach((wrapper, index) => {
397
375
  const input = this.refs.input[index];
398
- const checked = (value === undefined || value === null)
399
- ? false
400
- : (input.type === 'checkbox')
401
- ? value[input.value] || input.checked
402
- : _.isEqual(this.normalizeValue(this.getValueByInput(input)), value);
376
+ const checked = (value === undefined || value === null) ? false : (input.type === 'checkbox') ? value[input.value] || input.checked : (input.value.toString() === value.toString());
403
377
  if (checked) {
404
378
  //add class to container when selected
405
379
  this.addClass(wrapper, this.optionSelectedClass);
@@ -413,25 +387,10 @@ export default class RadioComponent extends ListComponent {
413
387
  });
414
388
  }
415
389
  }
416
- setMetadata(value) {
417
- let key = value;
418
- if (typeof value !== 'string') {
419
- const checkedInput = Array.prototype.find.call(this.refs.input ?? [], (input => input.type === 'radio' && input.getAttribute('checked')));
420
- key = checkedInput?.value || key;
421
- }
422
- if (this.isSelectURL && this.templateData && this.templateData[key]) {
423
- const submission = this.root.submission;
424
- if (!submission.metadata.selectData) {
425
- submission.metadata.selectData = {};
426
- }
427
- _.set(submission.metadata.selectData, this.path, this.templateData[key]);
428
- }
429
- }
430
390
  updateValue(value, flags) {
431
391
  const changed = super.updateValue(value, flags);
432
392
  if (changed) {
433
393
  this.setSelectedClasses();
434
- this.setMetadata(this.dataValue);
435
394
  }
436
395
  if (!flags || !flags.modified || !this.isRadio) {
437
396
  if (changed) {
@@ -443,9 +402,7 @@ export default class RadioComponent extends ListComponent {
443
402
  this.currentValue = this.dataValue;
444
403
  const shouldResetValue = flags && flags.modified && !flags.noUpdateEvent && this.previousValue === this.currentValue;
445
404
  if (shouldResetValue) {
446
- this.resetValue();
447
- this.triggerChange(flags);
448
- this.setSelectedClasses();
405
+ this.uncheckValue(flags);
449
406
  }
450
407
  this.previousValue = this.dataValue;
451
408
  return changed;
@@ -455,7 +412,7 @@ export default class RadioComponent extends ListComponent {
455
412
  * @param {*} value - The value to normalize
456
413
  * @returns {*} - Returns the normalized value
457
414
  */
458
- normalizeValue(value) {
415
+ convertByDataType(value) {
459
416
  const dataType = this.component.dataType || 'auto';
460
417
  if (value === this.emptyValue) {
461
418
  return value;
@@ -487,9 +444,17 @@ export default class RadioComponent extends ListComponent {
487
444
  value = !(!value || value.toString() === 'false');
488
445
  break;
489
446
  }
490
- return super.normalizeValue(value);
447
+ return value;
491
448
  }
492
- isSingleInputValue() {
493
- return true;
449
+ normalizeValue(value) {
450
+ const valueConverted = this.convertByDataType(value);
451
+ if (this.isSelectURL && this.templateData && this.templateData[valueConverted]) {
452
+ const submission = this.root.submission;
453
+ if (!submission.metadata.selectData) {
454
+ submission.metadata.selectData = {};
455
+ }
456
+ _.set(submission.metadata.selectData, this.path, this.templateData[valueConverted]);
457
+ }
458
+ return super.normalizeValue(valueConverted);
494
459
  }
495
460
  }
@@ -1,4 +1,4 @@
1
- import { getContextButtons } from '../../../utils/utils';
1
+ import { getContextButtons } from '../../../utils';
2
2
  export default [
3
3
  {
4
4
  key: 'recaptchaInfo',
@@ -89,6 +89,7 @@ export default class SelectComponent extends ListComponent {
89
89
  disableInfiniteScroll(): void;
90
90
  set serverCount(value: any);
91
91
  get serverCount(): any;
92
+ shouldResetChoicesItems(items: any): boolean;
92
93
  setItems(items: any, fromSearch: any): void;
93
94
  selectItems: any;
94
95
  set downloadedResources(value: any);
@@ -2,7 +2,7 @@ import _ from 'lodash';
2
2
  import { Formio } from '../../Formio';
3
3
  import ListComponent from '../_classes/list/ListComponent';
4
4
  import Form from '../../Form';
5
- import { getRandomComponentId, boolValue, isPromise, componentValueTypes, getComponentSavedTypes, isSelectResourceWithObjectValue, removeHTML } from '../../utils/utils';
5
+ import { getRandomComponentId, boolValue, isPromise, componentValueTypes, getComponentSavedTypes, isSelectResourceWithObjectValue, removeHTML } from '../../utils';
6
6
  import Choices from '../../utils/ChoicesWrapper';
7
7
  export default class SelectComponent extends ListComponent {
8
8
  static schema(...extend) {
@@ -359,6 +359,18 @@ export default class SelectComponent extends ListComponent {
359
359
  this.downloadedResources.serverCount = this.downloadedResources.length;
360
360
  this.serverCount = this.downloadedResources.length;
361
361
  }
362
+ shouldResetChoicesItems(items) {
363
+ if (this.choices._store.choices.length !== items.length) {
364
+ return true;
365
+ }
366
+ for (let item of items) {
367
+ const choicesItem = this.choices._store.choices.find((i) => i.label === item.label);
368
+ if (!choicesItem) {
369
+ return true;
370
+ }
371
+ }
372
+ return false;
373
+ }
362
374
  /* eslint-disable max-statements */
363
375
  setItems(items, fromSearch) {
364
376
  this.selectItems = items;
@@ -444,7 +456,7 @@ export default class SelectComponent extends ListComponent {
444
456
  this.addOption(itemValueAndLabel.value, itemValueAndLabel.label, {}, _.get(item, this.component.idPath, String(index)));
445
457
  });
446
458
  if (this.choices) {
447
- this.choices.setChoices(this.selectOptions, 'value', 'label', true);
459
+ this.choices.setChoices(this.selectOptions, 'value', 'label', true, true, !fromSearch && this.shouldResetChoicesItems(this.selectOptions));
448
460
  }
449
461
  else if (this.loading) {
450
462
  // Re-attach select input.
@@ -935,8 +947,9 @@ export default class SelectComponent extends ListComponent {
935
947
  });
936
948
  }
937
949
  // Add value options.
950
+ const value = this.undoValueTyping(this.dataValue);
938
951
  this.addValueOptions();
939
- this.setChoicesValue(this.dataValue);
952
+ this.setChoicesValue(value);
940
953
  if (this.isSelectResource && this.refs.addResource) {
941
954
  this.addEventListener(this.refs.addResource, 'click', (event) => {
942
955
  event.preventDefault();
@@ -1248,7 +1261,7 @@ export default class SelectComponent extends ListComponent {
1248
1261
  }
1249
1262
  _.set(submission.metadata.selectData, this.path, templateData);
1250
1263
  }
1251
- if (flags.resetValue && this.root?.submission && !this.options.readOnly) {
1264
+ if (flags.resetValue && !flags.fromSubmission && this.root?.submission && !this.options.readOnly) {
1252
1265
  const submission = this.root.submission;
1253
1266
  if (!submission.metadata) {
1254
1267
  submission.metadata = {};
@@ -1312,6 +1325,9 @@ export default class SelectComponent extends ListComponent {
1312
1325
  this.lazyLoadInit = true;
1313
1326
  const searchProperty = this.component.searchField || this.component.valueProperty;
1314
1327
  this.triggerUpdate(_.get(value.data || value, searchProperty, value), true);
1328
+ this.itemsLoaded.then(() => {
1329
+ this.setChoicesValue(value, hasPreviousValue, flags);
1330
+ });
1315
1331
  return changed;
1316
1332
  }
1317
1333
  // Add the value options.
@@ -1,5 +1,5 @@
1
1
  import _ from 'lodash';
2
- import { eachComponent } from '../../../utils/utils';
2
+ import { eachComponent } from '../../../utils';
3
3
  const calculateSingleSelectData = (context, defaultValue) => {
4
4
  const { instance, data } = context;
5
5
  const rawDefaultValue = instance.downloadedResources.find(resource => _.get(resource, data.valueProperty) === defaultValue);
@@ -8,6 +8,12 @@ export default class SelectBoxesComponent extends RadioComponent {
8
8
  * @returns {boolean} - If the value is empty.
9
9
  */
10
10
  isEmpty(value?: any): boolean;
11
+ /**
12
+ * Normalize values coming into updateValue.
13
+ * @param {any} value - The value to normalize.
14
+ * @returns {*} - The normalized value
15
+ */
16
+ normalizeValue(value: any): any;
11
17
  setInputsDisabled(value: any, onlyUnchecked: any): void;
12
18
  checkComponentValidity(data: any, dirty: any, rowData: any, options: any, errors?: any[]): boolean;
13
19
  }
@@ -1,5 +1,5 @@
1
1
  import _ from 'lodash';
2
- import { componentValueTypes, getComponentSavedTypes, boolValue, getComponent } from '../../utils/utils';
2
+ import { componentValueTypes, getComponentSavedTypes, boolValue, getComponent } from '../../utils';
3
3
  import RadioComponent from '../radio/Radio';
4
4
  export default class SelectBoxesComponent extends RadioComponent {
5
5
  static schema(...extend) {
@@ -1,7 +1,7 @@
1
1
  import SignaturePad from 'signature_pad';
2
2
  import Input from '../_classes/input/Input';
3
3
  import _ from 'lodash';
4
- import { componentValueTypes, getComponentSavedTypes } from '../../utils/utils';
4
+ import { componentValueTypes, getComponentSavedTypes } from '../../utils';
5
5
  export default class SignatureComponent extends Input {
6
6
  static schema(...extend) {
7
7
  return Input.schema({
@@ -1,6 +1,6 @@
1
1
  import _ from 'lodash';
2
2
  import Field from '../_classes/field/Field';
3
- import { boolValue, componentValueTypes, getComponentSavedTypes } from '../../utils/utils';
3
+ import { boolValue, componentValueTypes, getComponentSavedTypes } from '../../utils';
4
4
  export default class SurveyComponent extends Field {
5
5
  static schema(...extend) {
6
6
  return Field.schema({
@@ -1,4 +1,4 @@
1
- import { componentValueTypes, getComponentSavedTypes } from '../../utils/utils';
1
+ import { componentValueTypes, getComponentSavedTypes } from '../../utils';
2
2
  import Input from '../_classes/input/Input';
3
3
  import Choices from 'choices.js';
4
4
  export default class TagsComponent extends Input {
@@ -1,7 +1,7 @@
1
1
  /* global Quill */
2
2
  import TextFieldComponent from '../textfield/TextField';
3
3
  import _ from 'lodash';
4
- import { uniqueName, getBrowserInfo } from '../../utils/utils';
4
+ import { uniqueName, getBrowserInfo } from '../../utils';
5
5
  export default class TextAreaComponent extends TextFieldComponent {
6
6
  static schema(...extend) {
7
7
  return TextFieldComponent.schema({
@@ -58,8 +58,8 @@ export default class TextAreaComponent extends TextFieldComponent {
58
58
  if ((this.options.readOnly || this.disabled) && !this.isHtmlRenderMode()) {
59
59
  const elementStyle = this.info.attr.style || '';
60
60
  const children = `
61
- <div ${this._referenceAttributeName}="input"
62
- class="formio-editor-read-only-content"
61
+ <div ${this._referenceAttributeName}="input"
62
+ class="formio-editor-read-only-content"
63
63
  ${elementStyle ? `style='${elementStyle}'` : ''}
64
64
  role="textbox"
65
65
  aria-multiline="true"