mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
AAE-22948 Radio buttons should not display errors / call apis when they're in readOnly state (#9946)
* AAE-22948 Update form-field.model * AAE-22948 Update radio-buttons.widget * AAE-22948 Update radio-buttons-cloud.widget * AAE-22948 Update radio-buttons-cloud * AAE-22948 Update radio-buttons * AAE-22948 Improvements * AAE-22948 Small fix * AAE-22948 Fix unit
This commit is contained in:
committed by
GitHub
parent
63d017350d
commit
5d969ccca5
@@ -112,67 +112,111 @@ describe('FormFieldModel', () => {
|
||||
expect(field.readOnly).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should parse and leave dropdown value as is', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.DROPDOWN,
|
||||
options: [],
|
||||
value: 'deferred'
|
||||
describe('dropdown field model instantiation', () => {
|
||||
it('should add value (selected option) to field options if NOT present', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.DROPDOWN,
|
||||
options: [],
|
||||
value: { id: 'id_one', name: 'One' }
|
||||
});
|
||||
|
||||
expect(field.options).toEqual([{ id: 'id_one', name: 'One' }]);
|
||||
expect(field.value).toEqual('id_one');
|
||||
});
|
||||
|
||||
expect(field.value).toBe('deferred');
|
||||
});
|
||||
it('should add value (selected options) to field options if NOT present (multiple selection)', () => {
|
||||
const selectedOptions = [
|
||||
{ id: 'id_one', name: 'One' },
|
||||
{ id: 'id_two', name: 'Two' }
|
||||
];
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.DROPDOWN,
|
||||
options: [],
|
||||
value: selectedOptions,
|
||||
selectionType: 'multiple'
|
||||
});
|
||||
|
||||
it('should add value to field options if NOT present', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.DROPDOWN,
|
||||
options: [],
|
||||
value: { id: 'id_one', name: 'One' }
|
||||
expect(field.options).toEqual(selectedOptions);
|
||||
expect(field.value).toEqual(selectedOptions);
|
||||
});
|
||||
|
||||
expect(field.options).toEqual([{ id: 'id_one', name: 'One' }]);
|
||||
expect(field.value).toEqual('id_one');
|
||||
});
|
||||
it('should assign "empty" option as value if value is null and "empty" option is present in options', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.DROPDOWN,
|
||||
options: [
|
||||
{ id: 'empty', name: 'Chose one...' },
|
||||
{ id: 'one', name: 'One' }
|
||||
],
|
||||
value: null
|
||||
});
|
||||
|
||||
it('should assign "empty" option as value if value is null and "empty" option is present in options', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.DROPDOWN,
|
||||
options: [
|
||||
{ id: 'empty', name: 'Chose one...' },
|
||||
expect(field.hasEmptyValue).toBe(true);
|
||||
expect(field.emptyOption).toEqual({ id: 'empty', name: 'Chose one...' });
|
||||
expect(field.value).toEqual('empty');
|
||||
});
|
||||
|
||||
it('should set hasEmptyValue to true if "empty" option is present in options', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.DROPDOWN,
|
||||
options: [{ id: 'empty', name: 'Choose one...' }],
|
||||
value: null
|
||||
});
|
||||
|
||||
expect(field.hasEmptyValue).toBe(true);
|
||||
expect(field.emptyOption).toEqual({ id: 'empty', name: 'Choose one...' });
|
||||
});
|
||||
|
||||
it('should add default "empty" option to the options if hasEmptyValue is true but "empty" option is not present', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.DROPDOWN,
|
||||
options: [{ id: 'one', name: 'One' }],
|
||||
value: null,
|
||||
hasEmptyValue: true
|
||||
});
|
||||
|
||||
expect(field.hasEmptyValue).toBe(true);
|
||||
expect(field.emptyOption).toEqual({ id: 'empty', name: 'Choose one...' });
|
||||
expect(field.options).toEqual([
|
||||
{ id: 'empty', name: 'Choose one...' },
|
||||
{ id: 'one', name: 'One' }
|
||||
],
|
||||
value: null
|
||||
]);
|
||||
});
|
||||
|
||||
expect(field.hasEmptyValue).toBe(true);
|
||||
expect(field.emptyOption).toEqual({ id: 'empty', name: 'Chose one...' });
|
||||
expect(field.value).toEqual('empty');
|
||||
});
|
||||
|
||||
it('should set hasEmptyValue to true if "empty" option is present in options', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.DROPDOWN,
|
||||
options: [{ id: 'empty', name: 'Choose one...' }],
|
||||
value: null
|
||||
it('should parse dropdown with multiple options', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.DROPDOWN,
|
||||
options: [
|
||||
{ id: 'fake-option-1', name: 'fake label 1' },
|
||||
{ id: 'fake-option-2', name: 'fake label 2' },
|
||||
{ id: 'fake-option-3', name: 'fake label 3' }
|
||||
],
|
||||
value: [],
|
||||
selectionType: 'multiple'
|
||||
});
|
||||
expect(field.hasMultipleValues).toBe(true);
|
||||
expect(field.hasEmptyValue).toBe(false);
|
||||
});
|
||||
|
||||
expect(field.hasEmptyValue).toBe(true);
|
||||
expect(field.emptyOption).toEqual({ id: 'empty', name: 'Choose one...' });
|
||||
});
|
||||
describe('should leave not resolved value (in case of delayed options)', () => {
|
||||
it('when string', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.DROPDOWN,
|
||||
options: [],
|
||||
value: 'delayed-option-id'
|
||||
});
|
||||
|
||||
it('should add default "empty" option to the options if hasEmptyValue is true but "empty" option is not present', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.DROPDOWN,
|
||||
options: [{ id: 'one', name: 'One' }],
|
||||
value: null,
|
||||
hasEmptyValue: true
|
||||
expect(field.value).toBe('delayed-option-id');
|
||||
});
|
||||
|
||||
it('when object', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.DROPDOWN,
|
||||
options: [],
|
||||
value: { id: 'delayed-option-id', name: 'Delayed option' }
|
||||
});
|
||||
expect(field.value).toBe('delayed-option-id');
|
||||
});
|
||||
});
|
||||
|
||||
expect(field.hasEmptyValue).toBe(true);
|
||||
expect(field.emptyOption).toEqual({ id: 'empty', name: 'Choose one...' });
|
||||
expect(field.options).toEqual([
|
||||
{ id: 'empty', name: 'Choose one...' },
|
||||
{ id: 'one', name: 'One' }
|
||||
]);
|
||||
});
|
||||
|
||||
it('should store the date value as Date object if the display format is missing', () => {
|
||||
@@ -502,41 +546,93 @@ describe('FormFieldModel', () => {
|
||||
expect(field.hasEmptyValue).toBe(true);
|
||||
});
|
||||
|
||||
it('should parse dropdown with multiple options', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.DROPDOWN,
|
||||
options: [
|
||||
{ id: 'fake-option-1', name: 'fake label 1' },
|
||||
{ id: 'fake-option-2', name: 'fake label 2' },
|
||||
{ id: 'fake-option-3', name: 'fake label 3' }
|
||||
],
|
||||
value: [],
|
||||
selectionType: 'multiple'
|
||||
});
|
||||
expect(field.hasMultipleValues).toBe(true);
|
||||
expect(field.hasEmptyValue).toBe(false);
|
||||
});
|
||||
describe('radio buttons field model instantiation', () => {
|
||||
const mockOptions = [
|
||||
{ id: 'opt1', name: 'Option 1' },
|
||||
{ id: 'opt2', name: 'Option 2' }
|
||||
];
|
||||
|
||||
it('should parse and resolve radio button value', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.RADIO_BUTTONS,
|
||||
options: [
|
||||
{ id: 'opt1', name: 'Option 1' },
|
||||
{ id: 'opt2', name: 'Option 2' }
|
||||
],
|
||||
value: 'opt2'
|
||||
describe('should parse and resolve selected option id in case of', () => {
|
||||
it('string - id', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.RADIO_BUTTONS,
|
||||
options: mockOptions,
|
||||
value: 'opt2'
|
||||
});
|
||||
|
||||
expect(field.value).toBe('opt2');
|
||||
expect(field.options).toEqual(mockOptions);
|
||||
});
|
||||
|
||||
it('string - name', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.RADIO_BUTTONS,
|
||||
options: mockOptions,
|
||||
value: 'Option 1'
|
||||
});
|
||||
|
||||
expect(field.value).toBe('opt1');
|
||||
expect(field.options).toEqual(mockOptions);
|
||||
});
|
||||
|
||||
it('object with id and name', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.RADIO_BUTTONS,
|
||||
options: mockOptions,
|
||||
value: { id: 'opt2', name: 'Option 2' }
|
||||
});
|
||||
|
||||
expect(field.value).toBe('opt2');
|
||||
expect(field.options).toEqual(mockOptions);
|
||||
});
|
||||
|
||||
it('object with id, name and options', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.RADIO_BUTTONS,
|
||||
options: [{ id: 'lower-priority-opt', name: 'Lower Priority Option' }],
|
||||
value: {
|
||||
id: 'opt2',
|
||||
name: 'Option 2',
|
||||
options: mockOptions
|
||||
}
|
||||
});
|
||||
|
||||
expect(field.value).toBe('opt2');
|
||||
expect(field.options).toEqual(mockOptions);
|
||||
});
|
||||
});
|
||||
|
||||
expect(field.value).toBe('opt2');
|
||||
});
|
||||
describe('should leave not resolved value (in case of delayed options)', () => {
|
||||
it('when string', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.RADIO_BUTTONS,
|
||||
options: [],
|
||||
value: 'delayed-option-id'
|
||||
});
|
||||
|
||||
it('should parse and leave radio button value as is', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.RADIO_BUTTONS,
|
||||
options: [],
|
||||
value: 'deferred-radio'
|
||||
expect(field.value).toBe('delayed-option-id');
|
||||
});
|
||||
|
||||
it('when object', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.RADIO_BUTTONS,
|
||||
options: [],
|
||||
value: { id: 'delayed-option-id', name: 'Delayed option' }
|
||||
});
|
||||
expect(field.value).toBe('delayed-option-id');
|
||||
});
|
||||
});
|
||||
|
||||
it('should add value (selected option) to field options if NOT present', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.RADIO_BUTTONS,
|
||||
options: [],
|
||||
value: { id: 'opt1', name: 'Option 1' }
|
||||
});
|
||||
|
||||
expect(field.options).toEqual([{ id: 'opt1', name: 'Option 1' }]);
|
||||
expect(field.value).toEqual('opt1');
|
||||
});
|
||||
expect(field.value).toBe('deferred-radio');
|
||||
});
|
||||
|
||||
it('should parse boolean value when set to "true"', () => {
|
||||
@@ -595,49 +691,94 @@ describe('FormFieldModel', () => {
|
||||
expect(form.values['dropdown-2']).toEqual(field.options[1]);
|
||||
});
|
||||
|
||||
it('should update form with radio button value', () => {
|
||||
const form = new FormModel();
|
||||
const field = new FormFieldModel(form, {
|
||||
id: 'radio-1',
|
||||
type: FormFieldTypes.RADIO_BUTTONS,
|
||||
options: [
|
||||
{ id: 'opt1', name: 'Option 1' },
|
||||
{ id: 'opt2', name: 'Option 2' }
|
||||
]
|
||||
describe('radio buttons field value change', () => {
|
||||
let form: FormModel;
|
||||
let field: FormFieldModel;
|
||||
|
||||
describe('when rest type', () => {
|
||||
beforeEach(() => {
|
||||
form = new FormModel();
|
||||
field = new FormFieldModel(form, {
|
||||
id: 'rest-radio',
|
||||
type: FormFieldTypes.RADIO_BUTTONS,
|
||||
optionType: 'rest',
|
||||
options: [
|
||||
{ id: 'restOpt1', name: 'Rest Option 1' },
|
||||
{ id: 'restOpt2', name: 'Rest Option 2' }
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
it('should update form with selected option and options from which we chose', () => {
|
||||
field.value = 'restOpt2';
|
||||
|
||||
expect(form.values['rest-radio']).toEqual({
|
||||
id: 'restOpt2',
|
||||
name: 'Rest Option 2',
|
||||
options: field.options
|
||||
});
|
||||
});
|
||||
|
||||
describe('should update form with selected option properties set to null and options from which we chose', () => {
|
||||
it('when value does NOT match any option', () => {
|
||||
field.value = 'not_exist';
|
||||
|
||||
expect(form.values['rest-radio']).toEqual({
|
||||
id: null,
|
||||
name: null,
|
||||
options: field.options
|
||||
});
|
||||
});
|
||||
|
||||
it('when radio button value is null', () => {
|
||||
field.value = null;
|
||||
|
||||
expect(form.values['rest-radio']).toEqual({
|
||||
id: null,
|
||||
name: null,
|
||||
options: field.options
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
field.value = 'opt2';
|
||||
expect(form.values['radio-1']).toEqual(field.options[1]);
|
||||
});
|
||||
describe('when manual type', () => {
|
||||
beforeEach(() => {
|
||||
form = new FormModel();
|
||||
field = new FormFieldModel(form, {
|
||||
id: 'manual-radio',
|
||||
type: FormFieldTypes.RADIO_BUTTONS,
|
||||
optionType: 'manual',
|
||||
options: [
|
||||
{ id: 'opt1', name: 'Static Option 1' },
|
||||
{ id: 'opt2', name: 'Static Option 2' }
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
it('should update form with null when radio button value does NOT match any option', () => {
|
||||
const form = new FormModel();
|
||||
const field = new FormFieldModel(form, {
|
||||
id: 'radio-2',
|
||||
type: FormFieldTypes.RADIO_BUTTONS,
|
||||
options: [
|
||||
{ id: 'opt1', name: 'Option 1' },
|
||||
{ id: 'opt2', name: 'Option 2' }
|
||||
]
|
||||
it('should update form with selected option', () => {
|
||||
field.value = 'opt1';
|
||||
|
||||
expect(form.values['manual-radio']).toEqual({
|
||||
id: 'opt1',
|
||||
name: 'Static Option 1'
|
||||
});
|
||||
});
|
||||
|
||||
describe('should update form with selected option set to null', () => {
|
||||
it('when value does NOT match any option', () => {
|
||||
field.value = 'not_exist';
|
||||
|
||||
expect(form.values['manual-radio']).toEqual(null);
|
||||
});
|
||||
|
||||
it('when radio button value is null', () => {
|
||||
field.value = null;
|
||||
|
||||
expect(form.values['manual-radio']).toEqual(null);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
field.value = 'missing';
|
||||
expect(form.values['radio-2']).toBe(null);
|
||||
});
|
||||
|
||||
it('should update form with null when radio button value is null', () => {
|
||||
const form = new FormModel();
|
||||
const field = new FormFieldModel(form, {
|
||||
id: 'radio-2',
|
||||
type: FormFieldTypes.RADIO_BUTTONS,
|
||||
options: [
|
||||
{ id: 'opt1', name: 'Option 1' },
|
||||
{ id: 'opt2', name: 'Option 2' }
|
||||
]
|
||||
});
|
||||
|
||||
field.value = null;
|
||||
expect(form.values['radio-2']).toBe(null);
|
||||
});
|
||||
|
||||
it('should not update form with display-only field value', () => {
|
||||
|
@@ -322,7 +322,7 @@ export class FormFieldModel extends FormWidgetModel {
|
||||
}
|
||||
|
||||
if (this.isValidOption(value)) {
|
||||
this.addOption(value);
|
||||
this.addOption({ id: value.id, name: value.name });
|
||||
return value.id;
|
||||
}
|
||||
|
||||
@@ -341,14 +341,27 @@ export class FormFieldModel extends FormWidgetModel {
|
||||
but saving back as object: { id: <id>, name: <name> }
|
||||
*/
|
||||
if (json.type === FormFieldTypes.RADIO_BUTTONS) {
|
||||
if (json.value?.options) {
|
||||
this.options = this.parseValidOptions(json.value.options);
|
||||
}
|
||||
|
||||
// Activiti has a bug with default radio button value where initial selection passed as `name` value
|
||||
// so try resolving current one with a fallback to first entry via name or id
|
||||
// TODO: needs to be reported and fixed at Activiti side
|
||||
const entry: FormFieldOption[] = this.options.filter(
|
||||
const matchingOption = this.options.find(
|
||||
(opt) => opt.id === value || opt.name === value || (value && (opt.id === value.id || opt.name === value.name))
|
||||
);
|
||||
|
||||
return entry.length > 0 ? entry[0].id : value;
|
||||
if (matchingOption) {
|
||||
return matchingOption.id;
|
||||
}
|
||||
|
||||
if (this.isValidOption(value)) {
|
||||
this.addOption({ id: value.id, name: value.name });
|
||||
return value.id;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
if (this.isDateField(json) || this.isDateTimeField(json)) {
|
||||
@@ -414,7 +427,15 @@ export class FormFieldModel extends FormWidgetModel {
|
||||
}
|
||||
case FormFieldTypes.RADIO_BUTTONS: {
|
||||
const radioButton: FormFieldOption = this.options.find((opt) => opt.id === this.value);
|
||||
this.form.values[this.id] = radioButton || null;
|
||||
|
||||
if (this.optionType === 'rest') {
|
||||
this.form.values[this.id] = radioButton
|
||||
? { ...radioButton, options: this.options }
|
||||
: { id: null, name: null, options: this.options };
|
||||
} else {
|
||||
this.form.values[this.id] = radioButton ? { ...radioButton } : null;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case FormFieldTypes.UPLOAD: {
|
||||
|
Reference in New Issue
Block a user