mirror of
https://github.com/ceph/ceph
synced 2025-02-24 11:37:37 +00:00
mgr/dashboard: CdFormGroup
CdFormGroup extends 'FormGroup' with a few new methods that will help form development. Signed-off-by: Stephan Müller <smueller@suse.com>
This commit is contained in:
parent
544bc3ea58
commit
083865dc93
@ -0,0 +1,191 @@
|
||||
import { AbstractControl, FormControl, FormGroup, NgForm } from '@angular/forms';
|
||||
|
||||
import { CdFormGroup } from './cd-form-group';
|
||||
|
||||
describe('FormsHelperService', () => {
|
||||
let form: CdFormGroup;
|
||||
|
||||
const createTestForm = (controlName: string, value: any): FormGroup =>
|
||||
new FormGroup({
|
||||
[controlName]: new FormControl(value)
|
||||
});
|
||||
|
||||
describe('test get and getValue in nested forms', () => {
|
||||
let formA: FormGroup;
|
||||
let formB: FormGroup;
|
||||
let formC: FormGroup;
|
||||
|
||||
beforeEach(() => {
|
||||
formA = createTestForm('a', 'a');
|
||||
formB = createTestForm('b', 'b');
|
||||
formC = createTestForm('c', 'c');
|
||||
form = new CdFormGroup({
|
||||
formA: formA,
|
||||
formB: formB,
|
||||
formC: formC
|
||||
});
|
||||
});
|
||||
|
||||
it('should find controls out of every form', () => {
|
||||
expect(form.get('a')).toBe(formA.get('a'));
|
||||
expect(form.get('b')).toBe(formB.get('b'));
|
||||
expect(form.get('c')).toBe(formC.get('c'));
|
||||
});
|
||||
|
||||
it('should throw an error if element could be found', () => {
|
||||
expect(() => form.get('d')).toThrowError('Control \'d\' could not be found!');
|
||||
expect(() => form.get('sth')).toThrowError('Control \'sth\' could not be found!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('CdFormGroup tests', () => {
|
||||
let x, nested, a, c;
|
||||
|
||||
beforeEach(() => {
|
||||
a = new FormControl('a');
|
||||
x = new CdFormGroup({
|
||||
a: a
|
||||
});
|
||||
nested = new CdFormGroup({
|
||||
lev1: new CdFormGroup({
|
||||
lev2: new FormControl('lev2')
|
||||
})
|
||||
});
|
||||
c = createTestForm('c', 'c');
|
||||
form = new CdFormGroup({
|
||||
nested: nested,
|
||||
cdform: x,
|
||||
b: new FormControl('b'),
|
||||
formC: c
|
||||
});
|
||||
});
|
||||
|
||||
it('should return single value from "a" control in not nested form "x"', () => {
|
||||
expect(x.get('a')).toBe(a);
|
||||
expect(x.getValue('a')).toBe('a');
|
||||
});
|
||||
|
||||
it('should return control "a" out of form "x" in nested form', () => {
|
||||
expect(form.get('a')).toBe(a);
|
||||
expect(form.getValue('a')).toBe('a');
|
||||
});
|
||||
|
||||
it('should return value "b" that is not nested in nested form', () => {
|
||||
expect(form.getValue('b')).toBe('b');
|
||||
});
|
||||
|
||||
it('return value "c" out of normal form group "c" in nested form', () => {
|
||||
expect(form.getValue('c')).toBe('c');
|
||||
});
|
||||
|
||||
it('should return "lev2" value', () => {
|
||||
expect(form.getValue('lev2')).toBe('lev2');
|
||||
});
|
||||
|
||||
it('should nested throw an error if control could not be found', () => {
|
||||
expect(() => form.get('d')).toThrowError('Control \'d\' could not be found!');
|
||||
expect(() => form.getValue('sth')).toThrowError('Control \'sth\' could not be found!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('test different values for getValue', () => {
|
||||
beforeEach(() => {
|
||||
form = new CdFormGroup({
|
||||
form_undefined: createTestForm('undefined', undefined),
|
||||
form_null: createTestForm('null', null),
|
||||
form_emptyObject: createTestForm('emptyObject', {}),
|
||||
form_filledObject: createTestForm('filledObject', { notEmpty: 1 }),
|
||||
form_number0: createTestForm('number0', 0),
|
||||
form_number1: createTestForm('number1', 1),
|
||||
form_emptyString: createTestForm('emptyString', ''),
|
||||
form_someString1: createTestForm('someString1', 's'),
|
||||
form_someString2: createTestForm('someString2', 'sth'),
|
||||
form_floating: createTestForm('floating', 0.1),
|
||||
form_false: createTestForm('false', false),
|
||||
form_true: createTestForm('true', true)
|
||||
});
|
||||
});
|
||||
|
||||
it('returns objects', () => {
|
||||
expect(form.getValue('null')).toBe(null);
|
||||
expect(form.getValue('emptyObject')).toEqual({});
|
||||
expect(form.getValue('filledObject')).toEqual({ notEmpty: 1 });
|
||||
});
|
||||
|
||||
it('returns set numbers', () => {
|
||||
expect(form.getValue('number0')).toBe(0);
|
||||
expect(form.getValue('number1')).toBe(1);
|
||||
expect(form.getValue('floating')).toBe(0.1);
|
||||
});
|
||||
|
||||
it('returns strings that are not empty', () => {
|
||||
expect(form.getValue('someString1')).toBe('s');
|
||||
expect(form.getValue('someString2')).toBe('sth');
|
||||
});
|
||||
|
||||
it('returns booleans', () => {
|
||||
expect(form.getValue('true')).toBe(true);
|
||||
expect(form.getValue('false')).toBe(false);
|
||||
});
|
||||
|
||||
it('returns null if control was set as undefined', () => {
|
||||
expect(form.getValue('undefined')).toBe(null);
|
||||
});
|
||||
|
||||
it('returns a falsy value for empty string, null, undefined, false and 0', () => {
|
||||
expect(form.getValue('emptyString')).toBe(false);
|
||||
expect(form.getValue('false')).toBeFalsy();
|
||||
expect(form.getValue('null')).toBeFalsy();
|
||||
expect(form.getValue('number0')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('test _filterValue', () => {
|
||||
expect(form._filterValue(0)).toBe(true);
|
||||
expect(form._filterValue(null)).toBe(true);
|
||||
expect(form._filterValue(false)).toBe(true);
|
||||
expect(form._filterValue('')).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('should test showError', () => {
|
||||
let formDir: NgForm;
|
||||
let test: AbstractControl;
|
||||
|
||||
beforeEach(() => {
|
||||
formDir = new NgForm([], []);
|
||||
form = new CdFormGroup({
|
||||
test_form: createTestForm('test', '')
|
||||
});
|
||||
test = form.get('test');
|
||||
test.setErrors({ someError: 'failed' });
|
||||
});
|
||||
|
||||
it('should not show an error if not dirty and not submitted', () => {
|
||||
expect(form.showError('test', formDir)).toBe(false);
|
||||
});
|
||||
|
||||
it('should show an error if dirty', () => {
|
||||
test.markAsDirty();
|
||||
expect(form.showError('test', formDir)).toBe(true);
|
||||
});
|
||||
|
||||
it('should show an error if submitted', () => {
|
||||
expect(form.showError('test', <NgForm>{ submitted: true })).toBe(true);
|
||||
});
|
||||
|
||||
it('should not show an error if no error exits', () => {
|
||||
test.setErrors(null);
|
||||
expect(form.showError('test', <NgForm>{ submitted: true })).toBe(false);
|
||||
test.markAsDirty();
|
||||
expect(form.showError('test', formDir)).toBe(false);
|
||||
});
|
||||
|
||||
it('should not show error if the given error is not there', () => {
|
||||
expect(form.showError('test', <NgForm>{ submitted: true }, 'someOtherError')).toBe(false);
|
||||
});
|
||||
|
||||
it('should show error if the given error is there', () => {
|
||||
expect(form.showError('test', <NgForm>{ submitted: true }, 'someError')).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,95 @@
|
||||
import {
|
||||
AbstractControl,
|
||||
AbstractControlOptions,
|
||||
AsyncValidatorFn,
|
||||
FormGroup,
|
||||
NgForm,
|
||||
ValidatorFn
|
||||
} from '@angular/forms';
|
||||
|
||||
/**
|
||||
* CdFormGroup extends FormGroup with a few new methods that will help form development.
|
||||
*/
|
||||
export class CdFormGroup extends FormGroup {
|
||||
constructor(
|
||||
public controls: { [key: string]: AbstractControl },
|
||||
validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null,
|
||||
asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null
|
||||
) {
|
||||
super(controls, validatorOrOpts, asyncValidator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a control out of any control even if its nested in other CdFormGroups or a FormGroup
|
||||
*
|
||||
* @param {string} controlName
|
||||
* @returns {AbstractControl}
|
||||
*/
|
||||
get(controlName: string): AbstractControl {
|
||||
const control = this._get(controlName);
|
||||
if (!control) {
|
||||
throw new Error(`Control '${controlName}' could not be found!`);
|
||||
}
|
||||
return control;
|
||||
}
|
||||
|
||||
_get(controlName): AbstractControl {
|
||||
return (
|
||||
super.get(controlName) ||
|
||||
Object.values(this.controls)
|
||||
.filter((c) => c.get)
|
||||
.map((form) => {
|
||||
if (form instanceof CdFormGroup) {
|
||||
return form._get(controlName);
|
||||
}
|
||||
return form.get(controlName);
|
||||
})
|
||||
.find((c) => Boolean(c))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of a control if it has none it will return false
|
||||
*
|
||||
* @param {string} controlName
|
||||
* @returns {any} false or the value of the control
|
||||
*/
|
||||
getValue(controlName: string): any {
|
||||
const value = this.get(controlName).value;
|
||||
return this._filterValue(value) && value;
|
||||
}
|
||||
|
||||
// Overwrite this if needed.
|
||||
_filterValue(value) {
|
||||
return value !== '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a control without triggering a value changes event
|
||||
*
|
||||
* Very useful if a function is called through a value changes event but the value
|
||||
* should be changed within the call.
|
||||
*
|
||||
* @param {string} controlName
|
||||
* @param value
|
||||
*/
|
||||
silentSet(controlName: string, value: any) {
|
||||
this.get(controlName).setValue(value, { emitEvent: false });
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates errors of the control in templates
|
||||
*
|
||||
* @param {string} controlName
|
||||
* @param {NgForm} form
|
||||
* @param {string} errorName
|
||||
* @returns {boolean}
|
||||
*/
|
||||
showError(controlName: string, form: NgForm, errorName?: string) {
|
||||
const control = this.get(controlName);
|
||||
return (
|
||||
(form.submitted || control.dirty) &&
|
||||
(errorName ? control.hasError(errorName) : control.invalid)
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user