} }

Hello everyone. Many of us are using Jquery to manipulate DOM and for making Ajax requests to interact with the server. While building websites, we start with a basic layout and add as many features as possible. If we do that in plain JavaScript that project becomes clumsy and ahrd to maintain.

What is Angular JS?

In simple words

AngularJS's main deal is:

  • to decouple DOM manipulation from application logic. The difficulty of this is dramatically affected by the way the code is structured.
  • to decouple the client side of an application from the server side. This allows development work to progress in parallel, and allows for reuse of both sides.
  • to provide structure for the journey of building an application: from designing the UI, through writing the business logic, to testing.

Using Angular JS we can do Dom manipulation on the fly. Using it's templating style of programming and two way data communication we can build intelligent single page web applications.

Building Interactive Mark Sheet using Angular JS

Code

The total code for this web application can be found at https://github.com/narenaryan/Angular-Mark-Sheet

Working Demo

You can find the working demo here. http://narenaryan.github.io/Angular-Mark-Sheet/

People always complain about Angular saying it got 100 features. But if we are able to use 5 or 10 basic features, our web application can be more interactive. Even though there are advanced concepts like routing, factories and services in angular JS, atleast it's directives and templating can make our life easy.

We are going to build an Interactive web application for an enthusiastic teacher. My theme of this article is to show the magic of Angular JS.

Our app consists of a HTML file and a JS file called app.js.

index.html

<!doctype html>
<html>
   <head>
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
      <script src="app.js"></script>
      <link rel="stylesheet" href="http://bootswatch.com/darkly/bootstrap.min.css">
   </head>
   <body>
   </body>
</html>

Now create a file in same directory called app.js

app.js

app = angular.module('app', [])

app.controller('MainController', function($scope) {

});

In angular JS, app is the skeleton of the application. An app can have one or more controllers which actually controls the code that in turns manipulates HTML. In above file we declared app as

app = angular.module('app', [])

Here angular.module is the angular function to create an app. The second argument is list of other apps whose functionality can be used here. For now we don't have any related app.

app.controller('MainController', function($scope) {

});

We are defining a controller function on app "app". "MainController" is it's name and second argument is the function with a $scope variable.

$scope variable and it's importance

$scope variable is the central concept of Angular JS. It is a special global object which shares the context of both HTML and JS. It means that object is visible to both files. All we need to do is to attach our variables to it and use them. We are going to see that by adding more functionality.

Now modify app.js to add a student list.

app.js

app = angular.module('app', [])

app.controller('MainController', function($scope) {
      $scope.fields = ["Name", "Social studies", "Maths", "Science"]
      $scope.students = {data:[
                          {
                            name: "Naren", 
                            social:60, 
                            maths:87, 
                            science:85
                          },
                         {
                            name:"Saikiran",
                            social:80, 
                            maths:70, 
                            science:98
                          },
                          {
                            name:"Rajesh",
                            social:90, 
                            maths:90, 
                            science:78
                          }
                        ]} ;
      $scope.data_count = $scope.students.data.length;

    });

We just attached three variables called fields, students, and data_count(total students) to $scope

  • fields - The headers of Mark Sheet Table
  • students - Student marks details
  • data_count - Total number of student records

We are going to use these variables in our HTML to render a table by iterating the students array. I can use the JSON data which is supplied by server. Static data is just for illustration purpose.

index.html

<!doctype html>
<html>
   <head>
      <!-- Angular JS scripts -->
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.4/angular.min.js"></script>
      <script src="app.js"></script>
      <!-- These scripts are just for launching Modal -->
      <script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
      <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
      <link rel="stylesheet" href="http://bootswatch.com/darkly/bootstrap.min.css">
   </head>
   <body ng-app="app" ng-controller="MainController">
      <div class="container">
         <div class="row">
            <div class="col-md-4">
               <p class="bs-component">
               <h2>Nerds Mark Sheets</h2>
               </p>
               <p class="bs-component">
                  <button type="button" class="btn btn-info" data-toggle="modal" data-target="#myModal">Add Student</button>
               </p>

               <div id="myModal" class="modal fade" role="dialog">
                 <div class="modal-dialog">

                   <!-- Modal content-->
                   <div class="modal-content">
                     <div class="modal-header">
                       <button type="button" class="close" data-dismiss="modal">&times;</button>
                       <h4 class="modal-title">Enter Student Details</h4>
                     </div>
                     <div class="modal-body">
                       <div class="form-group">
                          <label for="name">Enter Name:</label>
                          <input type="text" class="form-control" id="name">

                          <label for="social">Social Score:</label>
                          <input type="text" class="form-control" id="social">

                          <label for="maths">Mathematics Score:</label>
                          <input type="text" class="form-control" id="maths">

                          <label for="science">Science Score:</label>
                          <input type="text" class="form-control" id="science">
                       </div>
                     </div>
                     <div class="modal-footer">
                       <button type="button" ng-click="add_student()" class="btn btn-default" data-dismiss="modal">Submit</button>
                     </div>
                   </div>
                 </div>
            </div>
         </div>
            <div class="col-md-4">
               Total students: <span ng-bind="data_count"></span>
            </div>
         </div>
         <div class="row">
            <table class="table table-striped table-hover ">
               <thead>
                  <tr class="success">
                     <th ng-repeat = "field in fields">
                        {{ field }}
                     </th>
                  </tr>
               </thead>
               <tbody>
                  <tr ng-repeat = "student in students.data">
                     <td ng-repeat = "property in student">
                        {{ property }}
                     </td>
                  </tr>
               </tbody>
            </table>
         </div>
      </div>
   </body>
</html>

Let us analyze different angular directives used this HTML file.

1.ng-app

It is used to load the app into the context of html file. In above HTML we added ng-app to body tag.

2.ng-controller

It is the controller which actually injects $scope into HTML.Here we are adding it to same body tag. If we want to restrict it's effect to certain section of code, then add controller to a div tag.

3.ng-bind

This directive is used to attach a value of a variable in $scope to a or visual HTML element. But amazing thing here is changes will reflect on HTML element, if it's value is changed in controller.

4.ng-click

This directive is used to invoke a function that we declare in controller. It is equivalent to adding a button click handler using JQuery. But here we add function on tag itself.

5.ng-repeat

This directive is used to repeat the rendering of same HTML elemnts with different data. Using this we can iterate over a List or Object and inject that data into HTML elements.

At this point of time HTML file in browser looks like this.

If you observe above HTML code there is one strange function in ng-click called add_student(). We need to add a function called add_student in the controller so that whenever "Add student" button is clicked it will launch a modal and inputs data from User. Once data is submitted it should be reflected in UI.

Now just add this below function $scope to controller in app.js.

  $scope.add_student = function()
  {
      // Get modal values using Angular's jqLite
      var name = angular.element(document.querySelector("#name"));
      var social_mark = angular.element(document.querySelector("#social"));
      var math_mark = angular.element(document.querySelector("#maths"));
      var science_mark = angular.element(document.querySelector("#science"));

      // Push data to students scope object. Magically UI will be updated too.

      $scope.students.data.push(
          {
              name: name.val(),
              social: social_mark.val(),
              maths: math_mark.val(),
              science: science_mark.val()
          }
      );

      // Update student count.
      $scope.data_count += 1;

      // Clear modal
      name.val("");
      social_mark.val("");
      math_mark.val("");
      science_mark.val("");

  }

In this function we are collecting data from Modal and pushing them to $scope.students.data array. The UI will be updated too. Code is performing following tasks respectively.

  • Get data from model using Angular Jqlite
  • Store them in the students object
  • Increment student count
  • Clear Modals for next use

The total app.js looks like this.

app.js

app = angular.module('app', [])

app.controller('MainController', function($scope) {
      $scope.fields = ["Name", "Social studies", "Maths", "Science"]
      $scope.students = {data:[
                          {
                            name: "Naren", 
                            social:60, 
                            maths:87, 
                            science:85
                          },
                         {
                            name:"Saikiran",
                            social:80, 
                            maths:70, 
                            science:98
                          },
                          {
                            name:"Rajesh",
                            social:90, 
                            maths:90, 
                            science:78
                          }
                        ]} ;
      $scope.data_count = $scope.students.data.length;


      $scope.add_student = function()
      {
          // Get modal values using Angular's jqLite
          var name = angular.element(document.querySelector("#name"));
          var social_mark = angular.element(document.querySelector("#social"));
          var math_mark = angular.element(document.querySelector("#maths"));
          var science_mark = angular.element(document.querySelector("#science"));

          // Push data to students scope object. Magic is UI will be updated too.

          $scope.students.data.push(
              {
                  name: name.val(),
                  social: social_mark.val(),
                  maths: math_mark.val(),
                  science: science_mark.val()
              }
          );

          // Update student count.
          $scope.data_count += 1;

          // Clear modal
          name.val("");
          social_mark.val("");
          math_mark.val("");
          science_mark.val("");

      }

});

Now open HTML file in the browser and try to add new student by clicking the button. You will see this kind of modal.

Now when you submit data instantly you see that UI got updated with student Vaishnav neatly.

Adding Average Calculator for Columns

Let us add some more spice to this. Let us display the subject average mark of all students so that teacher gets idea of in which subject students did well.

So modify HTML to this.

index.html

<!doctype html>
<html>
   <head>
      <!-- Angular JS scripts -->
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
      <script src="app.js"></script>
      <!-- These scripts are just for launching Modal -->
      <script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
      <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
      <link rel="stylesheet" href="http://bootswatch.com/darkly/bootstrap.min.css">
   </head>
   <body ng-app="app" ng-controller="MainController">
      <div class="container">
         <div class="row">
            <div class="col-md-4">
               <p class="bs-component">
               <h2>Nerds Mark Sheets</h2>
               </p>
               <p class="bs-component">
                  <button type="button" class="btn btn-info" data-toggle="modal" data-target="#myModal">Add Student</button>
               </p>

               <div id="myModal" class="modal fade" role="dialog">
                 <div class="modal-dialog">

                   <!-- Modal content-->
                   <div class="modal-content">
                     <div class="modal-header">
                       <button type="button" class="close" data-dismiss="modal">&times;</button>
                       <h4 class="modal-title">Enter Student Details</h4>
                     </div>
                     <div class="modal-body">
                       <div class="form-group">
                          <label for="name">Enter Name:</label>
                          <input type="text" class="form-control" id="name">

                          <label for="social">Social Score:</label>
                          <input type="text" class="form-control" id="social">

                          <label for="maths">Mathematics Score:</label>
                          <input type="text" class="form-control" id="maths">

                          <label for="science">Science Score:</label>
                          <input type="text" class="form-control" id="science">
                       </div>
                     </div>
                     <div class="modal-footer">
                       <button type="button" ng-click="add_student()" class="btn btn-default" data-dismiss="modal">Submit</button>
                     </div>
                   </div>
                 </div>
            </div>
         </div>
            <div class="col-md-4">
               Total students: <span ng-bind="data_count"></span>
            </div>
         </div>
         <div class="row">
            <table class="table table-striped table-hover ">
               <thead>
                  <tr class="success">
                     <th ng-repeat = "field in fields">
                        {{ field }}
                     </th>
                  </tr>
               </thead>
               <tbody>
                  <tr ng-repeat = "student in students.data">
                     <td ng-repeat = "property in student">
                        {{ property }}
                     </td>
                  </tr>
                  <tr class="warning">
                     <td>Average:</td>
                     <td ng-bind="social_avg()"></td>
                     <td ng-bind="maths_avg()"></td>
                     <td ng-bind="science_avg()"></td>
                  </tr>
               </tbody>
            </table>
         </div>
      </div>
   </body>
</html>

and app.js to this

app.js

app = angular.module('app', [])

app.controller('MainController', function($scope) {
      $scope.fields = ["Name", "Social studies", "Maths", "Science"];
      $scope.students = {data:[
                          {
                            name: "Naren", 
                            social:60, 
                            maths:87, 
                            science:85
                          },
                         {
                            name:"Saikiran",
                            social:80, 
                            maths:70, 
                            science:98
                          },
                          {
                            name:"Rajesh",
                            social:90, 
                            maths:90, 
                            science:78
                          }
                        ]} ;
      $scope.data_count = $scope.students.data.length;


      $scope.add_student = function()
      {
          // Get modal values using Angular's jqLite
          var name = angular.element(document.querySelector("#name"));
          var social_mark = angular.element(document.querySelector("#social"));
          var math_mark = angular.element(document.querySelector("#maths"));
          var science_mark = angular.element(document.querySelector("#science"));

          // Push data to students scope object. Magic is UI will be updated too.

          $scope.students.data.push(
              {
                  name: name.val(),
                  social: parseInt(social_mark.val()),
                  maths: parseInt(math_mark.val()),
                  science: parseInt(science_mark.val())
              }
          );

          // Update student count.
          $scope.data_count += 1;

          // Clear modal
          name.val("");
          social_mark.val("");
          math_mark.val("");
          science_mark.val("");

      }

       /* Average Section of Subjects. */

      // Calculate Social Studies average
      $scope.social_avg = function()
      {
          var total = 0;
          for(var i=0;i<$scope.students.data.length;i++)
          {
              total += $scope.students.data[i].social; 
          }
          return (total/$scope.data_count).toFixed();
      }

      // Calculate Mathematics average
      $scope.maths_avg = function()
      {
          var total = 0;
          for(var i=0;i<$scope.students.data.length;i++)
          {
              total += $scope.students.data[i].maths; 
          }
          return (total/$scope.data_count).toFixed();
      }

      // Calculate Science average
      $scope.science_avg = function()
      {
          var total = 0;
          for(var i=0;i<$scope.students.data.length;i++)
          {
              total += $scope.students.data[i].science; 
          }
          return (total/$scope.data_count).toFixed();
      }

});

If you launch the web browser, you will find dynamic average calculator with few lines of AngularJS.

Thank you :). Leave comment at narenarya@live.com, if you have any query.


Comments

comments powered by Disqus