HTML Forms in AngularJS

This tutorial will show you how to collect and validate HTML form data using the two-way data binding of AnguarlJS. In this tutorial, we’ll learn how to implement a simple user registration form using Angular. Along the way, we’ll look at basic HTML and show what needs to be changed in order to incorporate AngularJS.

Prerequisities

Form HTML

The HTML for our signup form is shown below. Bootstrap has been used to make the site more visually appealing.

<html lang="en" ng-app="myApp">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Bootstrap 101 Template</title>
    <link href="css/bootstrap.min.css" rel="stylesheet" />
    <link rel="stylesheet" href="css/app.css" />
  </head>
  <body>
    <form class="form-horizontal" role="form">
      <div class="form-group">
        <label for="inputName3" class="col-sm-2 control-label">Name</label>
        <div class="col-sm-4">
          <input class="form-control" id="inputName3" placeholder="Name">
        </div>
      </div>
      <div class="form-group">
        <label for="inputEmail3" class="col-sm-2 control-label">Email</label>
        <div class="col-sm-4">
          <input class="form-control" id="inputEmail3" placeholder="Email">
        </div>
      </div>
      <div class="form-group">
        <label for="inputPassword3" class="col-sm-2 control-label">Password</label>
        <div class="col-sm-4">
          <input class="form-control" id="inputPassword3" placeholder="Password">
        </div>
      </div>
      <div class="form-group">
        <div class="col-sm-offset-2 col-sm-10">
          <button type="submit" class="btn btn-success">Sign up</button>
        </div>
      </div>
    </form>
    <script src="lib/common/jquery.min.js"></script>
    <script src="lib/common/bootstrap.min.js"></script>
    <script src="lib/angular/angular.js"></script>
    <script src="lib/angular/angular-route.js"></script>
    <script src="js/app.js"></script>
    <script src="js/services.js"></script>
    <script src="js/controllers.js"></script>
    <script src="js/filters.js"></script>
    <script src="js/directives.js"></script>
  </body>
</html>

The form should look like the following image.

Example Form

Collecting Data

In jQuery, individual form inputs are read using code like this:

$('#txtInput').val()

Because AngularJS supports two-way data binding, we don’t need to explicitly read the inputs. Instead, when the form input changes, it is automatically reflected in the controller’s $scope. To verify this, add the following span to the HTML before the closing form tag. This snipper relies on a variable named formInfo.

<span>{{formInfo}}</span>

AngularJS has a directive named ng-model which helps to bind an input to a variable. Let’s apply the ng-model directive to the three input elements in the form. Here is the updated HTML form:

<form class="form-horizontal" role="form">
  <div class="form-group">
    <label for="inputName3" class="col-sm-2 control-label">Name</label>
    <div class="col-sm-4">
      <input class="form-control" id="inputName3" placeholder="Name" ng-model="formInfo.Name">
    </div>
  </div>
  <div class="form-group">
    <label for="inputEmail3" class="col-sm-2 control-label">Email</label>
    <div class="col-sm-4">
      <input class="form-control" id="inputEmail3" placeholder="Email" ng-model="formInfo.Email">
    </div>
  </div>
  <div class="form-group">
    <label for="inputPassword3" class="col-sm-2 control-label">Password</label>
    <div class="col-sm-4">
      <input type="password" class="form-control" id="inputPassword3" placeholder="Password" ng-model="formInfo.Password">
    </div>
  </div>
  <div class="form-group">
    <div class="col-sm-offset-2 col-sm-10">
      <button type="submit" class="btn btn-success">Sign up</button>
    </div>
  </div>
  <span>{{formInfo}}</span>
</form>

As you can see, the ng-model directive has been attached to each of the input elements. Each input is bound to a specific field in the formInfo object. Now, as the user enters data into the input elements, formInfo automatically gets updated. You can see this code in action by looking at this working demo. Using the same formInfo variable we can access the form data without reading each element value individually inside our controller. For that, we need to define a $scope.formInfo variable inside our controller, MyCtrl1. After making these changes, this is what app/js/controllers.js looks like:

'use strict';

/* Controllers */

angular.module('myApp.controllers', []).
  .controller('MyCtrl1', ['$scope', function($scope) {
    $scope.formInfo = {};
    $scope.saveData = function() {

    };
  }])
  .controller('MyCtrl2', [function() {

  }]);

We have also defined a function named saveData() which will be called when the user clicks the Sign Up button.

Next, we need to attach a ng-controller directive to the form itself.

<form class="form-horizontal" role="form" ng-controller="MyCtrl1">

Next, attach a ng-click directive to the Sign Up button:

<button type="submit" ng-click="saveData()" class="btn btn-success">Sign up</button>

Inside the saveData() function, add a console.log($scope.formInfo); just to check if we are getting the form data collection in our controller using the $scope. Restart the node server, browse to the HTML page, and check your browser console. You should see some thing like this:

Object {Name: "Jay", Email: "jay3dec@gmail.com", Password: "helloworld"} 

Now, this collected data can be stored in a database.

Validating the Inputs

We also need to validate, if the data that we received from the $scope is valid. If it’s not, we must show some validation errors. The ng-show directive shows or hides an element based on the value of an expression. We’ll be using it to show error messages. Begin by defining three $scope variables – $scope.nameRequired, $scope.emailRequired, and $scope.passwordRequired. We’ll validate the name, email, and password in the saveData() function as shown in the updated app/js/controllers.js.

'use strict';

/* Controllers */

angular.module('myApp.controllers', [])
  .controller('MyCtrl1', ['$scope', function($scope) {
    $scope.formInfo = {};
    $scope.saveData = function() {
      $scope.nameRequired = '';
      $scope.emailRequired = '';
      $scope.passwordRequired = '';

      if (!$scope.formInfo.Name) {
        $scope.nameRequired = 'Name Required';
      }

      if (!$scope.formInfo.Email) {
        $scope.emailRequired = 'Email Required';
      }

      if (!$scope.formInfo.Password) {
        $scope.passwordRequired = 'Password Required';
      }
    };
  }])
  .controller('MyCtrl2', [function() {

  }]);

In the HTML page, add a span for each input element to display error message as shown below;

<span ng-show="nameRequired">{{nameRequired}}</span>
<span ng-show="emailRequired">{{emailRequired}}</span>
<span ng-show="passwordRequired">{{passwordRequired}}</span>

Restart the node server and try to click the Sign Up button with empty input elements. You should see the appropriate error messages.

Conclusion

In this tutorial, we learned how to read data from a form and validate it using AngularJS. I would recommend reading the AngularJS API docs for deeper insight. In the meantime, a working demo is available here.

Win an Annual Membership to Learnable,

SitePoint's Learning Platform

  • ggsp

    I think you’re last snippet should use ‘emailRequired’ for the ng-show on email and ‘passwordRequired’ for the password one.

    Otherwise, good stuff.

    • http://www.techillumination.in Jay

      thnks..corrected :)

  • http://www.techillumination.in Jay

    Thnks for the feedback Simon. This article mainly focused on how to collect data from Angular form. As far as validation and stuff is considered, you are right, AngularJS handles most of the validation using attributes like required, maxlength etc.What i showed here is just a way to handle custom validations like say…to check if an entered number is in a particular format or any other validation like that. So to validate that I believe you have to validate it the way i did. Off course i only checked for empty data but that can be extended for other complex validations. :)

  • http://www.techillumination.in Jay

    Thanks for the feedback. What i showed here is a way to do some complex validations although I just checked for empty data. But it can be extended for complex validations. :)

  • http://learnwebtutorials.com Blissful Writer

    I think there is a syntax error with the two “dots” (one at the end of the first row and another at the beginning of the second row) here …

    angular.module(‘myApp.controllers’, []).
    .controller(‘MyCtrl1′, [‘$scope’, function($scope) {

    Also what I like to do is to add an “else-clause” here …

    if (!$scope.formInfo.Name) {
    $scope.nameRequired = ‘Name Required';
    } else {
    $scope.nameRequired = ”;
    }

    to clear out the error after the user corrects the missing value.

  • http://medium.com/@christianramsey Christian Ramsey

    In AngularJS version 1.2.15 it seems that the custom form validation needs different casing in the controller.

    if (!$scope.formInfo.Email) {

    if (!$scope.formInfo.email) { // E to e -> should be lowercase

    $scope.emailRequired = ‘Email Required';

    }

    Unless this is some other type of bug.