Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 5 solely validation on blur?

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.

like image 307
timfrans Avatar asked Apr 30 '18 15:04

timfrans


2 Answers

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)">
like image 109
timfrans Avatar answered Nov 01 '22 19:11

timfrans


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

like image 25
mclem Avatar answered Nov 01 '22 20:11

mclem