AngularJS Tutorial 2

AngularJS TutorialIn this part of my AngularJS tutorial I’m going to cover Form Validation, Using $rootScope to share data between controllers, Controller Inheritance, Filters, Custom Filters and a whole lot more.

If you haven’t watched part 1 of my AngularJS tutorial definitely watch it or you’ll be very confused. All of the code covered in this tutorial follows the video down below to act as a transcript and cheat sheet for AngularJS.

If you like videos like this consider supporting me on Patreon where I’m offering exclusive videos for anyone that contributes $1.

[googleplusone]

Code From the Video

angulartut5.html

<!doctype html>
<html ng-app="app5" ng-cloak>
  <head>
    <title>AngularJS Tutorial 5</title>
    <style>
    [ng\:cloak], [ng-cloak], .ng-cloak {
      display: none;
    }
    table{
      width: 400px;
      text-align: left;
      border: 2px solid black;
      padding: 10px;
    }
    input.ng-dirty.ng-invalid {
      border-color: red;
    }
    </style>
  </head>
  <body>

    <div id="groceryList" ng-controller="gListCtrl">

      <h3>Grocery List</h3>

      <table>
        <thead>
          <tr>
            <th>Item</th>
            <th>Purchased</th>
          <tr>
        </thead>
        <tr ng-repeat="grocery in groceries">
          <td>{{grocery.item}}</td>
          <td>
            <!-- Bind the checkbox to the data model -->
            <input type="checkbox" ng-model="grocery.purchased" />
          </td>
        </tr>
      </table>

      <br>

      <!-- User enters a new item and when the button is clicked
      the value in the input box is added to the array -->
      <label>New Item :
        <input type="text" ng-model="newItem" />
      </label>
      <button ng-click="addItem(newItem)">Add Item</button>

      <!-- Error shows here if no item was entered -->
      <h4>{{missingNewItemError}}</h4>

    </div> <!-- End of groceryList -->

    <div ng-controller="userCtrl">

      <!-- Pass the user data to saveUser() -->
      <form name="userForm" ng-submit="saveUser(userInfo)">
        <label>First Name:</label>

        <!-- Define that a value is required and it must be 2 characters in length or more -->
        <input type="text" name="fName" ng-model="userInfo.fName"
        ng-required="true" ng-minlength="2" />

        <!-- $dirty is set to true if a user interacts with a element and then we check if the elements required field is true -->
        <span class="error-message" ng-show="userForm.fName.$dirty
        && userForm.fName.$error.required">Must Enter a First Name
        </span>

        <!-- Check if the element has been edited and whether it contains at least 2 characters -->
        <span class="error-message" ng-show="userForm.fName.$dirty
          && userForm.fName.$error.minlength">Must be a Minimum of 2 Characters</span>

        <br><br>

        <label>Last Name:</label>

        <input type="text" name="lName" ng-model="userInfo.lName"
        ng-required="true" ng-minlength="2" />

        <span class="error-message" ng-show="userForm.lName.$dirty
        && userForm.lName.$error.required">Must Enter a Last Name
        </span>

        <span class="error-message" ng-show="userForm.lName.$dirty
          && userForm.lName.$error.minlength">Must be a Minimum of 2 Characters</span>

        <br><br>

        <label>Street:</label>

        <input type="text" name="street" ng-model="userInfo.street"
        ng-required="true" ng-minlength="6" ng-pattern="/^(\d{3,})\s?(\w{0,5})\s([a-zA-Z]{2,30})\s([a-zA-Z]{2,15})\.?\s?(\w{0,5})$/" />

        <span class="error-message" ng-show="userForm.street.$dirty
        && userForm.street.$invalid">Must Enter a Number, Street and Street Type (ex: 123 Main St)
        </span>

        <br><br>

        <label>Subscribe:</label>

        <input type="checkbox" name="subscribe" ng-model="userInfo.subscribe" ng-true-value="'Subscribe'" ng-false-value="'Don\'t Subscribe'" />

        <br><br>

        <label>Delivery Method:</label>

        <select name="delivery" ng-model="userInfo.delivery"  ng-required="true">

          <option value="Email">Email</option>
          <option value="Mail">Mail</option>

        </select>

        <br><br>

        <!-- Disable the button until every element in the form is valid -->
        <input type="submit" value="Save" ng-disabled="userForm.$invalid"/>

        <!-- Output new users -->
        <ul>
        <li ng-repeat = "item in user">
          {{ 'User: ' + item.fName + " " + item.lName + " " + item.street +
            " " + item.subscribe + " " + item.delivery}}
        </li>
      </ul>

    </div> <!-- End of userCtrl -->

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
    <script src="js/exam5.js"></script>

  </body>
</html>

exam5.js

var app5 = angular.module('app5', []);

app5.controller('gListCtrl', function($scope) {

  $scope.groceries= [
    {item: "Tomatoes", purchased: false},
    {item: "Potatoes", purchased: false},
    {item: "Bread", purchased: false},
    {item: "Hummus", purchased: false}
  ];

  // Receives the new item entered in the input box and puts
  // it on the end of the array
  $scope.addItem = function(newItem) {

    // Check that the input box has a value
    if(!(newItem === undefined || newItem === "")){
      $scope.groceries.push({
        item: newItem, purchased: false
      });
      $scope.missingNewItemError = "";
    } else {

      // Show an error if no item was entered
      $scope.missingNewItemError = "Please Enter an Item";
    }
  };
});

app5.controller('userCtrl', function($scope) {

  $scope.user= [{
    fName: "Derek",
    lName: "Banas",
    street: "123 Main St",
    subscribe: "Subscribe",
    delivery: "Email"
  }];

  $scope.saveUser = function(userInfo) {
    if($scope.userForm.$valid) {
      $scope.user.push({
        fName: userInfo.fName, lName: userInfo.lName, street: userInfo.street, subscribe: userInfo.subscribe, delivery: userInfo.delivery
      });
      console.log('User Saved');
    } else {
      console.log('Error : Couldn\'t Save User');
    }
 }

});

angulartut6.html

<!doctype html>
<html ng-app="app6" ng-cloak>
  <head>
    <title>AngularJS Tutorial 6</title>
    <style>
    [ng\:cloak], [ng-cloak], .ng-cloak {
      display: none;
    }
    </style>
  </head>
  <body>

    <!-- Demonstrating how to use $rootScope to share data between 2 controllers -->
    <div ng-controller="heroCtrl">

      <!-- Search for heroes in the scope -->
      <label>Hero to Search for : </label>
      <input type="text" ng-model="heroName" />
      <br><br>
      <button ng-click="getHeroData()">Submit</button>
      <br><br>

      {{heroData}}<br>

    </div>

    <div ng-controller="heroCtrl">

      <!-- Add new heroes -->
      <label>Hero Name : </label>
      <input type="text" ng-model="heroName" /><br><br>
      <label>Real Name : </label>
      <input type="text" ng-model="realName" /><br><br>
      <button ng-click="addHeroData(realName, heroName)">Add</button>

    </div>

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
    <script src="js/exam6.js"></script>

  </body>
</html>

exam6.js

var app6 = angular.module('app6', []);

// If you use a controller twice on one page each controller
// has its own $scope. You can update the $scopes however
// by using the $rootScope.
app6.controller('heroCtrl', function($scope, $rootScope) {

  $scope.hero = [
    {realName: "Bruce Wayne", heroName: "Batman"},
    {realName: "Clark Kent", heroName: "Superman"},
  ];

  // Receives the hero to look up
  $scope.getHeroData = function(){
    heroSearch($scope.heroName);
  };

  // Searches through the hero array for a match
  function heroSearch(name){

    // If a her is found it is returned
    $scope.heroData = "Not Found";
    for(var i=0; i < $scope.hero.length; i++){
      if ($scope.hero[i].heroName === name){
        $scope.heroData = $scope.hero[i].realName + " is " + $scope.hero[i].heroName;
      }
    }
  }

  // If a broadcast is caught named heroUpdated the new heroUpdated
  // is added to the other controllers $scope
  $scope.$on("heroUpdated", function(event, args){
    console.log("Real : " + args.realName + " Hero : " + args.heroName);
    $scope.hero.push({
      realName: args.realName, heroName: args.heroName
    });
  });

  // When a new hero is added we broadcast the update to the
  // other controllers $scope
  $scope.addHeroData = function(realName, heroName){
    $rootScope.$broadcast("heroUpdated",
    {
      realName: realName, heroName: heroName
    });
    console.log("Real : " + realName + " Hero : " + heroName);

  };

});

angulartut7.html

<!doctype html>
<html ng-app="app7" ng-cloak>
  <head>
    <title>AngularJS Tutorial 7</title>
    <style>
    [ng\:cloak], [ng-cloak], .ng-cloak {
      display: none;
    }
    </style>
  </head>
  <body>

    <!-- Demonstrating how to use controller inheritance -->
    <div ng-controller="mainCtrl as parent">

      <!-- Display parent data -->
      <p>Name : {{parent.name}}</p>
      <p>Sound : {{parent.sound}}</p>
      <button ng-click=parent.animalClick()>Animal Data</button><br>
    </div>

    <div ng-controller="dogCtrl as dog">
      <p>Name : {{dog.child.name}}</p>
      <p>Sound : {{dog.child.sound}}</p>

      <!-- Call the parent method using the dog fields -->
      <button ng-click=dog.child.animalClick()>Dog Data</button><br><br>

      <!-- Call the dog method -->
      <button ng-click=dog.child.dogData()>More Dog Data</button><br><br>

        <!-- Change a field value -->
        <input ng-model="dog.child.bark" /><br><br>
       <span>New Bark : {{dog.child.bark}}</span>
    </div>

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
    <script src="js/exam7.js"></script>

  </body>
</html>

exam7.js

var app7 = angular.module('app7', []);

app7.controller('mainCtrl', function() {

  // Define 2 fields that are bound to this controller
  // This is an example of a scopeless controller using this
  this.name = "Animal";
  this.sound = "Grrrrr";

  // Bound method
  this.animalClick = function(){
    alert(this.name + " says " + this.sound);
  };

});

// The $controller service allows us to instantiate a controller
// inside of another controller
app7.controller('dogCtrl', function($controller) {

  var childCtrl = this;

  // Create an instance of the parent controller
  childCtrl.child = $controller('mainCtrl', {});

  // Overwrite the parent name field
  childCtrl.child.name = "Dog";

  // Define a field for the child
  childCtrl.child.bark = "Wooof";

  // You can extend the child controller by declaring your own methods
  childCtrl.child.dogData = function(){
     alert(this.name + " says " + this.sound + " and " + this.bark);
  }

});

angulartut8.html

<!doctype html>
<html ng-app="app8" ng-cloak>
  <head>
    <title>AngularJS Tutorial 8</title>
    <style>
    [ng\:cloak], [ng-cloak], .ng-cloak {
      display: none;
    }
    </style>
  </head>
  <body>

    <!-- Filters transform data in the view without altering it in the scope using the pipe character -->
    <div ng-controller="mainCtrl">

      <!-- Uppercase -->
      <label>Make Uppercase : </label>
      <input type="text" ng-model="name">
      <p>Uppercase : {{name | uppercase}}</p>

      <!-- Lowercase -->
      <p>Lowercase : {{name | lowercase}}</p>

      <!-- Currency Filter -->
      <label>Currency Filter : </label>
      <input type="text" ng-model="money">
      <p>Uppercase : {{money | currency}}</p>

      <!-- Filter filter
      Change the order direction by putting -gpa -->
      <ul>
        <li ng-repeat = "student in student.gpas | filter: studentName |orderBy:'gpa'">
          {{ 'Name: ' + student.name + ' : GPA: ' + student.gpa }}
        </li>
      </ul>

      <!-- Number Filter -->
      <label>Number Filter : </label>
      <input type="text" ng-model="numVal">
      <p>Default : {{numVal | number}}</p>
      <p>No Fractions : {{numVal | number:0}}</p>
      <p>Negative 4 Decimals : {{-numVal | number:4}}</p>

      <!-- Date Filter https://docs.angularjs.org/api/ng/filter/date -->
      <p>Date 1 : {{currDate | date:'medium'}}</p>
      <p>Date 2 : {{currDate | date:"MM/dd/yyyy 'at' h:mma"}}</p>

      <!-- LimitTo Filter -->
      <p>Default : {{randomStr}}</p>
      <p>10 Characters : {{randomStr | limitTo:10}}</p>
      <p>
        <ul>
          <li ng-repeat="item in randArray | limitTo:3">
            {{item}}
          </li>
        </ul>
      </p>

      <!-- Custom Filter
      Different unicode characters are returned based on if item.rain
      has the value of true or false -->
      <p>
        <ul>
          <li ng-repeat="item in weather">
            {{item.day + " : "}} {{item.rain | raining}}
          </li>
        </ul>
      </p>

    </div>

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
    <script src="js/exam8.js"></script>

    <!-- Needed for custom Filter -->
    <script src="js/filters.js"></script>

  </body>
</html>

exam8.js

// Register our custom filter as a dependency
var app8 = angular.module('app8', ['weatherFilters']);

app8.controller('mainCtrl', function($scope) {

  $scope.students = [
    {name: "George Thomas", gpa: 3.5},
    {name: "Susy Smith", gpa: 3.6},
    {name: "Paul Marks", gpa: 3.2},
    {name: "Sue Edgar", gpa: 3.8}
  ];

  $scope.student = {
      gpas:[
        {name: "George Thomas", gpa: 3.5},
        {name: "Susy Smith", gpa: 3.6},
        {name: "Paul Marks", gpa: 3.2},
        {name: "Sue Edgar", gpa: 3.8}
      ]
  };

  $scope.currDate = new Date();

  $scope.randomStr = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "

  $scope.randArray = [
    "Tomato",
    "Potato",
    "Bread",
    "Pickles",
    "Raisins"
  ];

  $scope.weather = [
    {day: "Monday", rain: false},
    {day: "Tuesday", rain: true}
  ];

});

filters.js

// Create a module named weatherfilters
// The name for the filter is raining and different unicode
// characters are returned based on weather an item is true or false
angular.module('weatherFilters', []).filter('raining', function(){
  return function(input){
    return input ? '\u2602' : '\u2600';
  };
});

 

Leave a Reply

Your email address will not be published. Required fields are marked *