Introduction
Web development has never been this interesting. In the last 10 years, a lot of changed in the field of mobile computing. Long gone are those days where we had to refresh data to see in a browser, or carry a bulky N70 set in our pockets.
This is a new decade and in this a lot will change even further. There is especially one technology which would make all other languages obsolete . It has already started doing that or would be doing the replacement in the next few years. It's only a matter of choice and adaptability and re-usability before people actually start seeing the change.
That technology is HTML5. It has the potential to change everything as we know it today. I see most of the people who still see things from Microsoft IE8 or IE9 or give big security concerns or hide behind their inability to adapt, learn or live in there own nutshell.
I just want to remind people of one line which I read everyday.
"A Snake Has To Cast Its Skins Or Else It Has To Die"
This post is not for them. But still, please feel free to read.
But for those who believe there is a bigger thing, bigger than IE7 or IE8 or people wo know or dream what these technologies can do in the near future. Maybe, we don't know it but we still use most of the apps that are built around HTML5.
This post is for all people.
APP?????????
Where did this come from...????
Apps are not website but are full fledged web applications/application written in a language of the Web and ported over to multiple OS. So some might say how it is possible to have the same App run over in a different environment. That's all possible using HTML5 and cordova. Before we jump into cordova, let me tell you HTML5 comes with a scripting support which we know as JavaScript. It is JavaScript which glues all the app login, workflow and even UI elements glued together. The scope here is not to understand JavaScript. You might refer to some other links which explain JavaScript in details and come back later but to give a clear picture how technology can be coupled together and applied to do some greatest things which we could only imagine.
Do you know folks, JavaScript is the largest language which runs across devices, PCs, dedicated hardware or even Power the high performance Servers(nodejs). So ignoring JavaScript is not a good option.
Along the way came another groundbreaking technology (actually Framework) and it's called AngularJS. Angular JS mimicks MVC Design pattern and help users create SPA. Angular JS basic principles are to use Declarative Programming to construct UI and connect other software component. Angularjs infact extends HTML vocabulary and introduces two way data binding. (In other words, if you don't have any knowledge of Two way data binding, then kindly refer to the Observe Pattern in JavaScript. It is newly introduced Object.observe). Google it.
Background
To start this tutorial, at least basic knowledge of JavaScript, HTML5 and Angularjs is required.
Please have the following installed to start OR use Intel XDK:
Intel XDK is one the best tools to build Hybrid Application on the go.
Requirements
Snap.js and Snap.js Angular https://github.com/jakiestfu/Snap.js/ http://jtrussell.github.io/angular-snap.js/
(Kindly refer to the documentation.)
Intel XDK provides the best emulators though it does not fully provide Device level API emulation, but still it is one of the best tools to build a Hybrid App UI on the fly. It also has its own project management system.
IDE
Sublime Text http://www.sublimetext.com/
Atom.io https://atom.io/
Android Development Setup (If unable to do so, then download Intel XDK)
+ Ant/Java SDK/Grunt with all PATH configured. If not, refer to the below link.
Cordova /Phonegap (I am using Cordova) http://https://cordova.apache.org/
A Mobile Phone with Android
Setting Up Android Environment For Ubuntu Users
Setting Up Android Environment For Windows Users
Understanding the Basics
Let's create a basic HTML Page and add references to Angularjs and other dependencies.
The code here demonstrates how to use construct basic UI. What we would be doing here is to construct a Facebook like UI using angular, bootstrap and Snap.js. Snap.js is a tool to create a sliding menu. Most Hybrid app developers face a hard choice while constructing a menu. Though a Bootstrap CSS allows easily to create a responsive top drop down menu but in a lot of cases, the menu is preferred on the side so the real estate is free for other UI components.
Please refer to the following images which are used to describe how I manage my folder structure. You may be free to use any structure as desired, but for easy learning, please use this structure for this tutorials.
Kindly download all the related 3rd party files which I have mentioned and place it inside plugins.
Create controllers and templates.
Please have a look at the following folder structure which we have to create "Folder" word means actual folder with name only such as controllers, plugins, etc.
app- Root>
controllers Folder-> Contains all the controllers
plugins Folder - > contains all 3 rd party API and framework with there version number on folders
templates Folder - > contains all html templates
style Folder - > contains all custom css
services Folder -> contains services
init.js Folder -> this is from we would init or start or app
images Folder -> Contains all reference to images,sprites etc
index.html Folder - > the main index file which contains all the references
Below is the basic HTML5 markup with all dependencies and references. This is the base index file:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="plugins/bootstrap-3.3.4/css/bootstrap.min.css" rel="stylesheet" >
<link href="style/init.css" type="text/css" rel="stylesheet"/>
<link href="plugins/font-awesome-4.3.0/css/font-awesome.min.css" rel="stylesheet" />
<link href="plugins/Snap.js-develop/snap.css" rel="stylesheet" />
<!--
<link href="plugins/angular-snap.js-bower-master/angular-snap-only.min.css" rel="stylesheet" />
</head>
<body ng-controller="globalCtrl">
<div class="snapDrawer" snap-drawer="left">
</div>
<div class="snapContent" snap-content snap-options="snapOptions">
<div ng-include="'templates/topMenu.html'" ></div>
<div ng-view></div>
</div>
</body>
<script type="text/javascript" src="plugins/angular/angular.min.js" ></script>
<script type="text/javascript" src="plugins/angular/angular-route.min.js" ></script>
<script type="text/javascript" src="plugins/angular/angular-animate.min.js" ></script>
<!--
<script type="text/javascript" src="plugins/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="plugins/bootstrap-3.3.4/js/bootstrap.min.js"></script>
<!--
<script type="text/javascript" src="plugins/Snap.js-develop/snap.min.js"></script>
<!--
<script type="text/javascript" src="plugins/angular-snap.js-bower-master/angular-snap.min.js"></script>
<script type="text/javascript" src="plugins/ui.bootstrap/ui-bootstrap-tpls-0.13.0.min.js"></script>
<script type="text/javascript" src="init.js" ></script>
<!--
<script type="text/javascript" src="controllers/landingCtrl.js" ></script>
<script type="text/javascript" src="controllers/globalCtrl.js" ></script>
<script type="text/javascript" src="controllers/clusterInfoCtrl.js" ></script>
<!--
<script type="text/javascript" src="modals/addCluster/addClusterModalCtrl.js" ></script>
<script type="text/javascript" src="modals/contextGraph/contextGraphCtrl.js" ></script>
</html>
If you look at this index.html, you will see that I have not used ng-app
to initialize my application right away.
It's because we will bootstrap our application since a cordova app requires "deviceready
" event onto which only everything else will execute. But here, we will first see if it executes on browser window.onload
. Then, we will replace window.onload
with deviceready
event. Now let's open init.js and add the following code:
var log = console.log.bind(console);
window.onload = function()
{
angular.bootstrap(document,["myApp"]);
log("App Init.....Ready");
}
var app = angular.module('myApp', ["ngRoute","ui.bootstrap","snap"]);
app.config(function($routeProvider,snapRemoteProvider)
{
log("Routing Definition");
$routeProvider
.when("/",{
templateUrl : "templates/landing.html",
controller : "landingCtrl"
})
.otherwise({ redirectTo: '/' });
});
Let's have a look at init.js and what we are doing here.
In the first line, I am mapping console.log
to a log using bind since I dont like to always use console.log
all the time. You can use this bind to map others also.
Then we are using window.onload
here. The reason to use window.onload
here is that we have not defined ng-app
in the index.html. Since an angularjs would first look for ng-app
to initialize itself, but here we would be doing it manually so that it works and init based on our inputs.
angular.bootstrap(document,["myApp"]);
angular.bootstrap
actually tells the angularjs to bind "myApp
" to the document. so basically we are telling angularjs to bind "myApp
" to document. Since it is not automatically done, we take the privilege to add "myApp
" (from where angularjs init) on page load (page load success). This gives us greater flexibility and control. We can also use multiple angular.bootstrap
to init
other apps here.
Since we have instructed the Angularjs to init after page loads, the other part will not execute for angularjs till the page is loaded.
var app = angular.module('myApp', ["ngRoute","ui.bootstrap","snap"]);
This is execute once angular.bootstrap
is executed and then it will map the routes.
Please see my core dependencies are ngRoute
, ui.bootstrap
and snap
. All of these have added in index.html.
Please go ahead and run the project in your local system using any server WAMP/XAMPP
and open console to look for any errors..
Now please have a closer look at index.html. You will see a few lines of code written between bodies.
<div class="snapDrawer" snap-drawer="left">
</div>
<div class="snapContent" snap-content snap-options="snapOptions">
<div ng-include="'templates/topMenu.html'" ></div>
<div ng-view></div>
</div>
What is done here to create a sliding menu. If you can remember sliding menu on facebook app, you will see a menu slides in and the body also slides out.
The basic layout to achieve this kind of sliding is using Snap.js and Snap.js Angular (both are required).
<div snap-drawer="left"></div>
<div snap-content snap-options="snapOptions"></div>
Basic layout With and Without Custom Class is as follows:
<div class="snapDrawer" snap-drawer="left"></div>
<div class="snapContent" snap-content snap-options="snapOptions"></div>
This is the basic code to achieve a sliding menu. The snap-drawer
is something which contains all the hyperlinks which slides in and snap-content
which contains the body elements and UI elements which we normally use to display. I have added custom classes here and changed their background.
The snap-drawer="left" OR snap-drawer="right"
would ensure that the slide in happens either from Left Or Right. In this case, it is from the left.
Inside snap-content
, we can place all the UI elements which we want to display. snap-content
has snap-options
(please refer to snap.js documentation). Here, we are applying snap js basic configuration and tell snapjs how the slide would happen, how much it should slide. I always write App level configuration in globalCtrl.js.
app.controller('globalCtrl',function ($scope) {
$scope.snapOptions = {
disable: 'none',
addBodyClasses: true,
hyperextensible: true,
resistance: 0.5,
flickThreshold: 50,
transitionSpeed: 0.3,
easing: 'ease',
maxPosition: 266,
minPosition: -340,
tapToClose: true,
touchToDrag: false,
slideIntent: 40,
minDragDistance: 5
};
});
In this case, once the App is initialized, snapOptions
would apply to snap-content
. Use custom class to override background colors for both drawer and content.
NOTE: www.zip folder is attached as a complete app here. Please use local machine xampp/lamp/wamp to extract and run this Application.
Since the objective here is to create a basic angularjs page for cordova, let's move to creating a cordova app.
So let's open our index.html and add a reference. This should be the first reference in your index.html.
<script src="cordova.js"></script>
Then, open init.js and make few changes or add this complete code. It will run on both.
document.addEventListener("deviceready",function()
{
angular.bootstrap(document,["myApp"]);
log("App Init.....Ready");
},false);
The above code will ensure that once the cordova is initialized, this event would be fired. After init
, it will execute angular. This way, we can init an angular app using deviceready
event for cordova app.
Now open nodejs and create a basic cordova App:
root : > cordova create myApp myApp.com.app myApp
The above line create a cordova app with myApp folder with a namespace of myApp.com.app
(Its important) and the app name as myApp
.
Now go to myApp
:
root : > cordova platform add android
This line actually adds an Android OS support to this project. You will see this download happening to download Android related files. Under myApp, you will see multiple folders. The one that matters most is www folder.
Go ahead and delete everything inside www folder and copy paste the index.html and the folder we created.
Please ensure whatever is referenced in index.html should be mapped. Now inside www folder, copy/paste what we have created or download the www folder and paste all the content inside www folder.
root : > cordova build android
Now run the above command to build this App. If you use an emulator, then:
root : > cordova emulate android
OR if you want to test this app on device, then run:
root : > cordova run android
This will run the app on your actual devices. Do ensure your device gets detected. Type:
root : > adb devices
This will list your device. Do ensure that the USB Debugging is enabled on your device.
Welcome to the beautiful world of Android with cordova/angularjs and html5.
Points of Interest
Please give a reading on cordova. ionic is a great framework which removes all these hassles, but for me I stick to this way as I enjoy more control over my code. Please do let me know how you like this project or if there are any mistakes.