A web form groups controls for collecting user input and submitting it as an application action. In Angular, two-way `ngModel` bindings keep input values synchronized with component properties, while an `(ngSubmit)` event binding calls a method when the form is submitted. A product form can therefore fill a `newProduct` object and pass it to the method that adds a product. section 13.0 section 13.4
Build a form around the action it needs to perform:
- Bind each input to the corresponding model property with `[(ngModel)]`. A label and Bootstrap form classes provide the product fields with a straightforward layout. section 13.4.1
- Wrap the controls in `<form>` and bind `(ngSubmit)` to the component method. Give an input a `name` when using Angular validation; Angular uses it to identify the control. section 13.4.2
- Add rules such as `required`, `minlength`, and `pattern` where needed. Use control state to show feedback: Angular applies validity and interaction classes, and an `ngModel` template reference exposes errors for specific messages. section 13.4.2
Checkout submission
A checkout form binds required inputs to an `Order`, passes its `NgForm` object to `submitOrder`, and displays feedback when submission is attempted with invalid fields. The method saves the order only when `form.valid` is true; after a successful save, it clears the order and shows a confirmation. This explicit validity check matters: binding a submit handler alone does not express the application's save condition. section 6.5.2
The same structure supports editing as well as creation. A product editor binds fields to a `Product`; its route determines whether the form starts with an existing product, and the ID field appears disabled when editing. Angular Material supplies the form-field and input presentation. section 7.5.4
Listing 13.15. Adding form validation in the template.html file in the src/app folder
<div class="p-2">
<div class="bg-info text-white mb-2 p-2">
Model Data: {{jsonProduct}}
</div>
<form (ngSubmit)="addProduct(newProduct)">
<div class="form-group">
<label>Name</label>
<input class="form-control"
name="name"
[(ngModel)]="newProduct.name"
required
minlength="5"
pattern="^[A-Za-z ]+$" />
</div>
<button class="btn btn-primary mt-2" type="submit">
Create
</button>
</form>
</div>
Inspect the compact product form for the relationship between `<form>`, `(ngSubmit)`, a named `ngModel` input, and validation attributes. section 13.4.2
Listing 13.17. Adding validation messages in the template.html file in the src/app folder
<div class="p-2">
<div class="bg-info text-white mb-2 p-2">
Model Data: {{jsonProduct}}
</div>
<form (ngSubmit)="addProduct(newProduct)">
<div class="form-group">
<label>Name</label>
<input class="form-control"
name="name"
[(ngModel)]="newProduct.name"
#name="ngModel"
required
minlength="5"
pattern="^[A-Za-z ]+$" />
<ul class="text-danger list-unstyled mt-1"
*ngIf="name.dirty && name.invalid">
<li *ngIf="name.errors?.['required']">
You must enter a product name
</li>
<li *ngIf="name.errors?.['pattern']">
Product names can only contain letters and spaces
</li>
<li *ngIf="name.errors?.['minlength']">
Product names must be at least
{{ name.errors?.['minlength'].requiredLength }}
characters
</li>
</ul>
</div>
<button class="btn btn-primary mt-2" type="submit">
Create
</button>
</form>
</div>
Compare the extended form to see how a template reference and control errors produce messages after an invalid field has been edited. section 13.4.2











