In this article, we will discuss Template Driven Forms in Angular and how they can be used in a similar way to Reactive Forms.
Template driven forms (also known as model driven forms) in Angular are a way to create a form that is defined in the template of an Angular component. This differs from reactive forms where the form is defined via code in the Typescript file of the component.
With template driven forms, we give up some of the fine grained details of the functionality of the form. Angular takes care of this for us. However, in most use cases, if implemented correctly, the difference can be minimal. In the end, a template driven form generate the same data structure that a reactive form generates, so most of what can be accomplished in a reactive form can also be accomplished in a template driven form.
As discussed earlier, a template driven form is defined at the HTML template level by the Angular compiler. We specify the form with by creating a reference in the form tag in the template and define it in the Typescript file. The form's controls are assigned by the name attribute on the HTML DOM element. Below is an example of the HTML template. Note: To use template driven forms, you must import the FormsModule in the module. This differs from reactive forms, where you import the ReactiveFormsModule.
Things to Note: We create a reference of the form reference named myForm in the form tag. When we set it ="ngForm”, this tells the Angular compiler that the type of that reference of type NgForm. NgForm is the equivalent to FormGroup in reactive forms. This allows us to get access to the form from the Typescript file of the component. Another thing to note is that we use the ngModel directive for our 2 inputs. Note that we are NOT set the ngModel directive to a value. In this article, we will try to mimic a reactive form as closely as possible so we will create value changes events to handle changes that need to occur when we update the form. Marking the 2 inputs with the ngModel directive is the template driven form way to create form controls for the form group in reactive forms. The name of the form controls will be the value of the name attribute for the inputs.
Things to note:
We declare a @ViewChild from the myForm reference we created in the template form tag. The type for this is NgForm.
We log the myForm variable on ngOnInit and it is undefined. This is because since it is a @ViewChild, the variable is not set until after the ngOnInit lifecycle hook.
We log the myForm variable on ngAfterViewInit and now it is defined. The structure of the variable is almost identical to what the FormGroup type in reactive forms would look like. There is a controls property, which has the key value pairs on our inputs that we marked as ngModel. The value for these keys are FormControl, as they would be in FormGroup for reactive forms.
Adding custom validation:
Things to Note:
We implement Validator here which will return a key value pair if the control value has test.com as a part of value.
We provide NG_VALIDATORS with useExisting: CustomValidorDirective. This means that the form control using this directive is the instance that is passed into this validator.
Things to note:
We add the pmtCustomValidator directive to the email input. This will pass this form control to the validator we created.
We add a div to show errors when the form control is invalid. This shows that we can set the validation on the form control level and not just the form itself.
See it in action