Wednesday 31 July 2013

Form Validation in AngularJS

Every Web application will need a sort of validation before user enter submit button. This usually makes a round trip travel of the data to the server.
For example user fill form, then submit the form to the server. After checking in server, there were errors and the form sent back to the user with error message for the user to fix.

This give an unnecessary round trip request to the application server. In AngularJS, we minimize the roundtrip request to the server, because AngularJS tend to be Ajax application with REST api backend.
We validate the form input from the user before submitted to the server. But remember, we cannot depends on client side validation, which is easily to bypass. We just provide a better user experience in the application by giving error message before user even submit the data to the server. This also ease the burden in the server to process invalid input.

AngularJS provide a great way to validate the form. It is easier to do a form validation with interactive user experience using javascript. You have done the validation in client side using javascript plugin right? Many type of plugin i have used, but i am not bother to know how it works, just include the plugin and do what it specified.

With AngularJS we can do better and more interactive. So now move on to the code.
Let say we have a form :

  <form id="ArticleForm" class="form-horizontal" novalidate method="post" name="ArticleForm"  ng-submit="saveArticle()">

    <legend>

      <h2>

        <span data-ng-bind="page.action">

          Article

        </span></h2>

    </legend>

   
 <div class="alert alert-{{page.result}} ng-cloak" 
data-ng-animate="'myFade'" data-ng-show="page.showMsgBox" 
data-ng-cloak>

      <button class="close" data-ng-click="page.showMsgBox=false" type="button"></button>

        {{page.message}}

    </div>

    <div class="control-group">

      <label class="control-label">

        Title

      </label>

      <div class="controls">

        <input id="id" class="" type="hidden" ng-model="article._id" name="id"></input>

       
 <input id="title" class="input-xlarge" type="text" 
ng-model="article.title" placeholder="Title" required name="title" ></input>

        <span ng-show="ArticleForm.title.$valid"><i class="icon-checkmark-3-green"></i></span>

       
 <span class="error" ng-hide="!(ArticleForm.title.$error.required 
&& ArticleForm.title.$dirty)"><i 
class="icon-cancel-3-red"></i>&nbsp;Please enter Article 
Title</span>

      </div>

    </div>

  <div class="control-group">

       <label class="control-label"></label>

       <div class="controls">

        
 <button class="btn btn-success" 
data-ng-disabled="!ArticleForm.$valid" ng-submit="saveArticle()" 
data-ng-bind="page.action" data-ng-hide="noSubmit" type="submit">

           Create Article

         </button>

       </div>

     </div>

</form>


Lets analyze the form :
  1.  Make sure add novalidate directive in form
    This will prevent default HTML5 validation 
  2. Use requred in the input control
  3. To use the validation status, there are 4 status of the input
    $pristine   : The input not have been touch
    $dirty       : The input already modified by user
    $valid       : The input is valid
    $invalid    : The input is invalid
    To access the variable :
    ArticleForm.title.$pristine
    ArticleForm.title.$dirty
    ArticleForm.title.$valid
    ArticleForm.title.$invalid
  4. After user submit, you will need to reuse the form and reset the form validation status. you can just reset the pristine status of the form.
    $scope.ArticleForm.$setPristine();
The $setPristine() function is usefull to reset all the status, it means also reset your form alert. This function can be found after angular 1.1.1 .
Here are the patch AngularJS $setPristine() update  you can see what it do inside AngularJS.

My selft use it to reset the form validation status to a new fresh state as it just loaded.

And also for the bonus the css style for the form :

.error{
color:red;
}
span.ok, span.ko
{ display:none; float: right; font-size:34px; margin-top: -13px;
}
input.ng-pristine{
border:1px solid Gold;
}
input.ng-dirty.ng-valid
{border:1px solid Green; }
input.ng-dirty.ng-invalid { border:1px solid Red; }
input.ng-dirty.ng-valid ~ span.ok { color:green; display:inline; }
input.ng-dirty.ng-invalid ~ span.ko { color:red; display:inline; }


Just remember, you still need the input validation in server side.

0 comments:

Post a Comment

Twitter Delicious Facebook Digg Stumbleupon Favorites More