Welcome to the 3rd part of my AngularJS Tutorial. In this part we’ll learn about jqLite, editing HTML element text, css, attributes, and classes. We’ll append, prepend, remove and replace HTML elements. We’ll also create custom directives in multiple ways and will learn about transclusion.
If you missed the other parts watch them first here AngularJS Tutorial 1 and AngularJS Tutorial 2. The code follows the video below.
If you like videos like this please consider supporting me on Patreon. $1 is greatly appreciated.
[googleplusone]
Code From the Video
angulartut9.html
<!doctype html>
<html ng-app="app9" ng-cloak>
<head>
<title>AngularJS Tutorial 9</title>
<style>
[ng\:cloak], [ng-cloak], .ng-cloak {
display: none;
}
.thick {
font-weight: bold;
}
</style>
</head>
<body>
<!-- We cover how to modify, set, get attributes, set attributes, get values, set values for HTML elements -->
<div ng-controller="mainCtrl">
<ul jql-directive>
<li id="barry">Barry Bonds</li>
<ul>
<li>AVG : .298
<li>HR : 762
<li>OBP : .444
</ul>
<li id="hank">Hank Aaron</li>
<ul>
<li>AVG : .305
<li>HR : 755
<li>OBP : .374
</ul>
<li>Babe Ruth</li>
<ul>
<li>AVG : .342
<li>HR : 714
<li>OBP : .474
</ul>
</ul>
<h4>Children in List</h4>
<span id="childrenList"></span><br><br>
Barry's Number: <span id="barrysNum"></span><br><br>
Is Hank Bold: <span id="hankBold"></span><br><br>
Barry's ID: <span id="barryID"></span><br><br>
<button ng-click="unBold()">Toggle Bold</button>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
<script src="js/exam9.js"></script>
</body>
</html>
exam9.js
angular.module('app9', [])
.directive("jqlDirective", function() {
return function(scope, element, attrs) {
// Get the children of the element tied to the directive
var players = element.children();
var listOfPlayers = "";
// Cycle through the list of children
for(i = 0; i < players.length; i++){
// Modifying HTML Elements
// Check item for the value Barry Bonds
if(players.eq(i).text() == "Barry Bonds"){
// Change text color for the matching element
players.eq(i).css("color", "red");
// Add an attribute
players.eq(i).attr("number", "25");
}
// Check item for the value Hank Aaron
if(players.eq(i).text() == "Hank Aaron"){
// Add a class to an element
players.eq(i).addClass("thick");
}
// eq() returns an element at the given index
// text() returns the text in that element
listOfPlayers += players.eq(i).text() + ", ";
}
// How to select an element by id with JQLite and add text
angular.element(document.querySelector('#childrenList'))
.text(listOfPlayers);
// Get the value of an attribute
var barrysNum = angular.element(document.querySelector('#barry'))
.attr("number");
// Set the value of the attribute to the span
angular.element(document.querySelector('#barrysNum'))
.text(barrysNum);
// Remove a class
// You can remove an attribute with removeAttr
angular.element(document.querySelector('#hank'))
.removeClass("thick");
// Find out if an element has a class
var isHankBold = angular.element(document.querySelector('#hank'))
.hasClass("thick");
// Set the value in a span
angular.element(document.querySelector('#hankBold'))
.text(isHankBold);
// Get the value of a property
// Set a property with .prop("name", "value")
var barryID = angular.element(document.querySelector('#barry'))
.prop("id");
// Set the value in a span
angular.element(document.querySelector('#barryID'))
.text(barryID);
}
})
.controller("mainCtrl", function($scope) {
// Toggle a class on click
$scope.unBold = function() {
angular.element(document.querySelector('#hank')).toggleClass("thick");
}
})
angulartut10.html
<!doctype html>
<html ng-app="app10" ng-cloak>
<head>
<title>AngularJS Tutorial 10</title>
<style>
[ng\:cloak], [ng-cloak], .ng-cloak {
display: none;
}
</style>
</head>
<body>
<!-- Create a custom directive and then cover how to append, prepend, remove and replace HTML elements -->
<!-- Custom directives allow you to add functionality not provided by AngularJS and to create reusable code -->
<div ng-controller="mainCtrl">
<!-- The directive name is different because each uppercase letter is treated as a separate word in the attribute name. We define the item to get from the array by saving it in the array-item attribute. This is an example on how to apply a directive as an attribute. -->
<div bb-player-list="bbPlayers" array-item="name | uppercase"></div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
<script src="js/exam10.js"></script>
</body>
</html>
exam10.js
// You create directives with the Module.directive method
// using the name of the directive and the factory function
angular.module('app10', [])
.directive("bbPlayerList", function() {
// This is the link function and it links the HTML with the
// directive and the data in the scope.
// It receives the scope, the HTML element that the
// directive is applied to and attributes of the HTML
// element.
return function(scope, element, attrs) {
// Get the data by passing the value associated with
// bbPlayerList to the scope object
var data = scope[attrs["bbPlayerList"]];
// Verify that I have an array of data
if (angular.isArray(data)) {
// Get the item to display from the array-item attribute
var arrayItem = attrs["arrayItem"];
// angular.element wraps the DOM element as a JQuery
// element
var listElem = angular.element("<ul>");
// The ul element is the container in which the li
// elements will be assigned
element.append(listElem);
for (var i = 0; i < data.length; i++){
// Get the matching data stored in the defined key requested
// $eval eliminates the filter and leaves just the attribute
// name to pull from the array
listElem.append(angular.element('<li>')
.text(scope.$eval(arrayItem, data[i])));
}
// Add a span after the list
listElem.after(angular.element("<span id='mays'>").text("Willy Mays"));
// Add a span before the list
listElem.prepend(angular.element("<span id='cobb'>").text("Ty Cobb"));
// Remove an element
angular.element(document.querySelector('#mays')).remove();
// Replace an element
var gehrigHTML = "<span id='gehrig'>Lou Gehrig</span>";
var replacement = angular.element(gehrigHTML);
angular.element(document.querySelector('#cobb'))
.replaceWith(replacement);
}
}
})
.controller("mainCtrl", function($scope) {
$scope.bbPlayers = [
{name: "Barry Bonds", avg: 0.298, hr: 762, obp: 0.444},
{name: "Hank Aaron", avg: 0.305, hr: 755, obp: 0.374},
{name: "Babe Ruth", avg: 0.342, hr: 714, obp: 0.474},
{name: "Ted Williams", avg: 0.344, hr: 521, obp: 0.482}
];
});
angulartut11.html
<!doctype html>
<html ng-app="app11" ng-cloak>
<head>
<title>AngularJS Tutorial 11</title>
<style>
[ng\:cloak], [ng-cloak], .ng-cloak {
display: none;
}
</style>
</head>
<body>
<!-- Another custom directive example. Will pull in data based on the value of an attribute and replace the element player with that data below -->
<div ng-controller="mainCtrl">
<!-- Define the data to print by passing the scope name -->
<player name="barryBonds"></player>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
<script src="js/exam11.js"></script>
</body>
</html>
exam11.js
// Let's create another custom directive that will replace a
// custom element with data based on the data requested
// You create directives with the Module.directive method
// using the name of the directive and the factory function
var app11 = angular.module('app11', []);
app11.directive("player", function() {
// Create a directive object
var directive = {};
// Define that we are using an element directive instead of
// a A: attribute, C: class, or M: comment
// I covered how to apply as an attribute previously
// I normally only apply as elements or attributes because
// it is easy to figure out where the directive was applied.
directive.restrict = 'E';
// The template is filled with the data and replaces the element
directive.template = "{{player.name}} had a {{player.avg}} AVG with {{player.hr}} homeruns and a {{player.obp}} OBP";
// Scope defines what is unique about each element
directive.scope = { player: "=name" };
// compile is called during the initialization phase
directive.compile = function(element, attributes){
// The link function receives the scope, the element The
// directive is associated with and that elements
// attributes. Here we can handle events on that element
var linkFunc = function($scope, element, attributes){
element.bind('click', function() {
element.html('Barry disappeared');
});
}
return linkFunc;
}
return directive;
});
app11.controller("mainCtrl", function($scope) {
$scope.barryBonds = {name: "Barry Bonds", avg: 0.298, hr: 762, obp: 0.444};
$scope.hankAaron = {name: "Hank Aaron", avg: 0.305, hr: 755, obp: 0.374};
$scope.babeRuth = {name: "Babe Ruth", avg: 0.342, hr: 714, obp: 0.474};
$scope.tedWilliams ={name: "Ted Williams", avg: 0.344, hr: 521, obp: 0.482};
});
angulartut12.html
<!doctype html>
<html ng-app="app12" ng-cloak>
<head>
<title>AngularJS Tutorial 12</title>
<style>
[ng\:cloak], [ng-cloak], .ng-cloak {
display: none;
}
</style>
</head>
<body>
<!-- Here we'll use transclusion to add data without deleting
what is already there -->
<div ng-controller="mainCtrl">
<div ex-dir>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vestibulum neque nec purus rutrum, at dignissim lectus egestas. Aliquam pretium tortor ligula, non egestas massa dictum quis. Aenean iaculis elit tempor odio tristique malesuada. Vivamus in nisl vulputate, scelerisque mi vitae, efficitur metus. Suspendisse potenti
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
<script src="js/exam12.js"></script>
</body>
</html>
exam12.js
var app12 = angular.module('app12', []);
// When we use a template the template replaces the content
// in the document. You can use transclusion to display The
// original content and add in the new.
app12.directive("exDir", function() {
return {
transclude: true,
// ng-transclude defines where the data in the element
// shows up in the template
template: "<div><h4>{{moreLorem}}</h4></div><div ng-transclude></div>"
}
});
app12.controller("mainCtrl", function($scope) {
$scope.moreLorem = "The Amazing Lorem Story";
});