简体   繁体   中英

How can I stop the angular reactive form validation from activating when clicking close button

I have a reactive form in a modal popup, but when I first open the modal, a required field has focus. When I click on the close button the validation is triggered (I think by losing focus), and displays the required field validation message but the button does not click ie. the code behind the button does not run. If you click it again it all works fine.

These are the relevant bits of the TS file:

  ngOnInit() {
    this.addPaymentForm = this.formBuilder.group({
      jobId: ['', [Validators.required, Validators.maxLength(9)]],
      grossAmount:  ['', [Validators.required, Validators.max(10000), Validators.min(-10000)]]
    });
  }

  get f() { return this.addPaymentForm.controls; }

  close() {
    this.activeModal.close({ dataModified: false });
  }

And this is the html:

<form [formGroup]="addPaymentForm" (ngSubmit)="submit()">
    <label for="jobId">Job Id</label>
    <input type="number" id="jobId" class="form-control" formControlName="jobId" required>
    <div *ngIf="f.jobId.invalid && (f.jobId.dirty || f.jobId.touched)" class="alert alert-danger mt-2">
        <div *ngIf="f.jobId.errors.required">
            Job Id is required
        </div>
        <div *ngIf="f.jobId.errors.maxlength">
            Invalid Job Id
        </div>
    </div>

    <label for="grossAmount">Gross Amount</label>
    <input id="grossAmount" type="number" class="form-control" formControlName="grossAmount" required>
    <div *ngIf="f.grossAmount.invalid && (f.grossAmount.dirty || f.grossAmount.touched)"
        class="alert alert-danger mt-2">
        <div *ngIf="f.grossAmount.errors.required">
            Gross Amount is required
        </div>
        <div *ngIf="f.grossAmount.errors.max || f.grossAmount.errors.min">
            Invalid Gross Amount
        </div>
    </div>
    <button type="button" class="btn btn-outline-dark" [disabled]="submitting" (click)="close()">Close</button>
    <button type="submit" class="btn btn-primary"
        [disabled]="!addPaymentForm.valid || !jobDetail || submitting">{{ submitting ? "Please wait" : "Save"}}</button>
    </div>
</form>

I've tried moving the close button outside the form tags but that doesn't make any difference.

EDIT: OK I've created a stackblitz to demonstrate the issue. https://stackblitz.com/edit/angular-ng-bootstrap-modal-content-4e9fac It does seem to work better than my actual code though as the JobId field is not in focus automatically on this example, so please click into the JobId field when the modal pops up to simulate my situation. Not sure why the field is in focus in my code, I think it's down to a version difference with ng-bootstrap, maybe if I could change that then this wouldn't really be an issue.

Your thoughts are correct here: validation is firing on blur event at the time you're clicking Cancel button.

A new validation block appears in the screen and Cancel button is shifted below. Since it is shifted the click event is not triggered.

There are many ways to solve it:

1) Use mousedown event instead of click so that blur event won't happen

<button type="button" ... (mousedown)="close()">Close</button>

Forked Stackblitz

2) Trigger validation only on submit

3) Remove error blocks from the main flow(eg set them position absolute) so they won't shift Cancel button

OK, a partial answer is this. In order to get the focus out of the input field I just needed to add the ngbAutofocus attribute to one of the buttons, so they would be in focus instead. This is a newish feature of ng-bootstrap so doesn't work in my stackblitz.

https://github.com/ng-bootstrap/ng-bootstrap/issues/2728

Still not sure how to fix this problem when the focus is on the field though, so this is only a partial answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM