Building a Hybrid Mobile app using Cordova

In this tutorial, I will show you how to build a hybrid mobile app with and Phonegap.

What is Phonegap?

PhoneGap is a free and open source framework that allows you to create mobile apps using standardized web APIs for the platforms you care about.

Reference: http://en.wikipedia.org/wiki/PhoneGap

Download and install Eclipse Neon and Xcode 7.3.1 (if you using Mac for mobile development).

Eclipse Neon – http://www.eclipse.org/downloads/
Xcode 7.3.1 – https://developer.apple.com/xcode/downloads/

Setup ADT and Android SDK into your eclipse. You can refer here how to setup, http://theopentutorials.com/tutorials/android/installing-android-sdk-and-eclipse-adt-plugin/. Then you need to setup cordova using NPM (node package manager) from that link.

Download Jquery and Ratchet from their official website. You should unzip it to proper location. For this tutorial, we using Jquery 3.1.0 and Ratchet 2.0.2.

Setting up your development environment

Setup Cordova first before create a cordova project here, https://www.npmjs.com/package/cordova. Create a cordova project using command below in your terminal/cmd:

cordova create com.intellij.cordova.todolist
cordova create project

cordova create project

Open config.xml inside com.revivalx.ratchet folder and replace with this code.

config.xml

config.xml

config.xml

<?xml version='1.0' encoding='utf-8'?>
<widget id="com.intellij.cordova.todolist" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name>ToDoList</name>
    <description>
        A To Do List app using Cordova.
    </description>
    <author email="nurdin@intellij.my" href="http://intellij.my">
        Mohammad Nurdin bin Norazan
    </author>
    <content src="index.html" />
    <plugin name="cordova-plugin-whitelist" spec="1" />
    <access origin="*" />
    <allow-intent href="http://*/*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="tel:*" />
    <allow-intent href="sms:*" />
    <allow-intent href="mailto:*" />
    <allow-intent href="geo:*" />
    <platform name="android">
        <allow-intent href="market:*" />
    </platform>
    <platform name="ios">
        <allow-intent href="itms:*" />
        <allow-intent href="itms-apps:*" />
    </platform>
</widget>

Add platform for iOS and android.

cordova platform add ios
cordova platform add android
cordova platform add ios

cordova platform add ios

 

cordova platform add android

cordova platform add android

Create a new project inside your eclipse.

create a new eclipse project

create a new eclipse project

Select General > Project.

new eclipse project

new eclipse project

Enter following details and click Finish.

Project name: com.intellij.cordova.todolist.

Location: your project location.

create a new eclipse project

create a new eclipse project

Overview of Cordova directory structures

Here is the Cordova directory structure:

cordova structure

cordova structure

hooks – This directory may contains scripts used to customize cordova commands.

platforms (android and iOS) – Platforms added to your application will have the native application project structures laid out within this directory.

plugins – Any added plugins will be extracted or copied into this directory.

www (css) – The main application CSS directory.

www (img) – The main application image directory.

www (js) – The main application javascript directory.

index.html – The main HTML file.

config.xml – A global configuration file.

 

Preview your app (android)

Import android project into your eclipse.

import cordova project

import cordova project

Select AndroidExisting Android Code Into Workspace.

import existing android code into workspace

import existing android code into workspace

Browse your project and click Finish.

import android project

import android project

Follow this tutorial how to run android app in android simulator.

http://gidunderoneroof.blogspot.my/2014/05/connect-genymotion-by-adding-genymotion.html

Preview your app (ios)

Go to your project directory and browse for xcode project, platforms > ios > ToDoList.xcodeproj then run xcode project.

xcode project

xcode project

Click Play on top left side to preview the app on your simulator.

xcode project

xcode project

Learning client side API and building a multi page application

Right click js folder on your project. Go to New > Javascript Source File.

Javascript Source File

Javascript Source File

Select JavaScript > JavaScript Source File and click Next.

javascript source file

javascript source file

Create 3 javascript files.

  • main.js – initialize function.
  • AddPage.js – to add user details.
  • ListPage.js – to retrieve user list.
  • DetailPage.js – to retrieve user details.

Click Finish.

javascript source file

javascript source file

Right click www folder and go to New > Folder to create a new folder.

add folder

add folder

Name it pages and click Finish.

add folder pages

add folder pages

Then create a few of html pages inside page folder that we already created just now. Right click pages folder and go to New > HTML File.

HTML Files

HTML Files

Select Web > HTML File and click Next.

new html file

new html file

Create 3 html files and click Finish. Repeat.

  • AddPage.html – to add user details.
  • ListPage.html – to retrieve user list.
  • DetailPage.html – to retrieve user details.
new html file

new html file

Copy Jquery javascript files that you already extract from proper location into js folder.

jquery

jquery

Go to extracted Ratchet directory and select/copy all folders inside ratchet-2.0.2 > dist .

ratchet directory

ratchet directory

Then paste it inside www folder.

ratchet

ratchet

Open your index.html and replace with this code.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>

    <!-- Sets initial viewport load and disables zooming -->
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">

    <!-- Makes your prototype chrome-less once bookmarked to your phone's home screen -->
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">

    <!-- Include the compiled Ratchet CSS -->
    <link href="css/ratchet.css" rel="stylesheet">
    <script src="cordova.js" type="text/javascript"></script>
    <script src="js/jquery-3.1.0.min.js"></script>
    <script src="js/ratchet.js"></script>
    <script src="js/main.js"></script>
  </head>
  <body onload="init()">

  </body>
</html>

Replace all codes with given codes for each javascript files.

AddPage.js

currentPage={};

currentPage.init = function() {
    console.log("AddPage :: init");
};

currentPage.back = function(){
    console.log("AddPage :: back");
    $("body").load(path + "pages/ListPage.html", function(){
        $.getScript(path + "js/ListPage.js", function() {
            if (currentPage.init) {
                currentPage.init();
            }
        });
    });
};

DetailPage.js

currentPage={};

currentPage.init = function() {
    console.log("DetailPage :: init");
};

currentPage.back = function(){
    console.log("DetailPage :: back");
    $("body").load(path + "pages/ListPage.html", function(){
        $.getScript(path + "js/ListPage.js", function() {
            if (currentPage.init) {
                currentPage.init();
            }
        });
    });
};

ListPage.js

currentPage = {};

currentPage.init = function(){
    console.log("ListPage :: init");
};

currentPage.loadPage = function(pageIndex){
    console.log("ListPage :: loadPage :: pageIndex: " + pageIndex);
    $("body").load(path + "pages/" + pageIndex + ".html");
    $.getScript(path + "js/" + pageIndex +".js", function() {
        if (currentPage.init) {
            currentPage.init();
        }
    });
};

main.js

var pagesHistory = [];
var currentPage = {};
var path = "";

function init(){

    $("body").load(path + "pages/ListPage.html", function(){
        $.getScript(path + "js/ListPage.js", function() {
            if (currentPage.init) {
                currentPage.init();
            }
        });
    });

}

Replace all codes with given codes for each html files.

AddPage.html

<script>
    $.getScript(path + "js/AddPage.js");
</script>



<header class="bar bar-nav">
	<a class="icon icon-left-nav pull-left" onclick="currentPage.back();"></a>


<h1 class="title">AddPage</h1>


</header>


DetailPage.html

<script>
    $.getScript(path + "js/DetailPage.js");
</script>



<header class="bar bar-nav">
	<a class="icon icon-left-nav pull-left" onclick="currentPage.back();"></a>


<h1 class="title">DetailPage</h1>


</header>


ListPage.html

<script>
    $.getScript(path + "js/ListPage.js");
</script>



<header class="bar bar-nav">
	<button id="LoadAddButton" class="btn pull-right" onclick="currentPage.loadPage('AddPage');">Load Add.html</button>


<h1 class="title">ListPage</h1>


</header>





<div class="content">


<div class="content-padded">
    <button id="LoadDetailButton" class="btn btn-positive btn-block" onclick="currentPage.loadPage('DetailPage');">Load Detail.html</button>
</div>


</div>



Preview your app using previous steps.

We will using there URLs for our HTTP request/response. Refer to this tutorial for more understanding.

Now we want to integrate PHP with app. You need to replace all html files and js files so we can invoke PHP from there.

AddPage.js

currentPage = {};
currentPage.init = function() {
    console.log("AddPage :: init");
};
currentPage.back = function() {
    console.log("AddPage :: back");
    $("body").load(path + "pages/ListPage.html", function() {
        $.getScript(path + "js/ListPage.js", function() {
            if (currentPage.init) {
                currentPage.init();
            }
        });
    });
};
currentPage.add = function() {
    console.log("AddPage :: add");
    var name = $("#name").val();
    var officeNumber = $("#officeNumber").val();
    var phoneNumber = $("#phoneNumber").val();
    var email = $("#email").val();
    formData = {
        name: $("#name").val(),
        officeNumber: $("#officeNumber").val(),
        phoneNumber: $("#phoneNumber").val(),
        email: $("#email").val()
    }
    if (name == "") {
        alert("Please enter name");
    } else if (officeNumber == "") {
        alert("Please enter office number");
    } else if (phoneNumber == "") {
        alert("Please enter phone number");
    } else if (email == "") {
        alert("Please enter email");
    } else {
        $.ajax({
            type: "get",
            url: "http://demo.revivalx.com/worklight/create_user.php",
            data: formData,
            dataType: "json",
            success: function(data) {
                alert("Add user success");
                $("body").load(path + "pages/ListPage.html", function() {
                    $.getScript(path + "js/ListPage.js", function() {
                        if (currentPage.init) {
                            currentPage.init();
                        }
                    });
                });
            },
            error: function() {
                alert("Add user failure");
            }
        });
    }
};

DetailPage.js

currentPage = {};
currentPage.init = function() {
    console.log("DetailPage :: init");
    detailUser();
};
currentPage.back = function() {
    console.log("DetailPage :: back");
    $("body").load(path + "pages/ListPage.html", function() {
        $.getScript(path + "js/ListPage.js", function() {
            if (currentPage.init) {
                currentPage.init();
            }
        });
    });
};
currentPage.edit = function() {
    console.log("DetailPage :: edit");
    var userId = sessionStorage.userId;
    var name = $("#name").val();
    var officeNumber = $("#officeNumber").val();
    var phoneNumber = $("#phoneNumber").val();
    var email = $("#email").val();
    formData = {
        userId: sessionStorage.userId,
        name: $("#name").val(),
        officeNumber: $("#officeNumber").val(),
        phoneNumber: $("#phoneNumber").val(),
        email: $("#email").val()
    }
    if (name == "") {
        alert("Please enter name");
    } else if (officeNumber == "") {
        alert("Please enter office number");
    } else if (phoneNumber == "") {
        alert("Alert", "Please enter phone number");
    } else if (email == "") {
        alert("Alert", "Please enter email");
    } else {
        $.ajax({
            type: "get",
            url: "http://demo.revivalx.com/worklight/update_user.php",
            data: formData,
            dataType: "json",
            success: function(data) {
                alert("Edit user success");
                $("body").load(path + "pages/ListPage.html", function() {
                    $.getScript(path + "js/ListPage.js", function() {
                        if (currentPage.init) {
                            currentPage.init();
                        }
                    });
                });
            },
            error: function() {
                alert("Edit user failure");
            }
        });
    }
};

function detailUser() {
    formData = {
        userId: sessionStorage.userId
    }
    $.ajax({
        type: "get",
        url: "http://demo.revivalx.com/worklight/get_user_details.php",
        data: formData,
        dataType: "json",
        success: function(data) {
            $('#name').val(data.user[0].name);
            $('#officeNumber').val(data.user[0].officeNumber);
            $('#phoneNumber').val(data.user[0].phoneNumber);
            $('#email').val(data.user[0].email);
        },
        error: function() {
            alert("Detail user failure");
        }
    });
}
currentPage.remove = function() {
    console.log("DetailPage :: delete");
    deleteUser();
};

function deleteUser() {
    formData = {
        userId: sessionStorage.userId
    }
    $.ajax({
        type: "get",
        url: "http://demo.revivalx.com/worklight/delete_user.php",
        data: formData,
        dataType: "json",
        success: function(data) {
            alert("Delete user success");
            $("body").load(path + "pages/ListPage.html", function() {
                $.getScript(path + "js/ListPage.js", function() {
                    if (currentPage.init) {
                        currentPage.init();
                    }
                });
            });
        },
        error: function() {
            alert("Delete user failure");
        }
    });
}

ListPage.js

currentPage = {};
currentPage.init = function() {
    console.log("ListPage :: init");
    listUsers();
};
currentPage.loadPage = function(pageIndex) {
    console.log("ListPage :: loadPage :: pageIndex: " + pageIndex);
    $("body").load(path + "pages/" + pageIndex + ".html");
    $.getScript(path + "js/" + pageIndex + ".js", function() {
        if (currentPage.init) {
            currentPage.init();
        }
    });
};
currentPage.detailPage = function(userId) {
    sessionStorage.setItem("userId", userId);
    $("body").load(path + "pages/DetailPage.html");
    $.getScript(path + "js/DetailPage.js", function() {
        if (currentPage.init) {
            currentPage.init();
        }
    });
};

function listUsers() {
    $.ajax({
        type: "get",
        url: "http://demo.revivalx.com/worklight/get_all_users.php",
        dataType: "json",
        success: function(data) {
            var ul = $('#userList');
            var html = '';
            $.each(data.users, function(index, item) {
                html += '

<li class="table-view-cell">';
                html += '<a class="navigate-right" onclick="currentPage.detailPage(' + item.userId + ');" >';
                html += item.name;
                html += '</a></li>


';
            });
            ul.append(html);
        },
        error: function() {
            alert("List user failure");
        }
    });
}

AddPage.html

<script>
    $.getScript(path + "js/AddPage.js");
</script>
 


<header class="bar bar-nav">
    <a class="icon icon-left-nav pull-left" onclick="currentPage.back();"></a>


<h1 class="title">AddPage</h1>


</header>





<div class="content">


<div class="card">


<ul class="table-view">


<li class="table-view-cell table-view-divider">Name:</li>


 


<li class="table-view-cell"><input id="name" name="name" type="text"></li>


 


<li class="table-view-cell table-view-divider">Office Number:</li>


 


<li class="table-view-cell"><input id="officeNumber" name="officeNumber" type="text"></li>


 


<li class="table-view-cell table-view-divider">Phone Number:</li>


 


<li class="table-view-cell"><input id="phoneNumber" name="phoneNumber" type="text"></li>


 


<li class="table-view-cell table-view-divider">Email:</li>


 


<li class="table-view-cell"><input id="email" name="email" type="text"></li>


 


<li class="table-view-cell"></li>


    </ul>


   </div>




<div class="card" style="margin-bottom:40px;">
    	<button class="btn btn-positive btn-block" onclick="currentPage.add();">ADD USER</button>
    </div>


</div>


DetailPage.html

<script>
    $.getScript(path + "js/DetailPage.js");
</script>
 


<header class="bar bar-nav">
    <a class="icon icon-left-nav pull-left" onclick="currentPage.back();"></a>


<h1 class="title">DetailPage</h1>


</header>


 


<div class="content">


<div class="card">


<ul class="table-view">


<li class="table-view-cell table-view-divider">Name:</li>


 


<li class="table-view-cell"><input id="name" name="name" type="text"></li>


 


<li class="table-view-cell table-view-divider">Office Number:</li>


 


<li class="table-view-cell"><input id="officeNumber" name="officeNumber" type="text"></li>


 


<li class="table-view-cell table-view-divider">Phone Number:</li>


 


<li class="table-view-cell"><input id="phoneNumber" name="phoneNumber" type="text"></li>


 


<li class="table-view-cell table-view-divider">Email:</li>


 


<li class="table-view-cell"><input id="email" name="email" type="text"></li>


    </ul>


   </div>




<div class="card" style="margin-bottom:40px;">
    	<button class="btn btn-positive btn-block" onclick="currentPage.edit();">EDIT USER</button>
   </div>




<div class="card" style="margin-bottom:40px;">
    	<button class="btn btn-negative btn-block" onclick="currentPage.remove();">REMOVE USER</button>
   </div>


 
</div>


ListPage.html

<script>
    $.getScript(path + "js/ListPage.js");
</script>



<header class="bar bar-nav">
	<button id="LoadAddButton" class="btn pull-right" onclick="currentPage.loadPage('AddPage');">Add</button>


<h1 class="title">ListPage</h1>


</header>





<div class="content">


<ul id="userList" class="table-view"></ul>


</div>


Build and run your app. You can find the source code here: https://github.com/IntellijSys/com.intellij.cordova.todolist

Leave a Reply

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