import { closest, attr, controller, target, html, TemplateResult } from 'core/utils';
import randomId from 'core/utils/random-id';
import { BaseComponentElement, Validator } from 'common/';
import { AppFormElement } from 'components/app-form/AppFormElement';
import { InputFieldElementTemplate } from 'components/input-field';
@controller('input-field')
class InputFieldElement extends BaseComponentElement {
@attr name: string;
@attr type: string;
@attr label: string;
@attr rules: string;
@attr pattern: string;
@attr customAction: string;
@attr initialValue: string;
@target main: HTMLElement;
@target inp: HTMLElement;
@closest appForm: AppFormElement;
@attr disabled: string;
valid: boolean;
displayError: boolean;
randId: string;
changed: boolean = false;
validator: Validator;
constructor() {
super();
}
public elementConnected = (): void => {
this.validator = new Validator(this, this.appForm, this.rules);
this.randId = `${name}${randomId()}`;
this.update();
if (this.initialValue) {
this._value = this.initialValue;
}
};
attributeChangedCallback() {
this.update();
}
setError = (error) => {
this.validator.error = error;
};
get error(): string {
return this.validator?.error;
}
get isValid(): boolean {
return this.validator.valid;
}
get required(): boolean {
return this.rules?.includes('required');
}
get _value() {
if (this.type == 'checkbox') {
return (this.inp as HTMLInputElement)?.checked;
}
return (this.inp as HTMLInputElement)?.value;
}
get _disabled() {
return this.disabled == 'true';
}
set _value(value) {
if (this.type == 'checkbox') {
(this.inp as HTMLInputElement).checked = value as boolean;
} else {
(this.inp as HTMLInputElement).value = value as string;
}
}
validate = (): boolean => {
const valid = this.validator.validate();
if (valid && this.displayError) {
this.displayError = false;
this.update();
} else if (this.changed && !valid) {
this.displayError = true;
this.update();
}
return valid;
};
validateDisplay = () => {
const active = this.appMain.activeElement;
if (active.closest('app-link') || active.closest('a') || active.closest('button')) return;
if (!this.validate()) {
this.displayError = true;
} else {
this.displayError = false;
}
this.update();
};
inputChange = (e) => {
if (!this.changed && e?.target?.value) {
this.changed = true;
}
this.appForm?.inputChange(e);
};
render = (): TemplateResult =>
InputFieldElementTemplate({
randId: this.randId,
required: this.required,
pattern: this.pattern,
_disabled: this._disabled,
customAction: this.customAction,
type: this.type,
error: this.error,
label: this.label,
});
}
export type { InputFieldElement };