Reputation: 4456
I am using a template based form in angular. I also use bootstrap (v4) and I wish to show some validation messages when the form was submitted.
This is my form:
<form [ngClass]="{'was-validated': wasValidated}">
<div class="form-group">
<label for="name">Name</label>
<input type="text" id="name" name="name" class="form-control" [(ngModel)]="category.name" #name="ngModel" required maxlength="100"/>
<div *ngIf="name.invalid" class="invalid-feedback">
<div *ngIf="name.errors.required">
Name is required.
</div>
</div>
</div>
<button type="submit" class="btn btn-success" (click)="save()">Save</button>
</form>
My component looks as follows:
category: Category;
wasValidated: boolean = false;
ngOnInit() {
this.reset();
}
save() {
this.wasValidated = true;
this.categoriesService.createCategory(this.category).subscribe(
() => {
this.notificationService.add(notifications.category_saved, {name: this.category.name});
this.reset();
},
() => this.notificationService.add(notifications.save_category_failed)
);
}
reset() {
this.wasValidated = false;
this.category = {} as Category;
}
This works, but I have a feeling it's overly complex and more like a workaround rather than the right way. What is the best way to accomplish this?
Note: the class was-validated
must be present on the form element in order to show the div with class invalid-feedback
. I'm using this: https://getbootstrap.com/docs/4.0/components/forms/#validation
Note 2: I have currently no mechanism yet to prevent form submission on error. I'd like to know a good solution for that as well!
Upvotes: 0
Views: 2042
Reputation: 4456
With the answer from @Chellappan V I was able to construct the solution I wanted.
I have applied to following changes:
First added #form="ngForm"
to the form tag in the template. Secondly I changed the ngClass expression to reference the submitted state of the form, rather than referring to a boolean which was set to true manually when form was submitted. Last but not least I pass the form in the submit method on the save button.
<form novalidate #form="ngForm" [ngClass]="{'was-validated': form.submitted}">
<!-- form controls -->
<button type="submit" class="btn btn-success" (click)="submit(form)">Save</button>
</form>
In the component I injected the template variable in the component with @ViewChild
.
@ViewChild("form")
private form: NgForm;
The submit method now takes a form parameter of type NgForm which is used to check if the form was valid before sending a request to the backend:
submit(form: NgForm) {
if (form.valid) {
this.categoriesService.createCategory(this.category).subscribe(
() => {
this.notificationService.add(notifications.category_saved, {name: this.category.name});
this.reset();
},
() => this.notificationService.add(notifications.save_category_failed)
);
} else {
this.notificationService.add(notifications.validation_errors);
}
}
Finally the reset method resets the form and the model so it can be re-entered to submit a next instance:
reset() {
this.form.resetForm();
this.category = {} as NewCategoryDto;
}
Upvotes: 0