Home > Mobile >  Creating a reusable method attach to input field for multiple components in Angular
Creating a reusable method attach to input field for multiple components in Angular

Time:04-02

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

  • Related