@standard-forms/cdk
Version:
Interfaces, types and classes utilities for @standard-forms.
164 lines (125 loc) • 3.52 kB
text/typescript
import { Form } from './Form';
import { FormItemProps, FormItemValidator, FormItemErrors, FormItemTexts, FormItemValueWatcher } from './FormItem.model';
export class FormItem {
readonly name: string;
readonly validators: FormItemValidator[];
readonly tag: string;
readonly props: any;
readonly required: boolean;
disabled: boolean;
label: string;
formItemComponent: any /* HTMLNmafaFormItemElement */;
formControlComponent: any;
form: Form;
private _value: any;
private _errors: FormItemErrors;
private _isValid: boolean;
private _valueWatchers: FormItemValueWatcher[] = [];
constructor(props: FormItemProps) {
this.name = props.name;
this.label = props.label;
this.validators = props.validators;
this.disabled = props.disabled;
this.required = props.required;
}
/* -------------- Public methods ---------------- */
/* ---------------------------------------------- */
disable() {
this.disabled = true;
this.formItemComponent.disabled = this.disabled;
this._emptyErrors();
this.form._calcErrors();
}
enable() {
this.disabled = false;
this.formItemComponent.disabled = this.disabled;
this._calcErrors(this._value);
this.form._calcErrors();
}
setValue(value: any) {
if (this.disabled) {
return;
}
this._saveValueAndRunWatchers(value);
this.formItemComponent.value = value;
this._calcErrors(value);
this.form._setValue( {...this.form.getValue(), [this.name]: value } );
}
getValue(): any {
return this._value;
}
watchValue(cb: FormItemValueWatcher) {
this._valueWatchers.push(cb);
}
getErrors(): FormItemErrors {
return this._errors;
}
setErrors(errors: FormItemErrors) {
this._setErrors(errors);
this.formItemComponent.errors = errors;
this.form._calcErrors();
}
isValid(): boolean {
return this._isValid;
}
setTexts({label}: FormItemTexts) {
this.label = label;
this.formItemComponent.label = label;
this._calcErrors(this.getValue());
}
isDisabled(): boolean {
return this.disabled;
}
/* -------------- Internal methods ---------------- */
/* ------------------------------------------------ */
_disable() {
this.disabled = true;
this.formItemComponent.disabled = this.disabled;
this._emptyErrors();
}
_enable() {
this.disabled = false;
this.formItemComponent.disabled = this.disabled;
this._calcErrors(this._value);
}
_setValue(value: any) {
if (this.disabled) {
return;
}
this._saveValueAndRunWatchers(value);
this.formItemComponent.value = value;
}
_saveValueAndRunWatchers(value: any) {
this._value = value;
this._valueWatchers.forEach(watch => {
watch(value);
});
}
_calcErrors(value: any) {
if (!this.formItemComponent) {
return;
}
let errors = {};
if (this.validators && this.validators.length && !this.disabled) {
this.validators.forEach((validator: FormItemValidator) => {
const errorMsg = validator.fn(value);
if (errorMsg) {
errors = {
...errors,
[validator.name]: errorMsg
};
}
});
}
this._setErrors(errors);
this.formItemComponent.errors = errors;
}
_setErrors(errors: FormItemErrors) {
this._errors = errors;
this._isValid = !Object.keys(this._errors).length;
}
_emptyErrors() {
this._setErrors({});
this.formItemComponent.errors = {};
}
}