Issue
I wrote this custom validator:
import { AbstractControl, ValidationErrors, ValidatorFn } from "@angular/forms";
export function notInSet(theSet: Set<string>): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const val = control.value;
if(theSet.has(val))
return {InSet: true};
else
return null;
}
}
Now in my template I have this:
<form #myForm novalidate>
<input pInputText [(ngModel)]="name" name="name" notInSet="existingNames" #theName="ngModel"/>
<div *ngIf="!theName.valid" class="text-error">
Please provide a unique name for this api
</div>
</form>
Here existingNames
and name
are defined the the corresponding ts file.
The problem is that that validator is never called. I feel that I have to register it somewhere, but I'm not really sure where.
Solution
You need to create a directive
when you are using custom validator for template driven forms, here is a working example on stackblitz which you can go through and implement your functionality, kindly let me know if any doubts!
directive
import { Directive, Input } from '@angular/core';
import {
NG_VALIDATORS,
Validator,
AbstractControl,
ValidationErrors,
} from '@angular/forms';
@Directive({
selector: '[notInSet]',
providers: [
{
provide: NG_VALIDATORS,
useExisting: NotInSetDirective,
multi: true,
},
],
standalone: true,
})
export class NotInSetDirective implements Validator {
@Input() notInSet!: Map<string, number>;
constructor() {}
validate(control: AbstractControl): { [key: string]: any } | null {
const val = control.value;
if (this.notInSet.has(val)) return { InSet: true };
else return null;
}
}
main.ts
import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { ReactiveFormsModule, FormsModule } from '@angular/forms';
import 'zone.js';
import { CommonModule } from '@angular/common';
import { NotInSetDirective } from './validator.directive';
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule, ReactiveFormsModule, FormsModule, NotInSetDirective],
template: `
<form #myForm novalidate>
<input pInputText [(ngModel)]="name" name="name" [notInSet]="existingNames" #theName="ngModel"/>
<div *ngIf="!theName.valid" class="text-error">
Please provide a unique name for this api
</div>
{{theName.valid | json}}
</form>
`,
})
export class App {
name = 'Angular';
existingNames = new Map([
['apples', 1],
['bananas', 1],
['oranges', 1],
]);
}
bootstrapApplication(App);
Answered By - Naren Murali
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.