Angular 2 Template Driven Validation

Last week’s post covered model driven validation in Angular 2 and this week I will be looking at template driven validation. Template driven validation provides a simplified way to add validation without the need to directly use a control group. This is a great way to get up and running for simple form cases, and maybe more complex ones as well. I haven’t hit a case yet that wouldn’t work with either validation style.

Building a Template Form with Validation

I started with a simple form that contains labels and inputs for entering a name and email address that are bound to corresponding values in the associated model.

The next example is the same form with validation added.

The first change you will notice is that the form now has a name assigned using  #contactForm="ngForm". In this case the name is not used, but it could be used to disable a submit button if any of the inputs the form contained didn’t have valid values. I am sure there are a lot more use cases as well.

On the inputs that need validation a controls name is assigned via  ngControl="name" and a name is assigned using  #nameControl="ngForm". I had some trouble withe assigning names to my inputs at first I keep getting the following.

The cause of the issue was that I was trying to use  #name for the control name which was already a property on the model. Once I changed to  #nameControl all worked fine.

For the input for name above  required minlength="3" tells the Angular form that the input is required and must be at least three characters in length.

Displaying Validation

For the name input you can see that it has two divs used to show specific messages based on which validation condition failed.

I am not sure why, but when using the template style validation I had to check  !nameControl.errors in addition to the specific error like  !nameControl.errors.required or I would get an exception when the page tried to load. If your control doesn’t have more than a single validation then  nameControl.valid would be a sufficient condition for showing validation messages.

Custom Validators

I am going to use the same email validator from last week with a few changes so can be used from a template. The following is the full class.

The biggest difference is the  @Directive decorator. The selector is the attribute that will be used to mark that an input needs to pass the specified validation. I am not 100% sure of the specifics of the provider, but the above works. This is another topic I need to explore more.

Using a Custom Validator

First in the model the validator must be imported.

Then the validator needs to be added to the directives section of the @Component decorator.

To use in the view just add the emailValidator selector to the proper input.

Finally add a div to display the error.

Wrapping Up

Using template driven validation you can quickly get a form validated without having to make changes outside of your template (unless you are using a custom validator). Angular 2 offers a lot of options when it comes to validation and where it should be put.

Angular 2 Model Driven Validation

In this post a couple of weeks ago I covered Aurelia’s new validation plugin and I thought it would be good to see what Angular 2 has to offer validation wise. Angular’s offering is vastly different that Aurelia. Angular can use model driven or template driven validations. This post is going to look at the model driven style.

Forms

Angular forms is the framework’s way to handle groups of data entry that need support for data binding and validation among other things.

Building a Form with Validation

The first step to building a model driven form is import the classes that will be needed.

Next add a variable for control group and setup the control group in the constructor of the class.

The above uses FormBuilder to define a name property that is required with a minimum length of three characters and an email property that is required. Later in the post I will add better email validation via customer validator.

Angular 2 only comes with required, minimum length, max length and pattern (match given regex) validators out of the box. Thankfully custom validators are pretty easy to implement.

Using a From with a View

Now that the form is setup the view needs to utilize it. The following is the code form the view.

First notice in the form tag  [ngFormModel]="contactForm" is used to bind the form to the control group crated in the model.

Instead of  [(ngModel)]="name" we use  ngControl="name" to bind the input box to the name control in the control group that was crated using the form builder above.  #name="ngForm" defines  name as a variable that can be used later.

<div [hidden]="name.valid || name.pristine || !name.errors.required">Required</div>  is used to display validation errors to the user. This code is just saying to hide the div if name is valid or pristine (not changed by the user)  or if the validation error is not because the field is required. While this style works I much prefer Aurelia as it handles the extra work needed to automatically display validation errors.

Custom Validators

As I mention above I am going to show you a custom validator that can be used to better handle email validation. Most of this validation I found in a search but unfortunately I forgot to save the URL so I can’t link to the exact source. The following is the complete code for a custom email validator.

Note that returning null means that validation passed.

Using a Custom Validator in a Model

First the custom validator needs to be imported.

Now the validator can be used in the classes form builder.

Notices that the email control is now using  Validators.compose which is used to apply multiple validations to a single control.

Using a Custom Validator in a View

Now the view just has to be changed to show the user that the reason for the failed validation is an invalid email address.

Note that the entry in errors will match the return value from the custom validator. I had issues trying to use the minimum length validator because I was trying to use  minLength instead of  minlength. If you are having trouble with validation message showing up that would be the first thing to check.

Wrapping Up

That covers the basics of model driven validation in Angular 2. Be on the look out for a post in the future that covers the same concepts but using a template driven approach. I also wanted to point out this post by Pascal Precht and this post by David Den Toom which helped me a lot in writing this post.

Aurelia Validation the Replacement Library

The post from last week on Aurelia Validation is now useless as this blog post from the Aurelia team states validation has been completely overhauled. This post is going to feel very similar to last weeks, but using the new validation library. The details on adding a main.js will match exactly from last weeks post, but is being included to make sure the examples in this post are complete.

Installation

Validation in Aurelia is provided using a plugin in which must be installed before being used. Make sure you have npm and jspm installed. For more information on getting up and running with Aurelia check out this post that will guide you through the process and links to a Github repo with matching code.

From the console execute this command  jspm install aurelia-validatejs to download and install the files needed for validation.

In order to load plugins a named Aurelia-App is need to allow more control of the bootstrapping process. In Views/Home/Aurelia.cshtml make the following change.

Now that this Aurelia application has been named “main” Aurelia will look for a matching main.js file and call its  configure function during the bootstrapping process. Here is the main.js I am using. Note that the validation plugin in is being loaded. For my project main.js is located in wwwroot/Aurelia.

Usage

The first step in using validation is to add its import to the top of the class that will be using it.

Next setup the validation rules using decorators and inject validation via the constructor and set up the validation rules. The plugin also supports a fluent style of adding validation to property, but I ran into issues getting it working so I just stuck with decorators for this post.

The above makes sure that Name is required and that email is required and conforms to the rule of what an email address. This is only a small sample of the built in validations provided by check out this page for a sample of the other provided validations.

Show Validation Failures in a View

The validation plugin in provides a way to display validation messages with the appropriate field. The following is a part of a view that contains name and email address that are bound to the properties from above.

By adding  & validate as part of the value bind statement the plug in knows where the validation messages show be shown.

Warning

If you run into a “Cannot read property ‘bindingContext’ of null” when trying to implement the new validation plugin make sure your class constructor contains:

From what I can tell this requirement will be temporary. This is an alpha release of the overhaul and has a few rough edges such as the binding context gotcha and the fluent API issues I mentioned above. With the track record of the Aurelia team I am sure the issues I hit will be resolved quickly.

Aurelia Validation

Update: this post is now out of date an updated version can be found here.

Client side validation is an important part of client side frameworks and can provide users with immediate feedback as well as check away to stop before posting data to the server. This post is going to look at validation with in Aurelia.

Installation

Validation in Aurelia is provided using a plugin in which must be installed before being used. Make sure you have npm and jspm installed. For more information on getting up and running with Aurelia check out this post that will guide you through the process and links to a Github repo with matching code.

From the console execute this command  jspm install aurelia-validation to download and install the files needed for validation.

In order to load plugins a named Aurelia-App is need to allow more control of the bootstrapping process. In Views/Home/Aurelia.cshtml make the following change.

Now that this Aurelia application has been named “main” Aurelia will look for a matching main.js file and call its  configure function during the bootstrapping process. Here is the main.js I am using. Note that the validation plugin in is being loaded. For my project main.js is located in wwwroot/Aurelia.

Usage

The first step in using validation is to add its import to the top of the class that will be using it.

Next the inject validation via the constructor and set up the validation rules.

The above makes sure that Name is required and has a length between 3 and 50 characters and that email is required and conforms to the rule of what an email address contain. This is only a small sample of the built in validations provided by check out this page for a demo of the other provided validations.

Show Validation Failures in a View

The validation plugin in provides a custom attribute that will loop all nested child elements and display validation messages with the appropriate field. The following is a part of a view that contains name and email address that are bound to the properties from above.

You can see that the validate custom attribute is bound to the validation property of the class defined above. Since the controls are in a form group the validation plugin is able to infer where bound field is show validation errors in the appropriate area. Check out this page for more details on visualization of validation errors. The default visualization is based on Twitter Bootstrap, but that can be changed the details of which can be found here.

Issues

Unfortunately I ran into some problems with trying to implement validation in a more complex situation dealing with an object that is replaced via binding. I doubt this is a problem with Aurelia. If anyone has any experience with validation on objects that are fully replaced via binding please let me know. Expect a blog post once I get my issue figured out.