mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[AAE-5971] [Form] Support for multi select drop down (#7321)
* [AAE-5971] [ADF][Form-cloud] Support for multi select drop down * * fix drop down validation * * minor changes * * fix tests * * minor changes * * fix comments * * fix e2e
This commit is contained in:
@@ -71,6 +71,9 @@ describe('FormFieldValidator', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.DROPDOWN,
|
||||
value: '<empty>',
|
||||
options: [
|
||||
{id: 'empty', name: 'Choose option...'}
|
||||
],
|
||||
hasEmptyValue: true,
|
||||
required: true
|
||||
});
|
||||
@@ -82,6 +85,22 @@ describe('FormFieldValidator', () => {
|
||||
expect(validator.validate(field)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should fail for dropdown with zero selection', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.DROPDOWN,
|
||||
value: [],
|
||||
hasEmptyValue: true,
|
||||
required: true,
|
||||
selectionType: 'multiple'
|
||||
});
|
||||
|
||||
field.emptyOption = <FormFieldOption> { id: 'empty' };
|
||||
expect(validator.validate(field)).toBeFalsy();
|
||||
|
||||
field.value = [];
|
||||
expect(validator.validate(field)).toBe(false);
|
||||
});
|
||||
|
||||
it('should fail for radio buttons', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.RADIO_BUTTONS,
|
||||
|
@@ -59,6 +59,10 @@ export class RequiredFieldValidator implements FormFieldValidator {
|
||||
if (this.isSupported(field) && field.isVisible) {
|
||||
|
||||
if (field.type === FormFieldTypes.DROPDOWN) {
|
||||
if (field.hasMultipleValues) {
|
||||
return !!field.value.length;
|
||||
}
|
||||
|
||||
if (field.hasEmptyValue && field.emptyOption) {
|
||||
if (field.value === field.emptyOption.id) {
|
||||
return false;
|
||||
|
@@ -460,13 +460,29 @@ describe('FormFieldModel', () => {
|
||||
const field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.DROPDOWN,
|
||||
options: [
|
||||
{id: 'fake-option-1', name: 'fake label 1'},
|
||||
{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'
|
||||
});
|
||||
expect(field.getOptionName()).toBe('fake label 2');
|
||||
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);
|
||||
});
|
||||
|
||||
it('should parse and resolve radio button value', () => {
|
||||
|
@@ -71,6 +71,7 @@ export class FormFieldModel extends FormWidgetModel {
|
||||
enableFractions: boolean = false;
|
||||
currency: string = null;
|
||||
dateDisplayFormat: string = this.defaultDateFormat;
|
||||
selectionType: 'single' | 'multiple' = null;
|
||||
|
||||
// container model members
|
||||
numberOfColumns: number = 1;
|
||||
@@ -115,6 +116,10 @@ export class FormFieldModel extends FormWidgetModel {
|
||||
return this._isValid;
|
||||
}
|
||||
|
||||
get hasMultipleValues() {
|
||||
return this.selectionType === 'multiple';
|
||||
}
|
||||
|
||||
markAsInvalid() {
|
||||
this._isValid = false;
|
||||
}
|
||||
@@ -172,6 +177,7 @@ export class FormFieldModel extends FormWidgetModel {
|
||||
this._value = this.parseValue(json);
|
||||
this.validationSummary = new ErrorMessageModel();
|
||||
this.tooltip = json.tooltip;
|
||||
this.selectionType = json.selectionType;
|
||||
|
||||
if (json.placeholder && json.placeholder !== '' && json.placeholder !== 'null') {
|
||||
this.placeholder = json.placeholder;
|
||||
@@ -206,8 +212,13 @@ export class FormFieldModel extends FormWidgetModel {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.hasEmptyValue && this.options && this.options.length > 0) {
|
||||
this.emptyOption = this.options[0];
|
||||
const emptyOption = Array.isArray(this.options) ? this.options.find(({ id }) => id === 'empty') : undefined;
|
||||
if (this.hasEmptyValue === undefined) {
|
||||
this.hasEmptyValue = json?.hasEmptyValue ?? !!emptyOption;
|
||||
}
|
||||
|
||||
if (this.options && this.options.length > 0 && this.hasEmptyValue) {
|
||||
this.emptyOption = emptyOption;
|
||||
}
|
||||
|
||||
this.updateForm();
|
||||
@@ -291,6 +302,10 @@ export class FormFieldModel extends FormWidgetModel {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.hasMultipleValues) {
|
||||
value = Array.isArray(json.value) ? json.value : [];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -344,9 +359,17 @@ export class FormFieldModel extends FormWidgetModel {
|
||||
This is needed due to Activiti reading dropdown values as string
|
||||
but saving back as object: { id: <id>, name: <name> }
|
||||
*/
|
||||
if (this.value === 'empty' || this.value === '') {
|
||||
this.form.values[this.id] = {};
|
||||
} else {
|
||||
if (Array.isArray(this.value)) {
|
||||
this.form.values[this.id] = this.value;
|
||||
break;
|
||||
}
|
||||
|
||||
if (typeof this.value === 'string') {
|
||||
if (this.value === 'empty' || this.value === '') {
|
||||
this.form.values[this.id] = {};
|
||||
break;
|
||||
}
|
||||
|
||||
const entry: FormFieldOption[] = this.options.filter((opt) => opt.id === this.value);
|
||||
if (entry.length > 0) {
|
||||
this.form.values[this.id] = entry[0];
|
||||
|
@@ -385,7 +385,7 @@ export class FormModel {
|
||||
|
||||
addValuesNotPresent(valuesToSetIfNotPresent: FormValues) {
|
||||
this.getFormFields().forEach(field => {
|
||||
if (valuesToSetIfNotPresent[field.id] && (!this.values[field.id] || this.isEmptyDropdownOption(field.id))) {
|
||||
if (valuesToSetIfNotPresent[field.id] && (!this.values[field.id] || this.isValidDropDown(field.id))) {
|
||||
this.values[field.id] = valuesToSetIfNotPresent[field.id];
|
||||
field.json.value = this.values[field.id];
|
||||
field.value = field.parseValue(field.json);
|
||||
@@ -393,8 +393,12 @@ export class FormModel {
|
||||
});
|
||||
}
|
||||
|
||||
private isEmptyDropdownOption(key: string): boolean {
|
||||
if (this.getFieldById(key) && (this.getFieldById(key).type === FormFieldTypes.DROPDOWN)) {
|
||||
private isValidDropDown(key: string): boolean {
|
||||
const field = this.getFieldById(key);
|
||||
if (field.type === FormFieldTypes.DROPDOWN) {
|
||||
if (field.hasMultipleValues) {
|
||||
return Array.isArray(this.values[key]);
|
||||
}
|
||||
return typeof this.values[key] === 'string' ? this.values[key] === 'empty' : Object.keys(this.values[key]).length === 0;
|
||||
}
|
||||
return false;
|
||||
|
Reference in New Issue
Block a user