Reputation: 1014
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.
Upvotes: 2
Views: 4544
Reputation: 214017
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>
2) Trigger validation only on submit
3) Remove error blocks from the main flow(e.g. set them position absolute) so they won't shift Cancel
button
Upvotes: 6
Reputation: 1014
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.
Upvotes: 0