Skip to main content

Everything You need to About Angular Template Driven Forms

 Forms in Angular 

Forms on html page and how angular can help you with those forms now on first side might be strange because form is something that you can simply submit server then keep in mind you are creating a single page application so there is no submit to the server instead you have to handle from through angular and if then you want to submit  something to server you will need to reach out via angular http  service.

How angular works together with forms.

This is html code of form which you might use nothing is angular specific about this code its normal html code placed in html document it will be displayed like this with the input for Name and mail 

  


Now angular job now is to allow you to retrieve values which is entered here and also check some other things like  is the form valid did the user entered valid information all that will happen in javascript and in typescript or we can say angular side. So some how we have to pass these values which user enters so some how you need javascript object representation of your form in your typescript code to work with. 

This object could look something like this it is more complex in real world these will be key features we need. We need to have value of the form and there could be any key value pair  where key is referes to name of input like name in the form or html we mentioned and value is holds user entered. This would make it super simple for you to work with these values in your type script code to do something with the values user entered. It might have also some meta data information like form is valid. 




Two types of forms in Angular / Two Approaches. 


  • Template driven forms (Angular infers the Form Object from the DOM)
  • Reactive forms (also known as dynamic forms) [Form is created programmatically and synchronised with the DOM]

Lecture 2:


So here I am on a simple example form just to get started, the code responsible for it is this HTML code in the template of my app component here and you can find this code attached to this lecture here. 

Now it's a simple form, we're going to expand it or enhance it with some features throughout this module, to get started, this is just fine.

Now if we have a look at this HTML code,





you will quickly realize that on the form tag here, I don't have the action attribute pointing to some route,

I'm also not specifying the method attribute which typically would be post.

The reason for this is that this form should not get submitted to a server,

I don't want a HTTP request to be the result of me clicking the submit button, instead

as mentioned earlier, Angular should handle this form and therefore, I don't have an action on it.

This of course means that right now if I hit the submit button, nothing happens,

if you have a look at the refresh icon up there, you see it's not spinning, nothing happens because we're

not actually sending a request.

Well we will work on this but first, let's understand what actually happens behind the scenes and how

Angular infers such forms, create such a Javascript object for us as it does when using the template

driven approach.

Lecture 3 :


now let's understand how Angular creates such a Javascript object representing our form in the template

driven approach.

The great thing is you don't have to do anything, well almost anything,

make sure that in your app module, you actually import the forms module, add it here to your imports array




and have the import at the top of this file. As the name implies,

this built-in module shipping with Angular includes a lot of forms related functionalities and it's

actually needed to get this template driven approach to work, to get this form creation by Angular to

work. Now by default in a CLI project, this should already be imported so it should work fine

but again, I'm just highlighting it because it's super important that you have this import, otherwise the following

steps will not work. With this imported, Angular will actually automatically create a form for you,

so a Javascript representations of the form when it detects a form element in HTML code, like it does

here.

<form>


</form>

So you can think of that form element serving as a selector for some Angular directive, which then creates

such a Javascript representation of the form for you.

Of course, you can't see that form representation as of now and it would be very empty because one thing

does not happen automatically, Angular will not automatically detect your inputs in this form

and the simple reason for this is that whilst you could argue that it should be able to scan your HTML

code and detect that you have an input here and here and that you have a select dropdown here, you

still might not want to add all these elements as controls to your form, so with control I'm referring

to what is in the Javascript object

and again not every input in your HTML code might be a control you want to have in your Javascript form.

Maybe you have a dropdown which values only changes something you view on the UI but the input

should not actually be part of what gets submitted,

maybe you use some third-party package which adds some custom form controls which are not labeled input,

which don't use input as a selector and then Angular would have no chance of detecting that this is a

control of your form.

So you still need to register controls manually,

you need to tell Angular hey within that form element, what should be an actual control of my form?

And this is what we're going to do

now, tell Angular how does our form look like,

which controls do we want to have? In the template driven approach,

this is super simple.

You simply pick the input which you want to add as a control, like this input here

and I'm just going to structure it a bit different to split it up over multiple lines to make it easier

to read and then you add ngModel, like this.

Now you might already know ngModel from the two-way binding, two-way data binding and it actually is

the same directive. In two-way data binding though,

you saw that we use that with square brackets and parentheses wrapped in ngModel.

Now we will have a look at this later again

but for now, let's add it without any parentheses, without any square brackets just like this.




This will be enough to tell Angular, hey this input is actually a control of my form, so ngModel in

the end is a directive made available in the forms module, something I mentioned earlier in the course

when we had a look at two-way data binding.

This is key to understand,

you can use it to get two-way data binding but it actually is part of a bigger module with more features

giving you full control over forms.

Now for this to work, for this to be recognized as a control in your form, we need to give Angular one other

piece of information, the name of this control.

Right now, it would see OK this input should be part of the Javascript object representation of this

form,

so whatever the user enters here as a value should be the value of this control, of what's

the name of that control.

We need to give that information to Angular and we do this by adding the normal HTML attribute, name. So

name is nothing Angular 2 specific, name is the default attribute

you can add to any HTML control.

Now here, the name might be username because that is what we can enter in this input

and with this, this control will be registered in this Javascript representation of the form.

Now I'll do the same for the email, restructure it so that it's easier to read, add ngModel and add

a name, like for example email here.

Well and the same is true for the select here which is just another type of HTML input.

Here we can also add ngModel and we can add a name, like secret because I'm asking for a secret question

here and with that, we registered all the controls,

of course we can't see that much though.

Well that is something we're going to have a look at in the next lecture when we see how we can submit

such a form and therefore, how we can see these key-value pairs representing what the user entered into

which input.

Lecture 4: Submitting and Using Form


In the last lecture, we configured our form here, we added some control by placing ngModel on the

inputs,

now let's make this form submittable so that we can actually see what the user entered.

For this, I'll go to my app component,

I already do have a method here which you will use later,

let's ignore it for now and I'll add a new method, onSubmit maybe, this should be triggered whenever this

form is submitted by the user. In onSubmit,

I want to output whatever the user entered,

well first of all we need to call this method,

so back in the template, how can we call onSubmit?

Now you might think that a good place would be on a click listener on this button here at the bottom right, because

this is a button we click when we want to submit the form,

however this is not the best place to do it.

Keep in mind that this button here is type submit,

so if we click it as it is placed inside of an HTML form element, something else will happen,

The default behavior of HTML will be triggered to call it like this.

If you have a button in a form element, this button will submit the form, will send a request normally

but besides that, it will also trigger a Javascript event,

the submit event that's built into Javascript, built into HTML

you could say. Angular takes advantage of this and gives a directive

we can place on this form element as a whole,

it is called ngSubmit and it actually only gives us one event we can listen to,

<form (ngSubmit)="onSubmit()">


</form>

so let's wrap it in parentheses.

This event made available by the ngSubmit directive will be fired whenever this form is submitted,

so whenever this default behavior is triggered

and here, we can call onSubmit like this and to show you that this works,

I will simply go into onSubmit and log submitted here,

just like that.

Now if we save this and let it recompile, let's go back and let's open up the developer tools and if

I now hit the submit button, you see submitted here on the right

because indeed, the form gets submitted.

Now it would be nice to see the actual values of the form though, to see that form object and to see

it, we have to go back to our template because we're in the template driven approach,

so as a rule of thumb, everything you do you do it in the template, everything you want to change about

this form, you want to add as functionality,

you do it in a template. On this form object,

we want to get access to the form created by Angular.

Now you learned about local references you can place on HTML elements to get access to them,

so we could place #f on the form element and now we could access this form element on the f

<form (ngSubmit)="onSubmit()" #f>

reference in our template and we could pass f as an argument to the onSubmit method and print it

there.

<form (ngSubmit)="onSubmit(f)" #f>

</form>

So now we know that we get the form

and actually, this will be of type element ref as we learned.

So if we import element ref and make this of type ElementRef here and we output the form here,
Note: Thats actually not correct it is of Type "HTMLFormElement"

onSubmit(form: HTMLFormElement)
{
console.log(form);
}

so this element, if we now go back to this and hit submit,

yes we did see the form object, we see some strange classes here, I will come back to them but that still is not what

we want,

it's not a Javascript object created by Angular but this object is there, we just need to know how to

get to it and there actually is a trick you could call it but it's no trick, it's the default way to

get access to this automatically created object,

you set this local reference equal to something.

Now we haven't done that yet but we can set it equal to something exposed by this

form here,

keep in mind the form element is kind of a selector for a directive built into Angular which will create

this Javascript object automatically and then it will expose some data we can fetch here on this form element.

We can get access to it by writing ngForm here between the quotation marks.

<form (ngSubmit)="onSubmit(f)" #f="ngForm">

So this might look super strange but what this in the end does is

it tells Angular hey please give me access to this form you created automatically.

That's just something you have to keep in mind,

this is how you get access to the form, to this Javascript object created by Angular automatically.

So therefore here where we get this form, we now still pass it,

now this will no longer be an ElementRef, so let's remove this type here, instead

this will now be of ngForm.

So let's import ngForm from @angular/forms and kind of makes sense that it is of type ngForm

because that is what we're accessing here,

this automatically created form.

Now let's print it to the console one more time and let's actually enter something into these fields to

see that it worked.

If I now type submit here, you see that now we get an ngForm object, an object which we certainly didn't

create

and there, we have a lot of properties,

we'll have a close look at those later.

We also do have a value property




and if we expand this, we indeed see a couple of key-value pairs here where we have the names of the

controls, so the names we set up here and the name attribute like username and email,

we find them here

and then the values the user entered.

And this is how we can submit such a form and how we can also get access to the form object created by

Angular,


Lecture 5: Understanding Form State


In the last lecture, we learned how we can submit a form created by Angular and how we can access to this

object

Angular created for us.

Now we had a look at the value property which stores the input of the user in key-value pairs,

Here value:Object
                email:"test@gmail.com"
                secret:"pet"
                username: "test"



we see that we also have a lot of other properties and that's pretty cool about this Javascript object,

about the form handling by Angular,

it allows us to really understand the state of our form

We can see which controls we registered here on the controls object, e-mail, secret and username and





each control is of type FormControl, of course a type made available by Angular where each control then

has a couple of properties, mostly the same properties we have on the overall form though

and therefore let's go back to that overall form,

for example properties like dirty, disabled, enabled, errors

and most of the properties should be pretty self-explanatory. 

Dirty for example is true because we changed something about that form.

If I reload the page and submit it now, you will see that dirty is false because I didn't type into any

input, so therefore of course dirty is false.

Disabled would be true if the form was disabled for some reason, 

invalid is false because we haven't added any validators, so it isn't invalid, it is indeed valid.

You do have the valid property down here too, so the form is valid right now,

we will later learn how to add validators to make sure that a valid e-mail address has to be entered

for example.

And we also have 

touched for example to see did we click into some of the fields, the difference to dirty

would be that for dirty, we have to change the field, have to change the value of a field, for touch we simply

have to click into it and now it would be touched and you will later learn how these properties can

be helpful in

changing the user experience, for example disabling the submit button if the form is not valid,

I will come back to this later.

It's important to understand that you have all these properties and definitely feel free to dive into

the output we logged here and understand which properties you have, how they change, which properties

the individual controls have and so on.

Lecture 6 : Accessing Form Child With @ViewChild


In the last lectures, we learned how we can register controls and how we can submit the form and also which

properties this form has. Now

right now, we submit the form by passing the form which we get via ngForm here to the onSubmit method,

<form (ngSubmit)="onSubmit(f)" #f="ngForm">

</form>

this is absolutely fine and probably the approach you will use in many use cases.

I just want to bring some other approach to your attention.

You don't have to submit it here.

Like we don't need to pass f in this method onSubmit()

Remember the components section where we learned about @ViewChild which allowed us to access a

local reference, an element controlled or which holds a local reference in our TypeScript code.

Well in the end, we do just have such a local reference here

and whilst that might not point to an element ref but to the ngForm object, it still is a local reference

in our template so we can also use @ViewChild here.

So I will simply comment out this onSubmit method here so that we have it in the code you can find

attached to this module and show you an alternative approach. In this alternative approach,

I will use @ViewChild, this decorator you learned about in the component section, so make sure to import

it from @angular/core




and I want to get access to the element which has the local reference f on it.

So I pass f as a string, as an argument to @ViewChild

and then I could simply store this in a variable named signupForm, any name you like, which will be of

type ngForm of course. Now in onSubmit,

I could output this signupForm, like this

and you should see that if I now submit this again, we still have this form

and I can also enter something so that we can see that this works too if we have a look at the value.

So this gives us access to the very same form without passing it to onSubmit,

this is especially useful if you need to access the form, not just at the point of time when you submit it

but also earlier

and I will show a use case for this in a later lecture.

For now, let's keep in mind that this is another way of getting access to the form in our TypeScript

code, a perfectly valid way of getting access and before diving deeper into why this might be useful

or when we could use that, let's actually understand how we can control the validity of the form.

So to determine whether the form is valid, if we entered a valid e-mail address here or not because right now

I can submit anything, no matter if this is invalid, if this is empty,

it would be nice if we could add such validation and take advantage of the tools Angular

gives us there to possibly also enhance the user experience by placing a red border around invalid elements

or something like this.

We'll have a look at validation in the next lectures.


Lecture 7 : Adding Validation to Check User Input


So as mentioned at the end of the last lecture, it would be nice if we could validate the user input,

something very important in any app you build.

Whilst you should still validate input on the server as the front-end can always be tricked, you can

greatly enhance user experience by also validating the input here,

for example we want to make sure that none of the fields here is empty and that the e-mail address

actually is a valid e-mail address.

So let's go back to our app component, to the HTML file, to the template and see how we can add such validators.

Now since we use the template driven approach, we can only add them in the template

and here we can for example add required to our username input. Now required is a default HTML attribute

<input type="text", id="username" class="form-control" ngModel name="username" required>

you can add to an input, here however Angular will detect it,

so it acts as a selector for a built-in directive shipping with Angular and it will automatically configure

your form you could say, to take this into account, to make sure that now this will be treated as invalid

if

it is empty.

And on the e-mail, we can for example therefore also add required

and there also is an email directive you can add.

<input type="email" id="email" class="form-control" ngModel name="email" required email>

Now e-mail is not a built-in HTML attribute,

it still is a directive

and keep in mind required is only treated as a selector for an Angular directive here.

An email is simply another directive made available by Angular which makes sure that this is actually

a valid e-mail address.

So now if we save this and we have a look at our form here and I submit it, I can still submit it because

we haven't set up anything which would prevent us from doing so

but if we have a look at it and check the valid attributes, you see it is false.

And if I enter something here and I enter something here,

so it's filled but the e-mail address is still not valid,

you see that still valid is false.

Only if I turn this into a valid e-mail address here, only in this case,

now if we submit it,

now you see valid is true.

So now Angular tracks the state of this form and correctly informs us or gives us a chance of querying

it whether this form is valid or not and actually this does not only work on form level, if we dive into

the actual controls, you'll see that on the e-mail control,

we also have a valid attribute which is true.

So it tracks this on a per control level

and then also on a form level, now there also is another place where it tracks this and helps us.

If we inspect this e-mail element here in the HTML code,

you'll see that it adds a couple of classes because the form-control class here is by us, it's

a Bootstrap class to give it some styling but ng-dirty, ng-touched and ng-valid,

these are not classes added by us and the ng at the beginning makes it pretty clear who is responsible

for adding these classes.

Now watch these classes

if I remove the @ sign here,

you saw that ng-invalid was added and ng-valid was removed.

So Angular dynamically add some classes, giving us information, some CSS classes, giving us information

about the state of the individual control here whether it is dirty or not,

so whether we did change the initial value, whether it touched or not

so whether we clicked into it or not and whether it is valid or not.

Now with that information, we can style these inputs conditionally.

So let's in the next lecture take advantage of the fact that Angular tracks the state of the validity and

of the form overall and change the styling and the behavior the user experience with that form.

Lecture 8 : Built- in Validators & Using HTML 5 Validation




Built-in Validators & Using HTML5 Validation
Which Validators do ship with Angular?


Check out the Validators class: https://angular.io/api/forms/Validators - these are all built-in validators, though that are the methods which actually get executed (and which you later can add when using the reactive approach).


For the template-driven approach, you need the directives. You can find out their names, by searching for "validator" in the official docs: https://angular.io/api?type=directive - everything marked with "D" is a directive and can be added to your template.


Additionally, you might also want to enable HTML5 validation (by default, Angular disables it). You can do so by adding the ngNativeValidate to a control in your template.



Lecture 9 Using the Form State 

In the last lecture we found out that Angular tracks the state of each control of the form, whether it's valid and so on and conditionally also adds these CSS classes.

Now with that information, we can go back to our form and you take advantage of it. Before diving into the CSS classes,

the easiest way of taking advantage is down here on the submit button,

let's disable the button if the form is not valid.

So I'll just split this over multiple lines and add some property binding, I want to bind to the disabled property

which will add the or which will set the disable state of this button to true or false depending on

some condition

and I will specify the condition here.

Now I could set it true here to always disable it,

that of course is not super useful, instead here I want to check whether the form,

remember we do have access to it on this f local reference here,

so if this form is valid, which would be precise

<button class"btn btn-primary" type="submit" [disabled]="!f.valid">Submit</button>

if it is not valid. So if this form is not valid, the button should be disabled and we can actually see

this once this reloads and

now the button is disabled and only if I enter some valid values here, I can hit the submit button again.

So this is the first improvement in place,

the second improvement is to take advantage of these CSS classes.

We do get these classes added automatically, so we can now go to the stylesheet of this app component

and we could say that on ng-invalid, we want to give it a red border,

.ng-invalid
{
    border: 1px solid red;
}

so one pixel solid red.

Sounds like a solid idea, doesn't it?

Well if we do this, you see everything is red

now, the two controls but also the overall form.

The reason for this is that our overall form is also invalid

and that Angular also adds the ng-invalid class, CSS class to the form element.

So a better approach would be to make sure that is not added to the form.

Now there are a couple ways of doing this and it's all just pure CSS logic, one idea would be that

we want to be inside of the form element but then it would still place these red borders around grouping

divs,

we will have a look at what I mean with this later.

So the best way is to simply be explicit that we want to add it on inputs for example

and of course you could also add select here, so input with ng-invalid or select with ng-invalid and which

other elements you have.

Just be creative here,

there are different ways of achieving this goal, in the end you just want to make sure that the border is applied

to the right controls.

Now with this in place, we see that now we only have a red border around the invalid controls but we

do have the border right from the start which is also not great because I at least want to give the

user the chance of changing it before showing a warning, showing that it's wrong.

So a better approach might be to make sure that we only add a red border to an input which has the CSS

class, ng-invalid

and also the CSS class ng-touched, so that the user has to at least click into it. Now by default,

we don't see anything red

even though the form is invalid

but if we click in there and decide yeah I'm done this is my value,

well now you see we have a red border because now we had a chance of changing it,

we didn't change it,

it is invalid

and we want to show this

and with that, we're taking advantage of this form state handled by Angular.

We disable the button and we show a visual feedback to the user.

Now you could of course go much further,

you could also add a warning message below this input here for example and output please enter a valid

value or be more precise than that of course

and add ngIf to conditionally show this if the input value is wrong.

<p *ngIf="">Please enter a valid value</p>

Well this gives us one additional problem though, how do we determine whether this input here or this

control here does hold a wrong value.


Lecture 10: Outputing Validation Error Message:

In the last lecture, we improve the user experience by taking advantage of the form state handled by

Angular.

Now let's improve this even more and let's say we want to output some help text below this input to assist
<input type="email" id="email" class="form-control" ngModel name="email" required email>
<span class="help-block">Please enter a valid email</span>


if there is an invalid value in there.

Now we can use a Bootstrap class here, help-block, to make sure that this has the appropriate styling

and then we could say please enter a valid e-mail.

We only want to show this if an invalid value has been entered into the control

associated with this input though.

Well, a quick and easy way of getting access to the control created by Angular automatically as we added

ngModel to the input is by adding a local reference to this input element here,

for example email, any name you like and associating this now not with ngForm as we did for the overall

form but with ngModel.

So just like the form directive automatically added by Angular when it detects a form element, the

ngModel directive here also kind of exposes some additional information about the control it creates

for us on the overarching form by accessing ngModel.

<input type="email" id="email" class="form-control" ngModel name="email" required email #email="ngModel">
<span class="help-block" *ngIf="!email.valid && email.touched">Please enter a valid email</span>

So with this, we could simply check or say that we want to attach this span here

if e-mail is not valid, so add an exclamation mark at the beginning.

Now with this if this reloads, you'll see that help text

and of course you can improve this by also chaining another condition

that e-mail should have been touched to give the user a chance of changing it.

So now you don't see the warning but if you click in there and click out of there and it is invalid,

you see that warning

and if you now enter a valid data, it disappears.

So this is another way of taking advantage of the state managed by Angular

but this also shows you how you can get a quick and easy access to control added by Angular.

And with that, you should have tools to really provide a pleasant user experience showing the right errors,

the right warnings and styling the form correctly depending on the state of the form.


Lecture 11: Set Default Values with ngModel Property Binding.

How to define some default value should be displayed like in drop down by default nothing is selected so its nice if something is shown by default. 

So we can change they way we add ngModel to select 

<select id="select" class="form-control" [ngModel]="dedaultQuestion" name="secret">

            <option value="pet">Your first Pet</option>
            <option value="teacher">Your first teacher ?</option>

</select>

This dedaultQuestion property can be fined in ts file with pet value 
like this 
dedaultQuestion = 'pet';

Now this first option will show.



Lecture 13: Grouping Form Controls.


Now let's say that on the value object we get when we submit the form, we want to group some things,

for example we want to group the secret and the questionAnswer and the username and e-mail to just have

some structure in our object because for a very big form,

we might want to have such a structure.

This would also be nice if we could then validate the validity, the status of our individual groups of

inputs,

turns out that's easy to do with the template driven approach. Here

on our first group, the username and e-mail, I already have a wrapping div with the ID userData here.

Now you can simply place another directive on it,




the ngModelGroup directive like this and this will now group this into,

well you guessed it, a group of inputs,

however ngModelGroup needs to be set equal to a string.

So for example, the userData,

this will be the key name for this group.

So now if I save this with ngModelGroup added, If I enter value here and here and hit submit and we

have a look at the value of the form, you'll now see that we have a userData field here which holds

another object where we now have e-mail and username.




Now not only did we add this extra field in our value, we also now have a different set up here in controls,

here

we also now have a userData control with all the properties you know on those controls, like valid and

so on.




So if we now simply inspect our HTML code and this div with the ID userData, you'll see that there also

we got the ng-dirty, touched and valid classes added.

So you can now also check the validity of this overall control here for example

which might be a nice feature in your form.

You can also get access to the Javascript representation by again adding a local reference to

the element which holds the ngModelGroup directive,

here for example userData would be a fitting name and then setting this equal to ngModelGroup.

So just like we did before with e-mail which was equal to ngModel, I'm now setting this reference

equal to ngModel group to get access to this Javascript object

and this would allow us to for example output a message if this whole group is not valid.




So we could simply output a paragraph here, userData is invalid which we add if userData, this is the local

reference created here,

if userData is not valid



and let's say it has been touched,

so userData touched is true. With that if this reloads,

you see that we don't see any message

but as soon as I click into one of the fields and then leave it,

you'll see userData is invalid was shown.

So now you really got a very finegrained control over your form with all these tools.


Lecture 14: Handling Radio Buttons

We're nearing the end of the first part of this section, the template driven approach,

there are still some things I want to show you, for example how to work with radio buttons.

We don't have any radio buttons in our form as of now, so let's add some. Let's add a property in the app

component first with some genders.




So this is simply an array where I have male and female and I don't want to insult anyone, I know there

are more genders nowadays, I'm going to go with the classic approach here just to keep it simple.

We have this genders array and now with that array, I want to output genders here,

so let's say below our

your reply paragraph here, I'll add a new div with a class of radio

and this div should be replicated for all the genders.

So I'm going to loop through my genders, maybe bind it to a gender variable and this is just a setup

of Bootstrap uses to give this some nice styling, of course

use any other setup to style your radio buttons here. I'm looping through all the genders

and now again in the bootstrap world, to create a nice looking radio button,

I'm going to wrap it in a label, this input here which is of type radio

and I'm going to wrap this over multiple lines too, just to make it all super simple to read and to understand

and here I will give it a name of gender because in a radio button, I can only select one of them in a group,

so

the name should be gender for whichever button is selected and I will place ngModel on it to make

it a control

and I will prepopulate or I set the value of this button equal to gender,

so this variable of my ngFor loop.

Now with that if we save this, we should see that we have some gender buttons, to output a text,

I need to add it here after my input.

So again, gender here

like that

and now we have male and female here

and if I just enter something so that I can submit the form and I pick male here, you will see that on

the value object here,

we got gender which is male and of course if I pick female, this will, you guessed it. be set to female.

So this is how you can easily incorporate radio buttons by binding or by placing ngModel on the

input as always, setting the value, of course you could also hardcode the value and that well makes

it usable just like any other input.




And if you want to set it to a default gender of course, you can use one-way binding again to make sure

that one of the two buttons is selected by default at the start

when you load the form. You can also of course add the required directive or attribute to that input

here to make sure that now the form will not be valid until one of the two has been selected,

so that works just like on any other input.

So I just want to highlight this because radio buttons can look like a very special case,

they aren't, they are used like any other input when using the template driven approach in your Angular

app.

Angular framework support for Forms

  • Two data Binding
  • Change Tracking
  • Validations
  • Error Handling
  • Unit Testing


Template Driven Forms : Introduction


  • Easy to use
  • Template driven forms are simple and straight forward
  • All the validations, forms elements are all defined in the template file
  • Forms are tracked automatically
  • Tracked form data traverses via various states (pristine etc)
  • Uses Two-Way data binding techniques to bind data.
  • Most of the code resides in template file.
  • Validations are mostly the default HTML5 validations
  • Minimal component code as most of the code is in template file.
  • Unit testing will be a challenge.
  • We will need to import FormsModule in app module to work with template driven forms.

How to use Template Driven Forms

We will need to import FormsModule in app module to work with Template driven forms.

Step #1 - Import and add in the FormsModule in the app.module.ts



  • For template driven forms - FormsModule need to be imported. 
  • If we do NOT import this - We will get error when doing two way data binding. 
  • Add the module into the array list of imports. 

Step #2 - Create the form in app.component.html

  • ngForm
    • Form name as template variable using "#" for e.g #loginForm

  • ngModel
    • Every form field should have a "name" attribute and ngModel attached to it. 

Reference Image





Here in example.component.ts file  we will define that method and we can get value by getting that template reference variable and on template reference variable we have value.fieldname which we defined in input or select or radio with name="that field".

Adding different form fields in template form.

  • Input type = "text"
  • Input type = "radio"
  • Input type = "checkbox"
  • Input type = "email"
  • textarea
  • Select drop down.

Validations in Template Driven Forms


  • Validations are extremely important and integral part of any Forms in apps.
  • In order to prevent unwanted data or junk data we must validate the form fields and it's data entered by the users.
  • Angular provides common validators like minLength, maxLength, required etc.

        Angular maintains state information of the Forms at all times.

  1. ng-touched
  2. ng-untouched
  3. ng-dirty
  4. ng-pristine
  5. ng-valid
  6. ng-invalid

First, Let's see the form object that is always maintained in console log


Ways to Handle Validations in Template Driven Forms.

  • Highligting the errors

            input.ng-invalid.ng-touched{

            background-color:red
            
            }

we can add this property to css and once we enter mouse in input field and step out then it will show as red color but for that we have to define required as attribute to input field.




  •  Disabling the Submit button
    • By adding attribute [disabled]="!formNameTemplateReferenceVariable.valid"    

  • Custom Field Level Validation - Show hide Errors Messages
    • <span *ngIf="fieldName.touched && !fieldName.valid">Define custom error message </span>            

        But to do this we have to do 2 ways data binding means we have also define (template reference variable with ngModel) #fieldName="ngModel".  We have to define in each field. 



Reactive Forms in Angular

Reactive Forms / Dynamic Forms: Introduction


  • Experience is similar to Template Driven Forms
  • Whats different is how we implement, design and handle the form and the data.
  • All the form elements, user interactions and validations are handled in the component class
  • We will make use of Angular's built in formGroup and formControl
  • Using reactive forms we can control better data binding.
  • Exclusive define custom regular expression patterns for error handling
  • We will need to import ReactiveFormsModule in our app module.
  • Very flexible and allows users to define, develop complex requirements for forms.
  • More logic in the component class and less in HTML mark up itself.

        Angular maintains state information of the Forms at all times.

  • ng-touched
  • ng-untouched
  • ng-dirty
  • ng-pristine
  • ng-valid
  • ng-invalid

Reactive Forms in Easy Steps

How to use Reactive Forms

  • Step #1 - Import and Add in the ReactiveFormsModule in the app.module.ts
    • For template driven forms - ReactiveFormsModule needs to be imported.
    • If we do NOT import this - we will get error.
    • Add the module into the array list of imports


  • Step #2 - Create the form in app.component.html
    • FormGroup
      • We need to use the directive FormGroup for the entire form and give it a name.
      • Example: <form [formGroup]="checkoutForm">




    • formControlName
      • Every form field should have a "formControlName" attribute.



  • Step #3 - In the component class - import the required modules.




  • Step #4 - Inject the FormBuilder in the constructor

        constructor(private formBuilder: FormBuilder){}




  • Step #5- Create the form instance

            this.registerForm = formBuilder.group({
            fname: new FormControl(),
            lname: new FormControl()
});



Validations in Reactive Forms

  • Validations are extremely important and integral part of any Forms in apps
  • In order to prevent unwanted data or junk data we must validate the form fields and its data entered by the users
  • Angular provides common validators like minLength, maxLength, required etc.

Three Approaches to handle Validations in Reactive Forms


  • Approach #1 - Highlighting the errors
            input.ng-invalid.ng-touched{
                background-color:red
            }


  • Approach #2 - Disabling the Submit button

            By adding attribute [disabled]="!formName.valid"

            this.registerForm = formBuilder.group({
            fname: ['', Validators.required],
            lname: ['', 
                                [
                                    Validators.minLength(5),
                                    Validators.maxLength(10),
                                    Validators.required,
                                    Validators.pattern('^[a-zA-Z]+$')
                                ]
                        ],
            email:['', [Validators.required, Validators.email]]

})






  • Approach #3 - Custom Field Level Validation - Show Hide Errors Message.


Note: In case of checkbox required doesn't work it need Validators.requiredTrue in ts file while validating. 


Form Group - GET Values:-

  • We can get the values of a form fields/ controls from the form.

  • Syntax to read the value of "entire" form
    • this.formName.value 
    • // this will give values for all the form fields or Formcontrols of the form. 

  • Syntax to read the value of an individual form control
    • this.formName.get('fieldname').value
    • this.formName.value.fieldName 
    • // this field name can be anything from the form name attribute


  • Let's learn it with some hands on examples. 

Form Group - SET Values:-


  • Setting values in the Form - setValue
    • We can SET the values of the entire form using setValue()                
      • We need to set values for each and every field of the form
      • We cannot omit any field in the form.
      • Syntax
        • this.registerForm.setValue({
        • fname: 'ARC',
        • lname: 'Tutorials',
        • email: 'boolment@gmail.com'
        • });


Note: We set values in ngOnInit(){} method

  • Setting Individual Form Field Controls - patchValue
    • We can SET individual fields using patchValue()
      • Syntax:
        • this.registerForm.patchValue({
        • fname: 'ARC',
        • email: 'sridhar@gmail.com'
        • });



Form Group - Reset Forms

Its important that we reset our form to avoid any duplicate values getting added.

Reset Form - reset()

We can reset the entire form using reset() method.

Syntax 

    this.registerForm.reset() 
//We will use reset method to reset the entire form in one shot.





Angular maintains state information of the Forms at all the times.

  • ng-touched
  • ng-untouched
  • ng-dirty
  • ng-pristine
  • ng-valid
  • ng-invalid





        

Which is better - Template driven Forms or Reactive Forms ?



  • Template Driven Forms
    • If your application forms are simple straight forward
    • Fixed static form fields and elements.
    • No complex validations or pattern matching.


  • Reactive Forms
    • If your application forms are complex
    • Uses multiple dynamic components
    • Advanced validations requirements
    • Dependent form elements
    • Dynamic form generation based on user preferences.































Comments

Popular posts from this blog

How do I change the time zone of my Amazon RDS database instance?

As we know bydefault time in the format of UTC in mysql.We can set local time zone to our AWS RDS Instance for our application. or any other time zone prefared Cloud Based Website Hosting Service Provider Steps 1: Go to Services and Select RDS Now to change time zone we have to change "Parameter Group" in left side that is associated with DB instance first we can check default Parameter Group for our instance is Parameter group default.mysql5.7  ( in-sync ) like this. So we have to change the time zone in this Parameter Group.  now open that parameter group (default.mysql5.7)  and click on edit parameter. then search for time_zone (because we want to change it.) then we have to change time_zone only by default it is engine-default (that is utc)  we have to select Asia/Calcutta.  More information we can ref.  https://aws.amazon.com/premiumsupport/knowledge-center/rds-change-time-zone/

Changing the Time Zone on Amazon Linux Ec2 Instance

Amazon Linux instances are set to the UTC (Coordinated Universal Time) time zone by default, but you may wish to change the time on an instance to the local time or to another time zone in your network. Important These procedures are intended for use with Amazon Linux. For more information about other distributions, see their specific documentation. To change the time zone on an instance Identify the time zone to use on the instance. The  /usr/share/zoneinfo  directory contains a hierarchy of time zone data files. Browse the directory structure at that location to find a file for your time zone. [ec2-user ~]$ ls /usr/share/zoneinfo Africa Chile GB Indian Mideast posixrules US America CST6CDT GB-Eire Iran MST PRC UTC Antarctica Cuba GMT iso3166.tab MST7MDT PST8PDT WET Arctic EET GMT0 Israel Navajo right W-SU ... Some of the entries at this location are directo

Digital Marketing

What actually is Digital Marketing? This post will help you understand the insights of Digital Marketing What is Digital Marketing? Digital Marketing is an integral part of the overall marketing strategies of any business. It basically covers the advertisement of products/services/business/brand via digital channels. The digital channels could be of any type like websites, search engines, social media, emails, SMS, and MMS. In case if you're using all these digital channels for the marketing, make sure to have all the statistics & workflow of your campaigns via marketing automation. What are the types of digital marketing? Well, there are 6 core digital marketing types: Search Engine Optimization (SEO) : Search Engine Optimization is nothing but a long-term process of improving your website rankings on search engine results pages (SERPs), which in turn has a wide range of tactics & strategies to implement. Although there is no specific method or a  spec