@formio/js 5.0.0-dev.5935.c16c9d9 → 5.0.0-dev.5936.905c79f

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.
@@ -987,7 +987,7 @@ class EditGridComponent extends NestedArrayComponent_1.default {
987
987
  dirty;
988
988
  }
989
989
  validateRow(editRow, dirty, forceSilentCheck, fromSubmission) {
990
- var _a, _b;
990
+ var _a;
991
991
  editRow.errors = [];
992
992
  if (this.shouldValidateRow(editRow, dirty, fromSubmission)) {
993
993
  const silentCheck = (this.component.rowDrafts && !this.shouldValidateDraft(editRow)) || forceSilentCheck;
@@ -1037,12 +1037,9 @@ class EditGridComponent extends NestedArrayComponent_1.default {
1037
1037
  });
1038
1038
  }
1039
1039
  }
1040
- if (editRow.alerts && (!this.component.rowDrafts || ((_a = this.root) === null || _a === void 0 ? void 0 : _a.submitted))) {
1040
+ if (!this.component.rowDrafts || ((_a = this.root) === null || _a === void 0 ? void 0 : _a.submitted)) {
1041
1041
  this.showRowErrorAlerts(editRow, editRow.errors);
1042
1042
  }
1043
- else if ((_b = editRow.errors) === null || _b === void 0 ? void 0 : _b.length) {
1044
- this.setCustomValidity(editRow.errors, dirty);
1045
- }
1046
1043
  return editRow.errors;
1047
1044
  }
1048
1045
  showRowErrorAlerts(editRow, errors) {
@@ -27,6 +27,7 @@ export default class RadioComponent extends ListComponent {
27
27
  itemsLoadedResolve: ((value: any) => void) | undefined;
28
28
  optionsLoaded: boolean | undefined;
29
29
  loadedOptions: any[] | undefined;
30
+ valuesMap: Map<any, any> | undefined;
30
31
  beforeSubmit(): Promise<any>;
31
32
  render(): import("../_classes/field/Field").default;
32
33
  attach(element: any): Promise<void>;
@@ -35,10 +36,13 @@ export default class RadioComponent extends ListComponent {
35
36
  validateValueAvailability(setting: any, value: any): boolean;
36
37
  getValueAsString(value: any, options?: {}): any;
37
38
  setValueAt(index: any, value: any): void;
39
+ prepareValue(item: any, options?: {}): any;
40
+ getValueByInput(input: any): any;
38
41
  loadItems(url: any, search: any, headers: any, options: any, method: any, body: any): void;
39
42
  loadItemsFromMetadata(): void;
40
43
  setItems(items: any): void;
41
44
  setSelectedClasses(): void;
45
+ setMetadata(value: any): void;
42
46
  updateValue(value: any, flags: any): boolean;
43
47
  currentValue: any;
44
48
  }
@@ -7,6 +7,7 @@ const lodash_1 = __importDefault(require("lodash"));
7
7
  const ListComponent_1 = __importDefault(require("../_classes/list/ListComponent"));
8
8
  const Formio_1 = require("../../Formio");
9
9
  const utils_1 = require("../../utils/utils");
10
+ const uuid_1 = require("uuid");
10
11
  class RadioComponent extends ListComponent_1.default {
11
12
  static schema(...extend) {
12
13
  return ListComponent_1.default.schema({
@@ -142,6 +143,7 @@ class RadioComponent extends ListComponent_1.default {
142
143
  });
143
144
  this.optionsLoaded = !this.component.dataSrc || this.component.dataSrc === 'values';
144
145
  this.loadedOptions = [];
146
+ this.valuesMap = new Map();
145
147
  if (!this.visible) {
146
148
  this.itemsLoadedResolve();
147
149
  }
@@ -181,9 +183,12 @@ class RadioComponent extends ListComponent_1.default {
181
183
  if (!lodash_1.default.isString(this.dataValue)) {
182
184
  dataValue = lodash_1.default.toString(this.dataValue);
183
185
  }
184
- if (this.isSelectURL && lodash_1.default.isObject(this.loadedOptions[index].value)) {
185
- const optionValue = this.component.dataType === 'string' ? JSON.stringify(this.loadedOptions[index].value) : this.loadedOptions[index].value;
186
- input.checked = lodash_1.default.isEqual(optionValue, this.dataValue);
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);
187
192
  }
188
193
  else {
189
194
  input.checked = (dataValue === input.value && (input.value || this.component.dataSrc !== 'url'));
@@ -220,9 +225,14 @@ class RadioComponent extends ListComponent_1.default {
220
225
  let value = this.component.inputType === 'checkbox' ? '' : this.dataValue;
221
226
  this.refs.input.forEach((input, index) => {
222
227
  if (input.checked) {
223
- value = (this.isSelectURL && lodash_1.default.isObject(this.loadedOptions[index].value)) ?
224
- this.loadedOptions[index].value :
225
- input.value;
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;
226
236
  }
227
237
  });
228
238
  return value;
@@ -266,8 +276,8 @@ class RadioComponent extends ListComponent_1.default {
266
276
  }
267
277
  setValueAt(index, value) {
268
278
  if (this.refs.input && this.refs.input[index] && value !== null && value !== undefined) {
269
- const inputValue = this.refs.input[index].value;
270
- this.refs.input[index].checked = (inputValue === value.toString());
279
+ const inputValue = this.getValueByInput(this.refs.input[index]);
280
+ this.refs.input[index].checked = lodash_1.default.isEqual(inputValue, value);
271
281
  }
272
282
  }
273
283
  get shouldLoad() {
@@ -277,6 +287,23 @@ class RadioComponent extends ListComponent_1.default {
277
287
  }
278
288
  return super.shouldLoad;
279
289
  }
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
+ }
280
307
  loadItems(url, search, headers, options, method, body) {
281
308
  if (this.optionsLoaded) {
282
309
  this.itemsLoadedResolve();
@@ -327,7 +354,7 @@ class RadioComponent extends ListComponent_1.default {
327
354
  label: this.itemTemplate(item)
328
355
  };
329
356
  if (lodash_1.default.isEqual(item, this.selectData || lodash_1.default.pick(this.dataValue, lodash_1.default.keys(item)))) {
330
- this.loadedOptions[i].value = this.dataValue;
357
+ this.loadedOptions[i].value = this.prepareValue(this.dataValue, { skipValueProperty: true });
331
358
  }
332
359
  });
333
360
  this.optionsLoaded = true;
@@ -337,12 +364,15 @@ class RadioComponent extends ListComponent_1.default {
337
364
  const listData = [];
338
365
  items === null || items === void 0 ? void 0 : items.forEach((item, i) => {
339
366
  const valueAtProperty = lodash_1.default.get(item, this.component.valueProperty);
340
- this.loadedOptions[i] = {
341
- value: this.component.valueProperty ? valueAtProperty : item,
342
- label: this.component.valueProperty ? this.itemTemplate(item, valueAtProperty) : this.itemTemplate(item, item, i)
343
- };
344
- listData.push(this.templateData[this.component.valueProperty ? valueAtProperty : i]);
345
- const value = this.loadedOptions[i].value;
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
+ }
346
376
  if (!this.isRadio && (lodash_1.default.isObject(value) || lodash_1.default.isBoolean(value) || lodash_1.default.isUndefined(value))) {
347
377
  this.loadedOptions[i].invalid = true;
348
378
  }
@@ -365,7 +395,9 @@ class RadioComponent extends ListComponent_1.default {
365
395
  const value = this.dataValue;
366
396
  this.refs.wrapper.forEach((wrapper, index) => {
367
397
  const input = this.refs.input[index];
368
- const checked = (input.type === 'checkbox') ? value[input.value] || input.checked : (input.value.toString() === value.toString());
398
+ const checked = (input.type === 'checkbox')
399
+ ? value[input.value] || input.checked
400
+ : lodash_1.default.isEqual(this.normalizeValue(this.getValueByInput(input)), value);
369
401
  if (checked) {
370
402
  //add class to container when selected
371
403
  this.addClass(wrapper, this.optionSelectedClass);
@@ -379,10 +411,25 @@ class RadioComponent extends ListComponent_1.default {
379
411
  });
380
412
  }
381
413
  }
414
+ setMetadata(value) {
415
+ let key = value;
416
+ if (typeof value !== 'string') {
417
+ const checkedInput = Array.prototype.find.call(this.refs.input, (input => input.type === 'radio' && input.getAttribute('checked')));
418
+ key = (checkedInput === null || checkedInput === void 0 ? void 0 : checkedInput.value) || key;
419
+ }
420
+ if (this.isSelectURL && this.templateData && this.templateData[key]) {
421
+ const submission = this.root.submission;
422
+ if (!submission.metadata.selectData) {
423
+ submission.metadata.selectData = {};
424
+ }
425
+ lodash_1.default.set(submission.metadata.selectData, this.path, this.templateData[key]);
426
+ }
427
+ }
382
428
  updateValue(value, flags) {
383
429
  const changed = super.updateValue(value, flags);
384
430
  if (changed) {
385
431
  this.setSelectedClasses();
432
+ this.setMetadata(this.dataValue);
386
433
  }
387
434
  if (!flags || !flags.modified || !this.isRadio) {
388
435
  if (changed) {
@@ -438,14 +485,10 @@ class RadioComponent extends ListComponent_1.default {
438
485
  value = !(!value || value.toString() === 'false');
439
486
  break;
440
487
  }
441
- if (this.isSelectURL && this.templateData && this.templateData[value]) {
442
- const submission = this.root.submission;
443
- if (!submission.metadata.selectData) {
444
- submission.metadata.selectData = {};
445
- }
446
- lodash_1.default.set(submission.metadata.selectData, this.path, this.templateData[value]);
447
- }
448
488
  return super.normalizeValue(value);
449
489
  }
490
+ isSingleInputValue() {
491
+ return true;
492
+ }
450
493
  }
451
494
  exports.default = RadioComponent;
@@ -1026,12 +1026,9 @@ export default class EditGridComponent extends NestedArrayComponent {
1026
1026
  });
1027
1027
  }
1028
1028
  }
1029
- if (editRow.alerts && (!this.component.rowDrafts || this.root?.submitted)) {
1029
+ if (!this.component.rowDrafts || this.root?.submitted) {
1030
1030
  this.showRowErrorAlerts(editRow, editRow.errors);
1031
1031
  }
1032
- else if (editRow.errors?.length) {
1033
- this.setCustomValidity(editRow.errors, dirty);
1034
- }
1035
1032
  return editRow.errors;
1036
1033
  }
1037
1034
  showRowErrorAlerts(editRow, errors) {
@@ -27,6 +27,7 @@ export default class RadioComponent extends ListComponent {
27
27
  itemsLoadedResolve: ((value: any) => void) | undefined;
28
28
  optionsLoaded: boolean | undefined;
29
29
  loadedOptions: any[] | undefined;
30
+ valuesMap: Map<any, any> | undefined;
30
31
  beforeSubmit(): Promise<any>;
31
32
  render(): import("../_classes/field/Field").default;
32
33
  attach(element: any): Promise<void>;
@@ -35,10 +36,13 @@ export default class RadioComponent extends ListComponent {
35
36
  validateValueAvailability(setting: any, value: any): boolean;
36
37
  getValueAsString(value: any, options?: {}): any;
37
38
  setValueAt(index: any, value: any): void;
39
+ prepareValue(item: any, options?: {}): any;
40
+ getValueByInput(input: any): any;
38
41
  loadItems(url: any, search: any, headers: any, options: any, method: any, body: any): void;
39
42
  loadItemsFromMetadata(): void;
40
43
  setItems(items: any): void;
41
44
  setSelectedClasses(): void;
45
+ setMetadata(value: any): void;
42
46
  updateValue(value: any, flags: any): boolean;
43
47
  currentValue: any;
44
48
  }
@@ -2,6 +2,7 @@ import _ from 'lodash';
2
2
  import ListComponent from '../_classes/list/ListComponent';
3
3
  import { Formio } from '../../Formio';
4
4
  import { boolValue, componentValueTypes, getComponentSavedTypes } from '../../utils/utils';
5
+ import { v4 as uuidv4 } from 'uuid';
5
6
  export default class RadioComponent extends ListComponent {
6
7
  static schema(...extend) {
7
8
  return ListComponent.schema({
@@ -142,6 +143,7 @@ export default class RadioComponent extends ListComponent {
142
143
  });
143
144
  this.optionsLoaded = !this.component.dataSrc || this.component.dataSrc === 'values';
144
145
  this.loadedOptions = [];
146
+ this.valuesMap = new Map();
145
147
  if (!this.visible) {
146
148
  this.itemsLoadedResolve();
147
149
  }
@@ -181,9 +183,12 @@ export default class RadioComponent extends ListComponent {
181
183
  if (!_.isString(this.dataValue)) {
182
184
  dataValue = _.toString(this.dataValue);
183
185
  }
184
- if (this.isSelectURL && _.isObject(this.loadedOptions[index].value)) {
185
- const optionValue = this.component.dataType === 'string' ? JSON.stringify(this.loadedOptions[index].value) : this.loadedOptions[index].value;
186
- input.checked = _.isEqual(optionValue, this.dataValue);
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);
187
192
  }
188
193
  else {
189
194
  input.checked = (dataValue === input.value && (input.value || this.component.dataSrc !== 'url'));
@@ -220,9 +225,14 @@ export default class RadioComponent extends ListComponent {
220
225
  let value = this.component.inputType === 'checkbox' ? '' : this.dataValue;
221
226
  this.refs.input.forEach((input, index) => {
222
227
  if (input.checked) {
223
- value = (this.isSelectURL && _.isObject(this.loadedOptions[index].value)) ?
224
- this.loadedOptions[index].value :
225
- input.value;
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;
226
236
  }
227
237
  });
228
238
  return value;
@@ -266,8 +276,8 @@ export default class RadioComponent extends ListComponent {
266
276
  }
267
277
  setValueAt(index, value) {
268
278
  if (this.refs.input && this.refs.input[index] && value !== null && value !== undefined) {
269
- const inputValue = this.refs.input[index].value;
270
- this.refs.input[index].checked = (inputValue === value.toString());
279
+ const inputValue = this.getValueByInput(this.refs.input[index]);
280
+ this.refs.input[index].checked = _.isEqual(inputValue, value);
271
281
  }
272
282
  }
273
283
  get shouldLoad() {
@@ -277,6 +287,23 @@ export default class RadioComponent extends ListComponent {
277
287
  }
278
288
  return super.shouldLoad;
279
289
  }
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
+ }
280
307
  loadItems(url, search, headers, options, method, body) {
281
308
  if (this.optionsLoaded) {
282
309
  this.itemsLoadedResolve();
@@ -327,7 +354,7 @@ export default class RadioComponent extends ListComponent {
327
354
  label: this.itemTemplate(item)
328
355
  };
329
356
  if (_.isEqual(item, this.selectData || _.pick(this.dataValue, _.keys(item)))) {
330
- this.loadedOptions[i].value = this.dataValue;
357
+ this.loadedOptions[i].value = this.prepareValue(this.dataValue, { skipValueProperty: true });
331
358
  }
332
359
  });
333
360
  this.optionsLoaded = true;
@@ -337,12 +364,15 @@ export default class RadioComponent extends ListComponent {
337
364
  const listData = [];
338
365
  items?.forEach((item, i) => {
339
366
  const valueAtProperty = _.get(item, this.component.valueProperty);
340
- this.loadedOptions[i] = {
341
- value: this.component.valueProperty ? valueAtProperty : item,
342
- label: this.component.valueProperty ? this.itemTemplate(item, valueAtProperty) : this.itemTemplate(item, item, i)
343
- };
344
- listData.push(this.templateData[this.component.valueProperty ? valueAtProperty : i]);
345
- const value = this.loadedOptions[i].value;
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
+ }
346
376
  if (!this.isRadio && (_.isObject(value) || _.isBoolean(value) || _.isUndefined(value))) {
347
377
  this.loadedOptions[i].invalid = true;
348
378
  }
@@ -365,7 +395,9 @@ export default class RadioComponent extends ListComponent {
365
395
  const value = this.dataValue;
366
396
  this.refs.wrapper.forEach((wrapper, index) => {
367
397
  const input = this.refs.input[index];
368
- const checked = (input.type === 'checkbox') ? value[input.value] || input.checked : (input.value.toString() === value.toString());
398
+ const checked = (input.type === 'checkbox')
399
+ ? value[input.value] || input.checked
400
+ : _.isEqual(this.normalizeValue(this.getValueByInput(input)), value);
369
401
  if (checked) {
370
402
  //add class to container when selected
371
403
  this.addClass(wrapper, this.optionSelectedClass);
@@ -379,10 +411,25 @@ export default class RadioComponent extends ListComponent {
379
411
  });
380
412
  }
381
413
  }
414
+ setMetadata(value) {
415
+ let key = value;
416
+ if (typeof value !== 'string') {
417
+ const checkedInput = Array.prototype.find.call(this.refs.input, (input => input.type === 'radio' && input.getAttribute('checked')));
418
+ key = checkedInput?.value || key;
419
+ }
420
+ if (this.isSelectURL && this.templateData && this.templateData[key]) {
421
+ const submission = this.root.submission;
422
+ if (!submission.metadata.selectData) {
423
+ submission.metadata.selectData = {};
424
+ }
425
+ _.set(submission.metadata.selectData, this.path, this.templateData[key]);
426
+ }
427
+ }
382
428
  updateValue(value, flags) {
383
429
  const changed = super.updateValue(value, flags);
384
430
  if (changed) {
385
431
  this.setSelectedClasses();
432
+ this.setMetadata(this.dataValue);
386
433
  }
387
434
  if (!flags || !flags.modified || !this.isRadio) {
388
435
  if (changed) {
@@ -438,13 +485,9 @@ export default class RadioComponent extends ListComponent {
438
485
  value = !(!value || value.toString() === 'false');
439
486
  break;
440
487
  }
441
- if (this.isSelectURL && this.templateData && this.templateData[value]) {
442
- const submission = this.root.submission;
443
- if (!submission.metadata.selectData) {
444
- submission.metadata.selectData = {};
445
- }
446
- _.set(submission.metadata.selectData, this.path, this.templateData[value]);
447
- }
448
488
  return super.normalizeValue(value);
449
489
  }
490
+ isSingleInputValue() {
491
+ return true;
492
+ }
450
493
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@formio/js",
3
- "version": "5.0.0-dev.5935.c16c9d9",
3
+ "version": "5.0.0-dev.5936.905c79f",
4
4
  "description": "JavaScript powered Forms with JSON Form Builder",
5
5
  "main": "lib/cjs/index.js",
6
6
  "exports": {