Welcome to the world of AngularJS with PhoneGap! In this book, you will learn how to merge two very exciting technologies, namely AngularJS and PhoneGap. By the end of this book, you will have a working mobile app that works across iOS and Android, based on AngularJS and PhoneGap. As mentioned previously, this book is targeted at programmers who have knowledge of PhoneGap, but may or may not have knowledge regarding AngularJS. You should have some idea about JavaScript though, for you to get maximum benefit out of this book. That said, let us begin with AngularJS.
AngularJS (https://angularjs.org/) is a super heroic JavaScript MVC framework, which is maintained by Google. It is open source and its main goal is to assist with creating single page applications. These are typically one-page web applications that only require HTML, CSS, and JavaScript on the client side.
While one may argue that there are already many frameworks out there in the market that help with this issue, I would like to say that AngularJS is different in a few ways. And in quite a few of these instances, it makes your life much easier as a frontend programmer.
There are many concepts related to AngularJS, but I will cover the most commonly used ones for the sake of progressing through this chapter. As we go along in this book, I'll touch on other concepts, such as the use of self-defined directives and performing RESTful requests via AngularJS. The main concepts that you should understand in this section are directives, controllers, and data binding.
If you have already used JavaScript frameworks, such as BackBone.js, Can.js, Ember.js, or KnockOut.js, you should be familiar with this concept. Controllers are the behavior behind the DOM elements. AngularJS lets you express the behavior in a clean readable form without the usual boilerplate of updating the DOM, registering callbacks, or watching model changes.
Data-binding is an automatic way to update the view whenever the model changes, as well as updating the model whenever the view changes. The coolest aspect of this concept is that it is a two way data-binding process. Used in tandem with controllers, this can save you a lot of code, as there is no need for you to write the usual updating of the DOM elements.
Directives are another awesome concept in AngularJS. What they do is teach your application new HTML syntax and new things specific to your application. Directives can be self-defined and predefined. Some of the more notable predefined directives include:
ng-app
: This declares an element as a root element of the application, allowing its behavior to be modified through custom HTML tags.ng-bind
: This automatically changes the text of an HTML element to the value of a given expression.ng-model
: This is similar tong-bind
, but allows two-way binding between the view and scope.ng-controller
: This specifies a JavaScript controller class, which evaluates HTML expressions. In layman's terms, whatng-controller
does is that it applies a JavaScript function to this block of HTML so that this particular JavaScript function (including its accompanying logic, expressions, and more) can only operate in this block of HTML.
Now, let's take a look at how some of the previous concepts play together. Consider the following piece of code:
<!doctype html> <html ng-app> <head> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js"></script> </head> <body> <div> <label>Say Hello World</label> <input type="text" ng-model="yourHelloWorld" placeholder="Type anything here."> <hr> <h1>Hello {{yourHelloWorld}}!</h1> </div> </body> </html>
Tip
Downloading the example code
You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
Let's go through the code.
We defined an HTML5 HTML document in this case, as seen in the first line
Next, notice
ng-app
in the second line of the code; this is an AngularJS directive, which tells AngularJS that this is the root of the AngularJS applicationIn order to use AngularJS, we obviously have to install the script on this web page, as shown in the
<script>
tagWithin the body tag, we see a
label
, aninput
, and anh1
tag.Take note of the
input
tag, there is ang-model
directive, which is mapped toh1 tag's {{yourHelloWorld}}
What the previous piece of code does is that anything that is typed into the input box, will be shown in place of
{{yourHelloWorld}}
Take note of the version of the code we are using in this chapter, version 1.2.12; should you be using newer versions of AngularJS, there is no guarantee that the code will work.
Now that we have briefly walked through the code, let us copy the code and run it on our web browser. Feel free to copy the code and save it as concepts.html
. The source code for this chapter can be found in the concepts.html
file in the Chapter 1
folder.
Copied the code? If so, open the file in your favorite web browser. You should see the following screenshot in your browser:

A sample concept web page
Got the previous code? Ok great! So now you can try typing into the input box and see new text being appended to Hello and before ! in the screen.
For instance, when we type world
, we will see the new characters being appended to the screen as I continue to type. By the end of typing the word "World", we should see the following screenshot:

After typing World
Now that we have a brief idea as to how a simple AngularJS app works, let us move to a more complicated app.
In this example, we will cover in detail as to how to write code for a slightly more complicated AngularJS app. This app is modified from the official example found at angularjs.org. This example will be used as a base when we convert it from a web application to a PhoneGap application.
For starters, create the index.html
and todo.js
files. Just for your information, the code found in this section can be found in the todo
folder in Chapter 1
.
We need to prepare our HTML file so that we can make use of AngularJS. Similar to the previous concepts.html
file, you will see that we have included the use of AngularJS via script. Open up your index.html
file in your favorite editor and you can start by adding the following code:
<!doctype html> <html ng-app> <head> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js"></script> <script src="todo.js"></script> <link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css"> <style> body { padding:40px; } #todoDetails { visibility: hidden; } </style> </head> <body> <div class="row" ng-controller="todoCtrl"> <div class="col-md-6"> <h2>Todo</h2> <div> <span>{{getRemaining()}} of {{todos.length}} remaining</span> [ <button ng-click="archive()">archive</button> ] <ul class="unstyled"> <li ng-repeat="todo in todos"> <input type="checkbox" ng-model="todo.done"> <span class="done-{{todo.done}}">{{todo.text}}</span> <button ng-click="showDetail(todo.text)">Detail</button> </li> </ul> <form ng-submit="addTodo()"> <input type="text" ng-model="todoText" size="30" placeholder="add new todo here"> <input class="btn-primary" type="submit" value="add"> </form> </div> </div> <div id="todoDetails" class="col-md-6" > <h2>Details</h2> Title: <span id="title">{{currentText}}</span> <br> Add Details: <form ng-submit="addDetails()"> <textarea id="details" ng-model="currentDetails">{{currentDetails}}</textarea> <p> <input class="btn-primary" type="submit" value="Add Details"> <input class="btn-primary" type="submit" value="Cancel" ng-click="closeThis()"> </p> </form> </div> </div> </body> </html>
Now, to make sure that you are on the same page as I am, I want you to open this file in your favorite browser. You should see something like the following screenshot:

Our HTML template
Got the previous code? It looks weird now due to the fact that we have not added the main JavaScript functionalities. We will be working on it in the next section.
Now, let me explain the code; notice that I have highlighted a few lines of it. These are the most important lines of the code that you should take note of in this example. The remaining lines are just the usual HTML code.
The first two lines of the highlighted code simply install AngularJS and include BootStrap 3's CSS for styling purposes. Without both, the project will not work and may not look good.
The
ng-controller
directive is what we covered briefly earlier on in this chapter. We are applyingtodoCtrl
to this block of HTML.The
ng-click
directive is another directive that we did not touch on in the previous section. Whatng-click
does is that it executes whatever function is defined for this directive. In our example,ng-click="archive()"
means that on clicking it,archive()
will be executed. The JavaScript functionarchive()
is written in ourtodo.js
file, which we will cover later.The
ng-repeat
directive is a directive that loops through a collection. Notice how we implementedng-repeat
in our HTML code:<li ng-repeat="todo in todos"> <input type="checkbox" ng-model="todo.done"> <span class="done-{{todo.done}}">{{todo.text}}</span> <button ng-click="showDetail(todo.text)">Detail</button> </li>
Anything that is within
<li>
is dependent on thetodo
object, which is part of thetodos
collection.The
ng-submit
directive is generally used in forms. This is a directive which controls what is being done on the submit form. In this case, on the submit form, we will execute the JavaScript functionaddToDo()
.The
[]
option encapsulates<button ng-click="archive()">archive</button>
, which simply adds a square bracket around the button.
Now we will open our todo.js
file, which we created in the previous section. Open todo.js
in your favorite text editor. Let us begin by coding the following:
function todoCtrl($scope) { }
We are first going to define a controller, which we will be using for our app. Notice that we have named it todoCtrl
, which is mapped onto ng-controller
in the HTML file (index.html
), where ng-controller="todoCtrl"
means that todoCtrl
will be controlling this portion of the web page.
Also, notice the use of $scope
, which is an object that refers to the application model; it is the execution context for related expressions, such as ng-click
, ng-model
, and so on. Any such expressions of a predefined directive outside this scope will not be executed.
Let's start by initializing our to-do list. Within todoCtrl
, add the following code:
$scope.todos = [ {text:'here is my first to do', done:true, details:''}, {text:'continue writing chapter 1 for this book', done:false, details:''}, {text:'work on chapter 2 examples', done:false, details:''} ]; $scope.currentText = ''; // make the text empty $scope.currentDetails = ''; // make the text empty
What $scope.todos
does is that it simply creates a list of objects, which contains the text, details, and whether this to-do is executed or not (true or false). Notice that todos
here is mapped to the collection todos
as seen in index.html
, where ng-repeat
is being used.
Let's move on by adding more functionalities. After $scope.currentDetails
, add the following three JavaScript functions:
$scope.addTodo = function() { $scope.todos.push({text:$scope.todoText, done:false, details:''}); $scope.todoText = ''; }; $scope.remaining = function() { var count = 0; angular.forEach($scope.todos, function(todo) { count += todo.done ? 0 : 1; }); return count; }; $scope.archive = function() { var oldTodos = $scope.todos; $scope.todos = []; angular.forEach(oldTodos, function(todo) { if (!todo.done) $scope.todos.push(todo); }); };
The $scope.todoText
function resets todoText
after it has been pushed into the array. The $scope.addTodo
function does what it is suppose to do, simply adding a new to-do to the list of todos
as defined earlier. The beauty of AngularJS is that it uses standard JavaScript data structures that make manipulation so much easier.
The $scope.getRemaining
function simply calculates the number of items that are not done yet. Here, we can see two-way data-binding in action as this function executes whenever there is a change in the length of todos
.
The $scope.archive
function marks a to-do as done:true
in standard JavaScript manner.
By now, you should have noticed that all the JavaScript functions defined here are being used in index.html
under ng-controller="todoCtrl"
.
Let's now add three more JavaScript functions to complete the finishing touch for this sample application.
After the $scope.archive
function, add the following functions:
$scope.showDetail = function(text) { var result = $scope.todos.filter(function (obj) { return obj.text == text; }) $scope.currentText = result[0].text; $scope.currentDetails = result[0].details; document.getElementById('todoDetails').style.visibility = 'visible'; } $scope.closeThis = function() { $scope.currentText = ''; $scope.currentDetails = ''; document.getElementById('todoDetails').style.visibility = 'hidden'; } $scope.addDetails = function(text) { var result = $scope.todos.filter(function (obj) { return obj.text == text; }) angular.forEach($scope.todos, function(todo) { if(todo.text == text) { todo.details = $scope.currentDetails; } }); document.getElementById('todoDetails').style.visibility = 'hidden'; }
The $scope.showDetail
function simply retrieves the current to-do being clicked on and shows it on the div with ID #todoDetails
. The visibility of the #todoDetails
function is then set to visible
.
The $scope.close
function simply changes the visibility of #todoDetails
to hidden
.
Finally, $scope.addDetails
adds the details of the todo
item, and changes the visibility of #todoDetails
to hidden
once done.
Okay, so to see if we are on the same page, we now need to check our code. Save this file as todo.js
. Refresh your browser and you should still see the same user interface as per the previous screenshot.
Now, try clicking on the Detail button in front of work on chapter 2 examples, and you should see the following screenshot:

Details of the ToDo item shows on clicking on the corresponding detail button
You will see the details of a particular to-do item. You can try to add some details for this item and click on Add Details. You can then click on other items and come back to this item later (without refreshing the browser), and you should still see the details in the text area.
You can also check off any of the items and you will see that the number of remaining to-do item decreases:

Number of items changes dynamically as you check off items
And of course, you can add new items by simply typing in the input box and clicking on the add button. You should notice that the number of items now increases:

Adding new to-dos changes the number of items dynamically and also shows on the screen immediately
To summarize what we have done in this chapter; we have walked through the basics of building an AngularJS app and familiarized ourselves with the basic concepts used in AngularJS. We have made use of ng-app
, ng-controller
, ng-click
, ng-repeat
, and ng-submit
in general. These expressions, such as ng-click
and ng-submit
are typically mapped onto JavaScript functions defined in AngularJS controllers, as seen in todo.js
in our example. Notice how little code we have written in order to achieve such speedy UX through the concept of two-way data-binding and its controllers.
In the next chapter, we will start to port this app in a more organized manner to PhoneGap.