Angular 2 form validators, messing with the cancel button

I have a data collection component that includes a "cancel" button to cancel the whole process. The problem is if some of the HTML input fields that are validated by the Angular 2 validators have focus and are invalid and I click the cancel button, the component is not deleted. Instead, the validators will be activated, and pressing the cancel button will be ignored. I have to push it a second time, after the validators complain, for the component to disappear. The Rectangle button simply starts routing from the component. Relevant code:

component.html

<form [formGroup]="addReminderForm" (ngSubmit)="onSubmit(addReminderForm.value)">
  <input type="text" [formControl]="addReminderForm.controls['text']" />
  <div class="error" *ngIf="addReminderForm.controls['text'].hasError('required') &&
  addReminderForm.controls['text'].touched">You must enter reminder text</div>

  <button type="submit" [disabled]="!addReminderForm.valid" >Add Reminder</button>
</form>
<button (click)="cancel()">Cancel</button>

      

component.ts:

ngOnInit() {
  this.addReminderForm = this.fb.group({  
      'text': ['', Validators.compose([Validators.required, Validators.maxLength(20)])]
  });
}
cancel() {
    // Simply navigate back to reminders view
    this.router.navigate(['../'], { relativeTo: this.route }); // Go up to parent route     
 }

      

I have no idea why this is happening. Any ideas?

+3


source to share


2 answers


Try using the type = "reset" button, for example:

<form [formGroup]="heroForm" (ngSubmit)="onSubmit()" novalidate>

  ...       
  <div>
    <button type="submit" [disabled]="heroForm.pristine">Save</button>
    <button type="reset" (click)="revert()"[disabled]="heroForm.pristine">Revert o Cancel</button>
  </div>

</form>

      

In your component class:



revert() { this.ngOnChanges(); }

      

For more information at https://angular.io/guide/reactive-forms

I hope to help you.

+1


source


The reason is that the form validation fires as soon as the blur event fires. This happens before the undo click is registered.

I can only figure out one workaround - have a flag in your component that is initially set to false to know when to show errors.

Set to true only if you want the checks to be done "fire".

So, if the form loads and the user clicks in the field and then presses out, the flag is still false, so no validations are shown. If the user clicks on the submit button, you enable the flag, which checks the validations.

For example, this form has a span block that is used to display validation errors, and it is protected *ngIf

for a flag as well. It also protects the validate-field class for the input itself - it just adds a red border around the input if there is an error. So the flag must be right for the red border and validation error to be displayed.

  <form [formGroup]="form" (ngSubmit)="onSubmit(form.value)">
    <div class="modal-body">
      <input #nameElement id="template-name" (blur)="onBlur($event.target)" 
        [formControl]="name" (keyup)="keyUp($event)" class="form-control"
        [ngClass]="{'checking-field': isShowError}" 
        placeholder="Name this template">
      <span class="help-block" *ngIf="isShowError">
        <span class="text-danger" *ngIf="form.get('name').hasError('minlength')">Name is required</span>
        <span class="text-danger" *ngIf="form.get('name').hasError('noDifference')">Name must be different</span>
      </span>
    </div>
  </form>

      

OnSubmit starts like this:

  onSubmit(data: any):void {
    this.isShowError = true;
    if (this.form.valid) ...

      

which ensure that validation errors are shown when the user clicks the submit button. They will NOT appear when the field loses focus because the flag will be false.



However, you CAN work around this with an ugly hack as follows (cumbersome as well, since then you need a blur handler for all fields in the form!).

Add another flag to track when the user clicks the cancel button, and for each field in the form, in the handler (blur), check it during the timeout, e.g .:

setTimeout(() => {if (!userClickedCancel) this.isShowError = true}, 500);

      

Then in the cancel handler:

this.userClickedCancel = true;

      

This means that the cancellation code must change the flag before it times out in the handlers to check its value.

** NOTE. If you reject the shape and do not move **

Also, if you are not navigating, and perhaps "hiding" the form (or closing the modal), you should also set the flag isShowError

to false in the cancel handler (for cases where the user clicks submit, the form is invalid, then click Cancel. and then load the form again).

+1


source







All Articles