I have the following input
<div>
<input
type="text"
name="name"
[(ngModel)]="query.name"
[appInvalidName]="query.format"
(update)="onUpdate()"
#name="ngModel"
placeholder="Enter name..."
/>
<div class="error-message" *ngIf="name.invalid">
<span>{{name.errors?.["message"]}}</span>
</div>
</div>
where I can enter a name (query.name) which is then validated depending on query.format. I would like to make the whole div into a component TextInputComponent, thus appInvalidName needs to be passed from the outer div down to my input, as well as ngModeland update
<app-text-input
[appInvalidName]="query.format"
[(ngModel)]="query.name"
(update)="onUpdate()"
/>
That's the definition of the directive:
import {
AbstractControl,
NG_VALIDATORS,
ValidationErrors,
} from '@angular/forms';
import { Directive, EventEmitter, Input, Output } from '@angular/core';
import { Format } from './app.component';
@Directive({
selector: '[appInvalidName]',
providers: [
{
multi: true,
provide: NG_VALIDATORS,
useExisting: InvalidNameDirective,
},
],
})
export class InvalidNameDirective {
@Input('appInvalidName') format?: Format;
@Output() update = new EventEmitter();
ngOnChanges(): void {
this.update.emit();
}
validate(control: AbstractControl): ValidationErrors | null {
if (this.format === 'short' && !/\w\.\w/.test(control.value)) {
return {
message: 'wrong format',
};
}
return null;
}
}