@formio/js 5.1.0-dev.5936.81a1533 → 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 (77) hide show
  1. package/dist/formio.builder.css +1 -0
  2. package/dist/formio.builder.min.css +1 -1
  3. package/dist/formio.form.css +1 -0
  4. package/dist/formio.form.js +20 -42
  5. package/dist/formio.form.min.css +1 -1
  6. package/dist/formio.form.min.js +1 -1
  7. package/dist/formio.full.css +1 -0
  8. package/dist/formio.full.js +22 -44
  9. package/dist/formio.full.min.css +1 -1
  10. package/dist/formio.full.min.js +1 -1
  11. package/dist/formio.js +7 -7
  12. package/dist/formio.min.js +1 -1
  13. package/dist/formio.utils.js +8 -8
  14. package/dist/formio.utils.min.js +1 -1
  15. package/lib/cjs/Element.d.ts +2 -1
  16. package/lib/cjs/Element.js +6 -4
  17. package/lib/cjs/PDFBuilder.d.ts +1 -0
  18. package/lib/cjs/PDFBuilder.js +8 -8
  19. package/lib/cjs/Webform.d.ts +2 -2
  20. package/lib/cjs/Webform.js +4 -3
  21. package/lib/cjs/WebformBuilder.d.ts +1 -1
  22. package/lib/cjs/WebformBuilder.js +27 -8
  23. package/lib/cjs/components/_classes/component/Component.js +5 -0
  24. package/lib/cjs/components/_classes/input/Input.d.ts +1 -1
  25. package/lib/cjs/components/_classes/input/Input.js +2 -2
  26. package/lib/cjs/components/_classes/nested/NestedComponent.js +4 -2
  27. package/lib/cjs/components/address/Address.js +1 -1
  28. package/lib/cjs/components/editgrid/EditGrid.d.ts +0 -1
  29. package/lib/cjs/components/editgrid/EditGrid.js +0 -8
  30. package/lib/cjs/components/radio/Radio.d.ts +9 -4
  31. package/lib/cjs/components/radio/Radio.js +40 -76
  32. package/lib/cjs/components/select/Select.d.ts +1 -0
  33. package/lib/cjs/components/select/Select.js +19 -3
  34. package/lib/cjs/components/selectboxes/SelectBoxes.d.ts +6 -0
  35. package/lib/cjs/components/textfield/TextField.js +6 -1
  36. package/lib/cjs/formio.form.js +2 -2
  37. package/lib/cjs/translations/en.d.ts +1 -232
  38. package/lib/cjs/translations/en.js +4 -2
  39. package/lib/cjs/utils/formUtils.d.ts +2 -2
  40. package/lib/cjs/utils/index.d.ts +2 -2
  41. package/lib/cjs/utils/utils.js +10 -3
  42. package/lib/mjs/Element.d.ts +2 -1
  43. package/lib/mjs/Element.js +6 -4
  44. package/lib/mjs/PDFBuilder.d.ts +1 -0
  45. package/lib/mjs/PDFBuilder.js +8 -8
  46. package/lib/mjs/Webform.d.ts +2 -2
  47. package/lib/mjs/Webform.js +4 -3
  48. package/lib/mjs/WebformBuilder.d.ts +1 -1
  49. package/lib/mjs/WebformBuilder.js +26 -8
  50. package/lib/mjs/components/_classes/component/Component.js +5 -0
  51. package/lib/mjs/components/_classes/input/Input.d.ts +1 -1
  52. package/lib/mjs/components/_classes/input/Input.js +2 -2
  53. package/lib/mjs/components/_classes/nested/NestedComponent.js +4 -2
  54. package/lib/mjs/components/address/Address.js +1 -1
  55. package/lib/mjs/components/editgrid/EditGrid.d.ts +0 -1
  56. package/lib/mjs/components/editgrid/EditGrid.js +0 -8
  57. package/lib/mjs/components/radio/Radio.d.ts +9 -4
  58. package/lib/mjs/components/radio/Radio.js +40 -75
  59. package/lib/mjs/components/select/Select.d.ts +1 -0
  60. package/lib/mjs/components/select/Select.js +19 -3
  61. package/lib/mjs/components/selectboxes/SelectBoxes.d.ts +6 -0
  62. package/lib/mjs/components/textfield/TextField.js +6 -1
  63. package/lib/mjs/formio.form.js +1 -1
  64. package/lib/mjs/translations/en.d.ts +1 -232
  65. package/lib/mjs/translations/en.js +8 -47
  66. package/lib/mjs/utils/formUtils.d.ts +2 -2
  67. package/lib/mjs/utils/index.d.ts +2 -2
  68. package/lib/mjs/utils/utils.js +10 -2
  69. package/package.json +2 -2
  70. package/lib/cjs/i18n.d.ts +0 -13
  71. package/lib/cjs/i18n.js +0 -19
  72. package/lib/cjs/utils/i18n.d.ts +0 -19
  73. package/lib/cjs/utils/i18n.js +0 -120
  74. package/lib/mjs/i18n.d.ts +0 -13
  75. package/lib/mjs/i18n.js +0 -14
  76. package/lib/mjs/utils/i18n.d.ts +0 -19
  77. package/lib/mjs/utils/i18n.js +0 -112
@@ -170,10 +170,11 @@ export default class Element {
170
170
  /**
171
171
  * Translate a text using the i18n system.
172
172
  * @param {string|Array<string>} text - The i18n identifier.
173
+ * @param {any} data - contextual data object containing data, component, row, etc.
173
174
  * @param {...any} args - The arguments to pass to the i18n translation.
174
175
  * @returns {string} - The translated text.
175
176
  */
176
- t(text: string | Array<string>, ...args: any[]): string;
177
+ t(text: string | Array<string>, data: any, ...args: any[]): string;
177
178
  /**
178
179
  * Alias to create a text node.
179
180
  * @param {string} text - The text to create.
@@ -8,8 +8,9 @@ const moment_1 = __importDefault(require("moment"));
8
8
  const vanilla_text_mask_1 = __importDefault(require("@formio/vanilla-text-mask"));
9
9
  const EventEmitter_1 = __importDefault(require("./EventEmitter"));
10
10
  const Formio_1 = require("./Formio");
11
- const i18n_1 = require("./utils/i18n");
12
11
  const utils_1 = __importDefault(require("./utils"));
12
+ const core_1 = require("@formio/core");
13
+ const en_1 = __importDefault(require("./translations/en"));
13
14
  /**
14
15
  * The root component for all elements within the Form.io renderer.
15
16
  */
@@ -44,7 +45,7 @@ class Element {
44
45
  if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.language) {
45
46
  this.options.i18n.language = this.options.language;
46
47
  }
47
- this.options.i18next = this.i18next = this.options.i18next || i18n_1.I18n.init(this.options.i18n);
48
+ this.options.i18next = this.i18next = this.options.i18next || core_1.I18n.init(Object.assign({ en: en_1.default }, this.options.i18n));
48
49
  /**
49
50
  * An instance of the EventEmitter class to handle the emitting and registration of events.
50
51
  * @type {EventEmitter}
@@ -392,11 +393,12 @@ class Element {
392
393
  /**
393
394
  * Translate a text using the i18n system.
394
395
  * @param {string|Array<string>} text - The i18n identifier.
396
+ * @param {any} data - contextual data object containing data, component, row, etc.
395
397
  * @param {...any} args - The arguments to pass to the i18n translation.
396
398
  * @returns {string} - The translated text.
397
399
  */
398
- t(text, ...args) {
399
- return this.i18next ? this.i18next.t(text, ...args) : text;
400
+ t(text, data, ...args) {
401
+ return this.i18next ? this.i18next.t(text, data, ...args) : text;
400
402
  }
401
403
  /**
402
404
  * Alias to create a text node.
@@ -51,5 +51,6 @@ export default class PDFBuilder extends WebformBuilder {
51
51
  onDropzoneDrop(e: any): boolean;
52
52
  dropEvent: any;
53
53
  onDragEnd(e: any): void;
54
+ repeatablePathsComps: any[] | undefined;
54
55
  }
55
56
  import WebformBuilder from './WebformBuilder';
@@ -451,21 +451,21 @@ class PDFBuilder extends WebformBuilder_1.default {
451
451
  e.target.style.cursor = 'default';
452
452
  }
453
453
  highlightInvalidComponents() {
454
- const repeatablePaths = this.findRepeatablePaths();
454
+ const repeatablePathsComps = this.findComponentsWithRepeatablePaths();
455
455
  // update elements which path was duplicated if any pathes have been changed
456
- if (!lodash_1.default.isEqual(this.repeatablePaths, repeatablePaths)) {
457
- (0, utils_1.eachComponent)(this.webform.getComponents(), (comp, path) => {
458
- if (this.repeatablePaths.includes(path)) {
456
+ if (!lodash_1.default.isEqual(this.repeatablePathsComps, repeatablePathsComps)) {
457
+ (0, utils_1.eachComponent)(this.webform.getComponents(), (comp) => {
458
+ if (this.repeatablePathsComps.includes(comp.component)) {
459
459
  this.webform.postMessage({ name: 'updateElement', data: comp.component });
460
460
  }
461
461
  });
462
- this.repeatablePaths = repeatablePaths;
462
+ this.repeatablePathsComps = repeatablePathsComps;
463
463
  }
464
- if (!repeatablePaths.length) {
464
+ if (!repeatablePathsComps.length) {
465
465
  return;
466
466
  }
467
- (0, utils_1.eachComponent)(this.webform.getComponents(), (comp, path) => {
468
- if (this.repeatablePaths.includes(path)) {
467
+ (0, utils_1.eachComponent)(this.webform.getComponents(), (comp) => {
468
+ if (this.repeatablePathsComps.includes(comp)) {
469
469
  this.webform.postMessage({
470
470
  name: 'showBuilderErrors',
471
471
  data: {
@@ -45,7 +45,7 @@
45
45
  * @property {number} [saveDraftThrottle] - The throttle for the save draft feature.
46
46
  * @property {boolean} [readOnly] - Set this form to readOnly.
47
47
  * @property {boolean} [noAlerts] - Disable the alerts dialog.
48
- * @property {{[key: string]: string}} [i18n] - The translation file for this rendering.
48
+ * @property {{[key: string]: string}} [enTranslation] - The translation file for this rendering.
49
49
  * @property {string} [template] - Custom logic for creation of elements.
50
50
  * @property {boolean} [noDefaults] - Exclude default values from the settings.
51
51
  * @property {any} [fileService] - The file service for this form.
@@ -586,7 +586,7 @@ export type FormOptions = {
586
586
  /**
587
587
  * - The translation file for this rendering.
588
588
  */
589
- i18n?: {
589
+ enTranslation?: {
590
590
  [key: string]: string;
591
591
  } | undefined;
592
592
  /**
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const lodash_1 = __importDefault(require("lodash"));
7
7
  const compare_versions_1 = require("compare-versions");
8
8
  const EventEmitter_1 = __importDefault(require("./EventEmitter"));
9
- const i18n_1 = __importDefault(require("./i18n"));
9
+ const en_1 = __importDefault(require("./translations/en"));
10
10
  const Formio_1 = require("./Formio");
11
11
  const Components_1 = __importDefault(require("./components/Components"));
12
12
  const NestedDataComponent_1 = __importDefault(require("./components/_classes/nesteddata/NestedDataComponent"));
@@ -99,7 +99,7 @@ function getOptions(options) {
99
99
  * @property {number} [saveDraftThrottle] - The throttle for the save draft feature.
100
100
  * @property {boolean} [readOnly] - Set this form to readOnly.
101
101
  * @property {boolean} [noAlerts] - Disable the alerts dialog.
102
- * @property {{[key: string]: string}} [i18n] - The translation file for this rendering.
102
+ * @property {{[key: string]: string}} [enTranslation] - The translation file for this rendering.
103
103
  * @property {string} [template] - Custom logic for creation of elements.
104
104
  * @property {boolean} [noDefaults] - Exclude default values from the settings.
105
105
  * @property {any} [fileService] - The file service for this form.
@@ -369,7 +369,7 @@ class Webform extends NestedDataComponent_1.default {
369
369
  */
370
370
  addLanguage(code, lang, active = false) {
371
371
  if (this.i18next) {
372
- var translations = lodash_1.default.assign((0, utils_1.fastCloneDeep)(i18n_1.default.resources.en.translation), lang);
372
+ var translations = lodash_1.default.assign((0, utils_1.fastCloneDeep)(en_1.default), lang);
373
373
  this.i18next.addResourceBundle(code, 'translation', translations, true, true);
374
374
  if (active) {
375
375
  this.language = code;
@@ -1320,6 +1320,7 @@ class Webform extends NestedDataComponent_1.default {
1320
1320
  userAgent: navigator.userAgent,
1321
1321
  pathName: window.location.pathname,
1322
1322
  onLine: navigator.onLine,
1323
+ language: this.language,
1323
1324
  });
1324
1325
  }
1325
1326
  submitForm(options = {}, local = false) {
@@ -78,7 +78,7 @@ export default class WebformBuilder extends Component {
78
78
  replaceDoubleQuotes(data: any, fieldsToRemoveDoubleQuotes?: any[]): any;
79
79
  updateComponent(component: any, changed: any): void;
80
80
  originalDefaultValue: any;
81
- findRepeatablePaths(): any[];
81
+ findComponentsWithRepeatablePaths(): any[];
82
82
  highlightInvalidComponents(): void;
83
83
  /**
84
84
  * Called when a new component is saved.
@@ -1125,31 +1125,50 @@ class WebformBuilder extends Component_1.default {
1125
1125
  // Called when we update a component.
1126
1126
  this.emit('updateComponent', component);
1127
1127
  }
1128
- findRepeatablePaths() {
1129
- const repeatablePaths = [];
1128
+ findComponentsWithRepeatablePaths() {
1129
+ const repeatablePaths = {};
1130
1130
  const keys = new Map();
1131
1131
  (0, utils_1.eachComponent)(this.form.components, (comp, path, components, parent, paths) => {
1132
+ var _a, _b;
1133
+ const isRadioCheckbox = comp.type === 'checkbox' && comp.inputType === 'radio';
1132
1134
  const isLayout = (0, utils_1.componentInfo)(comp).layout;
1133
1135
  if (!isLayout) {
1134
1136
  if (keys.has(paths.dataPath)) {
1135
- repeatablePaths.push(paths.dataPath);
1137
+ const onlyRadioCheckboxes = ((_a = repeatablePaths[paths.dataPath]) === null || _a === void 0 ? void 0 : _a.onlyRadioCheckboxes) === false ? false : isRadioCheckbox;
1138
+ repeatablePaths[paths.dataPath] = {
1139
+ comps: [...(((_b = repeatablePaths[paths.dataPath]) === null || _b === void 0 ? void 0 : _b.comps) || []), keys.get(paths.dataPath), comp],
1140
+ onlyRadioCheckboxes,
1141
+ };
1136
1142
  }
1137
1143
  else {
1138
- keys.set(paths.dataPath, true);
1144
+ keys.set(paths.dataPath, comp);
1139
1145
  }
1140
1146
  }
1141
1147
  }, true);
1142
- return repeatablePaths;
1148
+ const componentsWithRepeatablePaths = [];
1149
+ Object.keys(repeatablePaths).forEach((path) => {
1150
+ const { comps, onlyRadioCheckboxes } = repeatablePaths[path];
1151
+ if (!onlyRadioCheckboxes) {
1152
+ componentsWithRepeatablePaths.push(...comps);
1153
+ }
1154
+ });
1155
+ return componentsWithRepeatablePaths;
1143
1156
  }
1144
1157
  highlightInvalidComponents() {
1145
- const repeatablePaths = this.findRepeatablePaths();
1158
+ const repeatablePathsComps = this.findComponentsWithRepeatablePaths();
1146
1159
  let hasInvalidComponents = false;
1160
+ // Matches anything expect letters and '_' at the beginning of the key and anything except of letters, numbers,
1161
+ // '-', '.' and '_' in the rest of the key
1162
+ const badCharacters = /^[^A-Za-z_]+|[^A-Za-z0-9\-._]+/g;
1147
1163
  this.webform.everyComponent((comp) => {
1148
- const path = comp.path;
1149
- if (repeatablePaths.includes(path)) {
1164
+ if (repeatablePathsComps.includes(comp.component)) {
1150
1165
  comp.setCustomValidity(this.t('apiKey', { key: comp.key }));
1151
1166
  hasInvalidComponents = true;
1152
1167
  }
1168
+ else if (comp.key.replace(badCharacters, '') === '') {
1169
+ comp.setCustomValidity(this.t('apiKeyNotValid', { key: comp.key }));
1170
+ hasInvalidComponents = true;
1171
+ }
1153
1172
  else {
1154
1173
  comp.setCustomValidity();
1155
1174
  }
@@ -2710,6 +2710,11 @@ class Component extends Element_1.default {
2710
2710
  this.setValueAt(i, isArray && !this.isSingleInputValue() ? value[i] : value, flags);
2711
2711
  }
2712
2712
  }
2713
+ // Also reset value of the modal component, otherwise it will keep the old value locally and the preview
2714
+ // element won't refresh
2715
+ if (this.componentModal && flags && flags.resetValue) {
2716
+ this.componentModal.setValue(value);
2717
+ }
2713
2718
  return changed;
2714
2719
  }
2715
2720
  /**
@@ -25,7 +25,7 @@ export default class Input extends Multivalue {
25
25
  get suffix(): any;
26
26
  renderElement(value: any, index: any): any;
27
27
  setCounter(type: any, element: any, count: any, max: any): void;
28
- updateValueAt(value: any, flags: any, index: any): void;
28
+ updateValueAt(value: any, flags: any, index?: number): void;
29
29
  getValueAt(index: any): any;
30
30
  updateValue(value: any, flags: any, index: any): boolean;
31
31
  parseValue(value: any): any;
@@ -118,7 +118,7 @@ class Input extends Multivalue_1.default {
118
118
  }
119
119
  const info = this.inputInfo;
120
120
  info.attr = info.attr || {};
121
- info.attr.value = this.getValueAsString(this.formatValue(this.parseValue(value)))
121
+ info.attr.value = this.getValueAsString(this.formatValue(this.parseValue(this.isMultipleMasksField ? value.value : value)))
122
122
  .replace(/"/g, '&quot;');
123
123
  const valueMask = this.component.inputMask;
124
124
  const displayMask = this.component.displayMask;
@@ -163,7 +163,7 @@ class Input extends Multivalue_1.default {
163
163
  }));
164
164
  }
165
165
  }
166
- updateValueAt(value, flags, index) {
166
+ updateValueAt(value, flags, index = 0) {
167
167
  flags = flags || {};
168
168
  if (lodash_1.default.get(this.component, 'showWordCount', false)) {
169
169
  if (this.refs.wordcount && this.refs.wordcount[index]) {
@@ -664,7 +664,7 @@ class NestedComponent extends Field_1.default {
664
664
  validationProcessor({ scope, data, row, instance, paths }, flags) {
665
665
  var _a;
666
666
  const { dirty } = flags;
667
- if (this.root.hasSubWizards && this.page !== this.root.page) {
667
+ if (this.root && this.root.hasSubWizards && this.page !== this.root.page) {
668
668
  instance = ((_a = this.componentsMap) === null || _a === void 0 ? void 0 : _a.hasOwnProperty(paths.dataPath))
669
669
  ? this.componentsMap[paths.dataPath]
670
670
  : this.getComponent(paths.dataPath);
@@ -800,8 +800,10 @@ class NestedComponent extends Field_1.default {
800
800
  return this.data;
801
801
  }
802
802
  resetValue() {
803
- super.resetValue();
803
+ // Reset values of child components first, then reset the parent one, otherwise it will restore the default
804
+ // value of parent component and clear it one by one while resetting child components
804
805
  this.getComponents().forEach((comp) => comp.resetValue());
806
+ super.resetValue();
805
807
  this.setPristine(true);
806
808
  }
807
809
  get dataReady() {
@@ -249,7 +249,7 @@ class AddressComponent extends Container_1.default {
249
249
  if (this.manualMode) {
250
250
  this.restoreComponentsContext();
251
251
  }
252
- if (changed || !lodash_1.default.isEmpty(value) && flags.fromSubmission) {
252
+ if (changed || !lodash_1.default.isEmpty(value) && flags.fromSubmission || flags.resetValue) {
253
253
  this.redraw();
254
254
  }
255
255
  return changed;
@@ -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';
@@ -1200,14 +1200,6 @@ class EditGridComponent extends NestedArrayComponent_1.default {
1200
1200
  this.setNestedValue(component, editRow.data, flags);
1201
1201
  });
1202
1202
  }
1203
- emptyRows() {
1204
- this.editRows.forEach((editRow, index) => this.destroyComponents(false, index));
1205
- this.editRows = [];
1206
- }
1207
- resetValue() {
1208
- super.resetValue();
1209
- this.emptyRows();
1210
- }
1211
1203
  }
1212
1204
  exports.default = EditGridComponent;
1213
1205
  EditGridComponent.prototype.hasChanged = Component_1.default.prototype.hasChanged;
@@ -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';
@@ -6,8 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const lodash_1 = __importDefault(require("lodash"));
7
7
  const ListComponent_1 = __importDefault(require("../_classes/list/ListComponent"));
8
8
  const Formio_1 = require("../../Formio");
9
- const utils_1 = require("../../utils/utils");
10
- const uuid_1 = require("uuid");
9
+ const utils_1 = require("../../utils");
11
10
  class RadioComponent extends ListComponent_1.default {
12
11
  static schema(...extend) {
13
12
  return ListComponent_1.default.schema({
@@ -80,13 +79,15 @@ class RadioComponent extends ListComponent_1.default {
80
79
  }
81
80
  return defaultValue;
82
81
  }
83
- resetValue() {
82
+ uncheckValue(flags = {}) {
84
83
  this.unset();
85
84
  this.setValue(this.emptyValue, {
86
85
  noUpdateEvent: true,
87
86
  noValidate: true,
88
87
  resetValue: true
89
88
  });
89
+ this.triggerChange(flags);
90
+ this.setSelectedClasses();
90
91
  }
91
92
  get inputInfo() {
92
93
  var _a;
@@ -143,7 +144,6 @@ class RadioComponent extends ListComponent_1.default {
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 @@ class RadioComponent extends ListComponent_1.default {
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 => (Object.assign(Object.assign({}, 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 @@ class RadioComponent extends ListComponent_1.default {
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 @@ class RadioComponent extends ListComponent_1.default {
183
189
  if (!lodash_1.default.isString(this.dataValue)) {
184
190
  dataValue = lodash_1.default.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 = lodash_1.default.isEqual(this.normalizeValue(optionValue), this.dataValue);
192
+ if (this.isSelectURL && lodash_1.default.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 = lodash_1.default.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 @@ class RadioComponent extends ListComponent_1.default {
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 && lodash_1.default.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 @@ class RadioComponent extends ListComponent_1.default {
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 = lodash_1.default.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 @@ class RadioComponent extends ListComponent_1.default {
287
285
  }
288
286
  return super.shouldLoad;
289
287
  }
290
- prepareValue(item, options = {}) {
291
- const value = this.component.valueProperty && !options.skipValueProperty
292
- ? lodash_1.default.get(item, this.component.valueProperty)
293
- : item;
294
- if (this.component.type === 'radio' && typeof value !== 'string') {
295
- const uuid = (0, uuid_1.v4)();
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 @@ class RadioComponent extends ListComponent_1.default {
354
335
  label: this.itemTemplate(item)
355
336
  };
356
337
  if (lodash_1.default.isEqual(item, this.selectData || lodash_1.default.pick(this.dataValue, lodash_1.default.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 @@ class RadioComponent extends ListComponent_1.default {
364
345
  const listData = [];
365
346
  items === null || items === void 0 ? void 0 : items.forEach((item, i) => {
366
347
  const valueAtProperty = lodash_1.default.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 && (lodash_1.default.isObject(value) || lodash_1.default.isBoolean(value) || lodash_1.default.isUndefined(value))) {
377
355
  this.loadedOptions[i].invalid = true;
378
356
  }
@@ -395,11 +373,7 @@ class RadioComponent extends ListComponent_1.default {
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
- : lodash_1.default.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,26 +387,10 @@ class RadioComponent extends ListComponent_1.default {
413
387
  });
414
388
  }
415
389
  }
416
- setMetadata(value) {
417
- var _a;
418
- let key = value;
419
- if (typeof value !== 'string') {
420
- const checkedInput = Array.prototype.find.call((_a = this.refs.input) !== null && _a !== void 0 ? _a : [], (input => input.type === 'radio' && input.getAttribute('checked')));
421
- key = (checkedInput === null || checkedInput === void 0 ? void 0 : checkedInput.value) || key;
422
- }
423
- if (this.isSelectURL && this.templateData && this.templateData[key]) {
424
- const submission = this.root.submission;
425
- if (!submission.metadata.selectData) {
426
- submission.metadata.selectData = {};
427
- }
428
- lodash_1.default.set(submission.metadata.selectData, this.path, this.templateData[key]);
429
- }
430
- }
431
390
  updateValue(value, flags) {
432
391
  const changed = super.updateValue(value, flags);
433
392
  if (changed) {
434
393
  this.setSelectedClasses();
435
- this.setMetadata(this.dataValue);
436
394
  }
437
395
  if (!flags || !flags.modified || !this.isRadio) {
438
396
  if (changed) {
@@ -444,9 +402,7 @@ class RadioComponent extends ListComponent_1.default {
444
402
  this.currentValue = this.dataValue;
445
403
  const shouldResetValue = flags && flags.modified && !flags.noUpdateEvent && this.previousValue === this.currentValue;
446
404
  if (shouldResetValue) {
447
- this.resetValue();
448
- this.triggerChange(flags);
449
- this.setSelectedClasses();
405
+ this.uncheckValue(flags);
450
406
  }
451
407
  this.previousValue = this.dataValue;
452
408
  return changed;
@@ -456,7 +412,7 @@ class RadioComponent extends ListComponent_1.default {
456
412
  * @param {*} value - The value to normalize
457
413
  * @returns {*} - Returns the normalized value
458
414
  */
459
- normalizeValue(value) {
415
+ convertByDataType(value) {
460
416
  const dataType = this.component.dataType || 'auto';
461
417
  if (value === this.emptyValue) {
462
418
  return value;
@@ -488,10 +444,18 @@ class RadioComponent extends ListComponent_1.default {
488
444
  value = !(!value || value.toString() === 'false');
489
445
  break;
490
446
  }
491
- return super.normalizeValue(value);
447
+ return value;
492
448
  }
493
- isSingleInputValue() {
494
- 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
+ lodash_1.default.set(submission.metadata.selectData, this.path, this.templateData[valueConverted]);
457
+ }
458
+ return super.normalizeValue(valueConverted);
495
459
  }
496
460
  }
497
461
  exports.default = RadioComponent;
@@ -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);
@@ -355,6 +355,18 @@ class SelectComponent extends ListComponent_1.default {
355
355
  this.downloadedResources.serverCount = this.downloadedResources.length;
356
356
  this.serverCount = this.downloadedResources.length;
357
357
  }
358
+ shouldResetChoicesItems(items) {
359
+ if (this.choices._store.choices.length !== items.length) {
360
+ return true;
361
+ }
362
+ for (let item of items) {
363
+ const choicesItem = this.choices._store.choices.find((i) => i.label === item.label);
364
+ if (!choicesItem) {
365
+ return true;
366
+ }
367
+ }
368
+ return false;
369
+ }
358
370
  /* eslint-disable max-statements */
359
371
  setItems(items, fromSearch) {
360
372
  var _a, _b;
@@ -441,7 +453,7 @@ class SelectComponent extends ListComponent_1.default {
441
453
  this.addOption(itemValueAndLabel.value, itemValueAndLabel.label, {}, lodash_1.default.get(item, this.component.idPath, String(index)));
442
454
  });
443
455
  if (this.choices) {
444
- this.choices.setChoices(this.selectOptions, 'value', 'label', true);
456
+ this.choices.setChoices(this.selectOptions, 'value', 'label', true, true, !fromSearch && this.shouldResetChoicesItems(this.selectOptions));
445
457
  }
446
458
  else if (this.loading) {
447
459
  // Re-attach select input.
@@ -903,8 +915,9 @@ class SelectComponent extends ListComponent_1.default {
903
915
  });
904
916
  }
905
917
  // Add value options.
918
+ const value = this.undoValueTyping(this.dataValue);
906
919
  this.addValueOptions();
907
- this.setChoicesValue(this.dataValue);
920
+ this.setChoicesValue(value);
908
921
  if (this.isSelectResource && this.refs.addResource) {
909
922
  this.addEventListener(this.refs.addResource, 'click', (event) => {
910
923
  event.preventDefault();
@@ -1219,7 +1232,7 @@ class SelectComponent extends ListComponent_1.default {
1219
1232
  }
1220
1233
  lodash_1.default.set(submission.metadata.selectData, this.path, templateData);
1221
1234
  }
1222
- if (flags.resetValue && ((_b = this.root) === null || _b === void 0 ? void 0 : _b.submission) && !this.options.readOnly) {
1235
+ if (flags.resetValue && !flags.fromSubmission && ((_b = this.root) === null || _b === void 0 ? void 0 : _b.submission) && !this.options.readOnly) {
1223
1236
  const submission = this.root.submission;
1224
1237
  if (!submission.metadata) {
1225
1238
  submission.metadata = {};
@@ -1283,6 +1296,9 @@ class SelectComponent extends ListComponent_1.default {
1283
1296
  this.lazyLoadInit = true;
1284
1297
  const searchProperty = this.component.searchField || this.component.valueProperty;
1285
1298
  this.triggerUpdate(lodash_1.default.get(value.data || value, searchProperty, value), true);
1299
+ this.itemsLoaded.then(() => {
1300
+ this.setChoicesValue(value, hasPreviousValue, flags);
1301
+ });
1286
1302
  return changed;
1287
1303
  }
1288
1304
  // Add the value options.