I am beginner in angular and started working on angular 12 project. I am working on reactive forms where I am adding on Blur method to add class to my input field on some error conditions to give some styling to input fields.
I am able to do that but now I have 12-15 components with forms. I want to utilize the same functionality on all the components. Is there a way I can do this without repeating the code in ts file for onblur method. Below is my code.
<form [formGroup]="changePasswordForm" (ngSubmit)="submitForm()">
<div [ngClass]="f.oldPassword.invalid && ((f.oldPassword.dirty || f.oldPassword.touched))?'has-error':''">
<label>Old Password<span >*</span></label>
<input type="password" formControlName="oldPassword" (blur)="onBlur($event)">
<div >
<div *ngIf="f.oldPassword.errors?.required">
<i aria-hidden="true"></i> Old password is required.
</div>
</div>
</div>
</form>
Component.ts
onBlur(e: any) {
if (e.target.className && e.target.className.indexOf('ng-invalid') > 0) {
e.target.className = e.target.className.replace('has-success', '');
} else {
e.target.className = e.target.className ' has-success';
}
}
I am writing the same piece of code in all the form components to get my work done. I know one way to deal above is create service and write it down over there. But I did some research and found that we can create directives for such things. But I am not sure how to do it. Any help will be appreciated. Thanks.
CodePudding user response:
You can use a directive on the input
@Directive({ selector: "[errorStyling]" })
export class ErrorStylingDirective {
constructor(
private elem:ElementRef
) { }
@HostListener("blur")
onBlur() {
// do something here
}
}
You could also use @HostBinding('class.xxx')
approach to set the updated classes
CodePudding user response:
Put that method in a separate service file like
CommonService.service.ts
@Injectable({
providedIn: 'root',
})
export class CommonService {
constructor() {}
blur(e){
if (e.target.className && e.target.className.indexOf('ng-invalid') > 0) {
e.target.className = e.target.className.replace('has-success', '');
} else {
e.target.className = e.target.className ' has-success';
}
}
}
Then import this service file in the component using dependency injection in constructor. Then call the method from the service file. You may need to change the code a little also check if you need to return from the method in the service file