Angular 5 solely validation on blur?

18,254

Solution 1

What I eventually have done:

Using reactive forms:

TS

this is the form to make. I needed the productCost and loanAmount to be validated on blur but the values itself needed to update onchange. If you set updateOn: "blur" the validation happens after the blur event but als the values will update after the blur event.

let formToMake = {
      productCost: new FormControl(null, {validators: Validators.required, updateOn: "blur"}),
      loanAmount: new FormControl(null, {validators: Validators.compose([Validators.required, Validators.min(2500)]), updateOn: "blur"}),
      loanLength: new FormControl(49, {validators: Validators.required, updateOn: "change"})
    };

handleInput method:

To solve this I just made an event handler which will be called on the input event.

TS

handleInput(e: any) {
    this.loanAmount = e;
  }

HTML

<input class="form__input" type="number" value="{{loanForm.get('loanAmount').value}}" id="loanAmount" formControlName="loanAmount" (input)="handleInput($event.target.value)">

Solution 2

I believe that you're looking for ng-binding on the Angular element. For example, you can bind to the keystrokes and blur like this for the input field:

<input type=text (blur)="validate()" (keypress)="eventHandler($event)">

eventHandler(event) {
   console.log(event, event.keyCode, event.keyIdentifier);
   // Update value of string on every keystroke
} 

validate() {
   // Validation code goes here
}

You could also use ngModel and then you wouldn't have to worry about the keystroke at all because the string would automatically be updated for you. It would look something like this:

<input [(ngModel)]="name" (blur)="validate()">

name: string;

validate() {
   // Validation code goes here
}

Since you're looking at using the Reactive Forms Module and their validation, you could do something like this:

Template Approach

<input [(ngModel)]="lastname" [ngModelOptions]="{ updateOn: 'blur' }">

The ngModel binding will change the input on every keystroke so you don't have to do it manually. I would really suggest taking this approach since this is what you're currently asking to do.

Reactive Forms Approach

this.nameForm = new FormGroup ({
  firstname: new FormControl('', {
    validators: Validators.required,
    updateOn: 'submit'
  }),
  lastname: new FormControl('', {
    validators: Validators.required,
    updateOn: 'submit'
  })
});

References: SO Approach Medium Article

Share:
18,254
timfrans
Author by

timfrans

Updated on July 24, 2022

Comments

  • timfrans
    timfrans almost 2 years

    I wonder if it is possible to have the validation in reactive forms on blur. At the moment you can set updateOn: "blur" but then the values of the input fields won't update on input. In my case i need the values to be updated on every keystroke because I do calculations with it and show the result to the user. The validation should only happen on blur.

    thx.

    EDIT:

    I use FormBuilder, some build in validators and some custom validators. Example code:

    let formToMake = {
      purpose: [null, Validators.required],
      registrationDate: this.fb.group({
        day: [null, Validators.required],
        month: [null, Validators.required],
        year: [null, Validators.required]
      }),
      isTruth: [null, Validators.compose([checkIfTrue, Validators.required])]
    };
    

    If i would use the blur event i need to do all my validation manually, which i think is not a good way.

  • timfrans
    timfrans about 6 years
    Yes but then I have to validate manually right? Currently I configure the validators with formbuilder: let formToMake = { productCost: [null, Validators.required], loanAmount: [null, Validators.compose([Validators.required, Validators.min(2500)])], loanLength: [49, Validators.required] }
  • timfrans
    timfrans about 6 years
    Yes but then I have to validate manually right? Currently I configure the validators with formbuilder: let formToMake = { productCost: [null, Validators.required], loanAmount: [null, Validators.compose([Validators.required, Validators.min(2500)])], loanLength: [49, Validators.required] }
  • Antonio de la mata
    Antonio de la mata about 6 years
    You could use a markAsTouched() for each form control method forcing the validations!, looping the form.controls object property.