In 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';
};
});