Let‘s build a signup form. This signup form will include the person‘s name, their email, and a desired username.
Let‘s start by looking at what the form will look like when it‘s done. Go ahead, play with it, start typing in the input fields, see how the form responds and reacts. Notice that the submit button becomes disabled when the form goes invalid:
Signup form Your name Your email
Username
Submit
Let‘s start with defining the form:
<form name="signup_form" novalidate ng-submit="signupForm()">
<fieldset>
<legend>Signup</legend>
<button type="submit" class="button radius">Submit</button>
</fieldset>
</form>
This form‘s name is signup_form and we are going to call signupForm() when the form is submitted.
Now, let‘s add the name of the user:
<div class="row">
<div class="large-12 columns">
<label>Your name</label>
<input type="text"
placeholder="Name"
name="name"
ng-model="signup.name"
ng-minlength=3
ng-maxlength=20 required />
</div>
</div>
Try it
Your name
Breaking this down. First thing to note is that I use Foundation for my css layouts, so you‘ll see that syntax is my forms. We added a form that has an input called name that is bound (by ng-model) to the object signup.name on the $scope object.
We also setup a few validations. These validations say we have to have a minlength of our name of 3 or more characters. We also impose a maximum limit of characters of 20
characters (this will be invalid at 21 characters and higher). Lastly, werequire that the name be filled out for the form to be valid.
Let‘s use the properties to show and/or hide a list of errors if the form is invalid. We‘ll also use the $dirty attribute to make sure the errors don‘t show up if the user hasn‘t touched the field:
<div class="row">
<div class="large-12 columns">
<label>Your name</label>
<input type="text"
placeholder="Name"
name="name"
ng-model="signup.name"
ng-minlength=3
ng-maxlength=20 required />
<div class="error"
ng-show="signup_form.name.$dirty &&
signup_form.name.$invalid">
<small class="error"
ng-show="signup_form.name.$error.required">
Your name is required.
</small>
<small class="error"
ng-show="signup_form.name.$error.minlength">
Your name is required to be at least 3 characters </small>
<small class="error"
ng-show="signup_form.name.$error.maxlength">
Your name cannot be longer than 20 characters </small>
</div>
</div>
</div>
Try it
Your name
Breaking this down, we‘re only going to show our errors if the form is invalid and changed, just as before. This time, we‘ll look through each of the valiations and only show a particular DOM element if the particular validation property is invalid.
Let‘s look at the next set of validations, the email validation:
<div class="row">
<div class="large-12 columns">
<label>Your email</label>
<input type="email"
placeholder="Email"
name="email"
ng-model="signup.email"
ng-minlength=3 ng-maxlength=20 required />
<div class="error"
ng-show="signup_form.email.$dirty &&
signup_form.email.$invalid">
<small class="error"
ng-show="signup_form.email.$error.required">
Your email is required.
</small>
<small class="error"
ng-show="signup_form.email.$error.minlength">
Your email is required to be at least 3 characters </small>
<small class="error"
ng-show="signup_form.email.$error.email">
That is not a valid email. Please input a valid email.
</small>
<small class="error"
ng-show="signup_form.email.$error.maxlength">
Your email cannot be longer than 20 characters </small>
</div>
</div>
Try it
Your email
This time (with the entire form included), we‘re looking at the email field. Note that we set the type of the input field to emailand added a validation error on $error.email. This is based off the AngularJS email validation (and the HTML5 attribute).
Finally, let‘s look at our last input field, the username:
<div class="large-12 columns">
<label>Username</label>
<input type="text"
placeholder="Desired username"
name="username"
ng-model="signup.username"
ng-minlength=3 ng-maxlength=20
ensure-unique="username" required />
<div class="error" ng-show="signup_form.username.$dirty &&
signup_form.username.$invalid">
<small class="error"
ng-show="signup_form.username.$error.required">Please input a username</small>
<small class="error"
ng-show="signup_form.username.$error.minlength">Your username is required to be at least 3 characters</small>
<small class="error"
ng-show="signup_form.username.$error.maxlength">Your username cannot be longer than 20 characters</small>
<small class="error"
ng-show="signup_form.username.$error.unique">That username is taken, please try another</small>
</div>
</div>
Try it
Username
In our last field, we‘re using all the same previous validations, with the exception that we‘ve added our custom validation. This custom validation is defined using an AngularJS directive:
app.directive('ensureUnique', ['$http', function($http) { return {
require: 'ngModel',
link: function(scope, ele, attrs, c) { scope.$watch(attrs.ngModel, function() { $http({
method: 'POST',
url: '/api/check/' + attrs.ensureUnique,
data: {'field': attrs.ensureUnique}
}).success(function(data, status, headers, cfg) { c.$setValidity('unique', data.isUnique);
}).error(function(data, status, headers, cfg) { c.$setValidity('unique', false);
});
});
} } }]);
When the form input is valid, this will make a POST request check to the server
at /api/check/username to check if the username is available. Now, obviously since we‘re only talking about front-end code here, we don‘t have a backend to test this on, although it could easily be written.
Update: As per a discussion in the comments, I‘ve added an update using the $timeout service. To check out that full source, check it out here.
Lastly, putting our button together, we can use the angular directive ng-disabled to disable and reenable the button when the form is valid:
<button type="submit" ng-disabled="signup_form.$invalid"
class="button radius">Submit</button>
As we said above, the form itself will have a $invalid and valid attributes given to us for free.
Update 2: Although live validation is great, it can be abrasive to the user when they see errors pop-up while they are typing, long before they have put in a valid value. You can be nicer to your users if you show the validations either only after they have submitted the form or after they have moved off of the input. Let‘s look at both ways to do that.