Displaying Error Messages
What can we do with all these validators? We can of course check the validity of the form, and disable the Save or Update button accordingly. But we also want to tell the user what went wrong and how to fix it. AngularJS offers two things to solve this problem:
- A model that reflects what exactly is wrong in the form, which we can use to display nicer error messages
- CSS classes automatically added and removed from each of these fields allow us to highlight problems in the form
Let’s first take a look at how to display specific error messages based on the problem with the following example:
Nothing in the controller has changed in this example compared with the previous post. Instead, we can just focus on the form HTML. Let’s see what changed with the form:
- First, we added the name attribute to both the input fields where we needed validation: uname for the username box, and pwd for the password text field.
- Then we leverage AngularJS’s form bindings to be able to pick out the errors for each individual field. When we add a name to any input, it creates a model on the form for that particular input, with the error state.
- So for the username field, we can access it if the field was not entered by accessing myForm.uname.$error.required. Similarly, for ng-minlength, the field would be myForm.uname.$error.minlength. For the password, we look at myForm.pwd.$error.required to see if the field was filled out or not.
- We also accessed the state of the input, similar to the form, by accessing myForm.uname.$invalid. All the other form states ($valid, $pristine, $dirty) we saw earlier are also available similarly on myForm.uname.
With this, we now have an error message that shows only when a certain type of error is triggered. Each of the validators we saw in the Table of previous post exposes a key on the $error object, so that we can pick it up and display the error message for that particular error to the user. Need to show the user that a field is required? Then when the user starts typing, show the minimum length, and then finally show a message when he exceeds the maximum length. All these kinds of conditional messages can be shown with the AngularJS validators.
Styling Forms and States
We saw the various states of the forms (and the inputs): $dirty, $valid, and so on. We saw how to display specific error messages and disable buttons based on these conditions, but what if we want to highlight certain input fields or form states using UI and CSS? One option would be to use the form and input states along with the ng-class directive to, say, add a class dirty when myForm.$dirty is true. But AngularJS provides an easier option.
For each of the states we described previously, AngularJS adds and removes the CSS classes shown below to and from the forms and input elements.
Table below defines Form state CSS classes
|Form state||CSS class applied|
Similarly, for each of the validators that we add on the input fields, we also get a CSS class in a similarly named fashion, as demonstrated in the below table.
Table below defines Input state CSS classes
|Input state||CSS class applied|
|required||ng-valid-required or ng-invalid-required|
|min||ng-valid-min or ng-invalid-min|
|max||ng-valid-max or ng-invalid-max|
|minlength||ng-valid-minlength or ng-invalid-minlength|
|maxlength||ng-valid-maxlength or ng-invalid-maxlength|
|pattern||ng-valid-pattern or ng-invalid-pattern|
|url||ng-valid-url or ng-invalid-url|
|ng-valid-email or ng-invalid-email|
|date||ng-valid-date or ng-invalid-date|
|number||ng-valid-number or ng-invalid-number|
Other than the basic input states, AngularJS takes the name of the validator (number,maxlength, pattern, etc.) and depending on whether or not that particular validator has been satisfied, adds the ng-valid-validator_name or ng-invalid-validator_name class, respectively.
Let’s take an example of how this might be used to highlight the input in different ways:
In this example, we kept the existing functionality of the validators, though we removed the specific error messages. Instead, what we try to do is mark out the required field using CSS classes. So here is what the example accomplishes:
- When the field is correctly filled out, it turns the input box green. This is done by setting the background color when the CSS class ng-valid is applied to our input field.
- We want to display the background as dark red if the user starts typing in, and then undoes it. That is, we want to set the background as red, marking it as a required field, but only after the user modifies the field. So we set the background color to be red if the CSS classes ng-dirty (which marks that the user has modified it) and ng-invalid-minlength (which marks that the user has not typed in the necessary amount of characters) are applied.
Similarly, you could add a CSS class that shows a * mark in red if the field is required but not dirty. Using a combination of these CSS classes (and the form and input states) from before, you can easily style and display all the relevant and actionable things to the user about your form.