From af552bfbb927266424250c8b199955ecd2954bd4 Mon Sep 17 00:00:00 2001 From: Wiktor Danielewski <63188869+wiktord2000@users.noreply.github.com> Date: Thu, 20 Jun 2024 15:18:29 +0200 Subject: [PATCH] AAE-23165 Not blocking task completion when there's no value selected in required radio buttons widget (#9836) * AAE-23165 Fix * AAE-23165 Update --- .../widgets/core/form-field.model.spec.ts | 84 +++++++++++-------- .../widgets/core/form-field.model.ts | 8 +- 2 files changed, 51 insertions(+), 41 deletions(-) diff --git a/lib/core/src/lib/form/components/widgets/core/form-field.model.spec.ts b/lib/core/src/lib/form/components/widgets/core/form-field.model.spec.ts index ee4826c4e7..ec1afd99dd 100644 --- a/lib/core/src/lib/form/components/widgets/core/form-field.model.spec.ts +++ b/lib/core/src/lib/form/components/widgets/core/form-field.model.spec.ts @@ -22,7 +22,6 @@ import { FormFieldModel } from './form-field.model'; import { FormModel } from './form.model'; describe('FormFieldModel', () => { - it('should store the form reference', () => { const form = new FormModel(); const model = new FormFieldModel(form); @@ -70,7 +69,7 @@ describe('FormFieldModel', () => { expect(field.options).toBeDefined(); expect(field.options.length).toBe(0); - field = new FormFieldModel(new FormModel(), {options: null}); + field = new FormFieldModel(new FormModel(), { options: null }); expect(field.options).toBeDefined(); expect(field.options.length).toBe(0); }); @@ -79,13 +78,13 @@ describe('FormFieldModel', () => { let field = new FormFieldModel(new FormModel(), null); expect(field.params).toEqual({}); - field = new FormFieldModel(new FormModel(), {params: null}); + field = new FormFieldModel(new FormModel(), { params: null }); expect(field.params).toEqual({}); }); it('should update form on every value change', () => { const form = new FormModel(); - const field = new FormFieldModel(form, {id: 'field1'}); + const field = new FormFieldModel(form, { id: 'field1' }); const value = 10; spyOn(field, 'updateForm').and.callThrough(); @@ -107,7 +106,7 @@ describe('FormFieldModel', () => { it('should take own readonly state if form is writable', () => { const form = new FormModel(); - const field = new FormFieldModel(form, {readOnly: true}); + const field = new FormFieldModel(form, { readOnly: true }); expect(form.readOnly).toBeFalsy(); expect(field.readOnly).toBeTruthy(); @@ -251,7 +250,7 @@ describe('FormFieldModel', () => { expect(field.value).toBe('28-04-2017'); }); - it('should set the value to today\'s date when the value is today', () => { + it('should set the value to todays date when the value is today', () => { const form = new FormModel(); const field = new FormFieldModel(form, { fieldType: 'FormFieldRepresentation', @@ -488,9 +487,9 @@ describe('FormFieldModel', () => { const field = new FormFieldModel(new FormModel(), { type: FormFieldTypes.DROPDOWN, options: [ - {id: 'empty', name: 'Choose option...'}, - {id: 'fake-option-2', name: 'fake label 2'}, - {id: 'fake-option-3', name: 'fake label 3'} + { id: 'empty', name: 'Choose option...' }, + { id: 'fake-option-2', name: 'fake label 2' }, + { id: 'fake-option-3', name: 'fake label 3' } ], value: 'fake-option-2' }); @@ -502,9 +501,9 @@ describe('FormFieldModel', () => { 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'} + { 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' @@ -517,8 +516,8 @@ describe('FormFieldModel', () => { const field = new FormFieldModel(new FormModel(), { type: FormFieldTypes.RADIO_BUTTONS, options: [ - {id: 'opt1', name: 'Option 1'}, - {id: 'opt2', name: 'Option 2'} + { id: 'opt1', name: 'Option 1' }, + { id: 'opt2', name: 'Option 2' } ], value: 'opt2' }); @@ -582,8 +581,8 @@ describe('FormFieldModel', () => { id: 'dropdown-2', type: FormFieldTypes.DROPDOWN, options: [ - {id: 'opt1', name: 'Option 1'}, - {id: 'opt2', name: 'Option 2'} + { id: 'opt1', name: 'Option 1' }, + { id: 'opt2', name: 'Option 2' } ] }); @@ -597,8 +596,8 @@ describe('FormFieldModel', () => { id: 'radio-1', type: FormFieldTypes.RADIO_BUTTONS, options: [ - {id: 'opt1', name: 'Option 1'}, - {id: 'opt2', name: 'Option 2'} + { id: 'opt1', name: 'Option 1' }, + { id: 'opt2', name: 'Option 2' } ] }); @@ -606,19 +605,34 @@ describe('FormFieldModel', () => { expect(form.values['radio-1']).toEqual(field.options[1]); }); - it('radio button value should be null when no default is set', () => { + 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'} + { id: 'opt1', name: 'Option 1' }, + { id: 'opt2', name: 'Option 2' } ] }); field.value = 'missing'; - expect(form.values['radio-2']).toBeUndefined(); + 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', () => { @@ -641,8 +655,8 @@ describe('FormFieldModel', () => { id: 'dropdown-happy', type: FormFieldTypes.DROPDOWN, options: [ - {id: 'opt1', name: 'Option 1'}, - {id: 'opt2', name: 'Option 2'} + { id: 'opt1', name: 'Option 1' }, + { id: 'opt2', name: 'Option 2' } ] }); @@ -714,8 +728,8 @@ describe('FormFieldModel', () => { required: false, readOnly: true, options: [ - {id: 'opt1', name: 'Option 1'}, - {id: 'opt2', name: 'Option 2'} + { id: 'opt1', name: 'Option 1' }, + { id: 'opt2', name: 'Option 2' } ] }); field.updateForm(); @@ -737,8 +751,8 @@ describe('FormFieldModel', () => { restIdProperty: 'fake-id-property', restLabelProperty: 'fake-label-property', options: [ - {id: 'opt1', name: 'Option 1'}, - {id: 'opt2', name: 'Option 2'} + { id: 'opt1', name: 'Option 1' }, + { id: 'opt2', name: 'Option 2' } ] }); field.updateForm(); @@ -759,8 +773,8 @@ describe('FormFieldModel', () => { restUrl: 'fake-url-just-to-show', optionType: 'rest', options: [ - {id: 'opt1', name: 'Option 1'}, - {id: 'opt2', name: 'Option 2'} + { id: 'opt1', name: 'Option 1' }, + { id: 'opt2', name: 'Option 2' } ] }); field.updateForm(); @@ -783,8 +797,8 @@ describe('FormFieldModel', () => { restLabelProperty: 'banLabel', optionType: 'rest', options: [ - {id: 'opt1', name: 'Option 1'}, - {id: 'opt2', name: 'Option 2'} + { id: 'opt1', name: 'Option 1' }, + { id: 'opt2', name: 'Option 2' } ] }); field.updateForm(); @@ -805,8 +819,8 @@ describe('FormFieldModel', () => { restUrl: '', optionType: 'rest', options: [ - {id: 'opt1', name: 'Option 1'}, - {id: 'opt2', name: 'Option 2'} + { id: 'opt1', name: 'Option 1' }, + { id: 'opt2', name: 'Option 2' } ] }); field.updateForm(); @@ -840,7 +854,6 @@ describe('FormFieldModel', () => { }); describe('variables', () => { - let form: FormModel; beforeEach(() => { @@ -907,7 +920,6 @@ describe('FormFieldModel', () => { expect(field.value).toBe('default hello'); }); - }); it('should validate readOnly field if it is validatable', () => { diff --git a/lib/core/src/lib/form/components/widgets/core/form-field.model.ts b/lib/core/src/lib/form/components/widgets/core/form-field.model.ts index 981d8bb920..4ee7d36069 100644 --- a/lib/core/src/lib/form/components/widgets/core/form-field.model.ts +++ b/lib/core/src/lib/form/components/widgets/core/form-field.model.ts @@ -406,10 +406,8 @@ export class FormFieldModel extends FormWidgetModel { break; } case FormFieldTypes.RADIO_BUTTONS: { - const radioButton: FormFieldOption[] = this.options.filter((opt) => opt.id === this.value); - if (radioButton.length > 0) { - this.form.values[this.id] = radioButton[0]; - } + const radioButton: FormFieldOption = this.options.find((opt) => opt.id === this.value); + this.form.values[this.id] = radioButton || null; break; } case FormFieldTypes.UPLOAD: { @@ -472,7 +470,7 @@ export class FormFieldModel extends FormWidgetModel { case FormFieldTypes.DECIMAL: { this.form.values[this.id] = parseFloat(this.value); break; - }; + } case FormFieldTypes.BOOLEAN: { this.form.values[this.id] = this.value !== null && this.value !== undefined ? this.value : false; break;