Here is what I would like to achieve. I would like to create a form, login form for example, where I have some required fields and submit button. I would like to have submit button disabled until the input is valid. I also would like to display invalid input error messages, but not initially. I would like them displayed only after the user starts entering the data. Pretty simple, ha? Here is the solution.
<div class="row" > <div class="span4 offset4"> <div class="well"> <legend>Login</legend> <form name="loginForm" data-ng-submit="login()" novalidate data-ng-controller="loginController" class="control-group"> <div class="alert alert-error hidden"> <a class="close" data-dismiss="alert" href="#">x</a>Incorrect email address or password! </div> <label class="requiredLabel" for="userEmail">Email</label> <input class="span3" placeholder="Enter email address" type="email" id="userEmail" name="userEmail" required data-ng-model="model.userEmail"> <div class="text-error" data-ng-show="loginForm.userEmail.$error.required && loginForm.userEmail.$dirty">Email is required</div> <div class="text-error" data-ng-show="loginForm.userEmail.$error.email && loginForm.userEmail.$dirty">Email is not in a correct format</div> <label class="requiredLabel" for="password">Password</label> <input class="span3" placeholder="Enter password" type="password" id="password" name="password" required data-ng-model="model.password"> <div class="text-error" data-ng-show="loginForm.password.$error.required && loginForm.$dirty">Password is required</div> <button class="btn-info btn" data-ng-disabled="loginForm.$invalid"><i class="icon-user"></i> Login</button> </form> </div> </div> </div>
Here is what the screen looks like.
Let’s break it down line by line. I am putting the form inside “row” class of twitter bootstrap that will ensure my alignment. Div inside of that is using span4 and offset4 classes, centering my form inside basic 12 column grid layout. I am using “well” class to give my form some effects. Then I have a form that Angular will use for validation. I am using simple controller with one “model” property with two fields – userEmail and password, bound to my two input fields. You will notice that I use email input type which will trigger email validation. Right below email I have two error messages – one for email being required, the other one for email being in valid format. I am using ng-show directives to control visibility of my error messages. You clearly see my condition. In case of required email address I am using combination of the field being dirty (edited by user) and field not being filled in. You can get specify error message using the path on format of “formName.inputFieldName.$error.RuleName”. I am using similar technique to disable the button, but instead of checking every field I am checking entire form. Simple, effective and looks decent enough. Let’s take a look at how the form looks when data is not valid. I am using Bootstrap’s text-error class to give my error messages some color.
And here is how it looks properly filed in.