Junior Full Stack Mobile App Developer (iOS/Android + PHP)

Responsibilities

As a developer, the most boring job you can get is to keep building things that bring little or no self improvement. Make no mistake about it, these jobs usually pay well which make it so hard to leave behind. If you are looking for a place where you get to level­up yourself every day in terms of technical skills and other soft skills, we have the right offer here.

We are currently looking for Junior Full Stack Mobile App Developer who are willing to sharpen their skills in either iOS (Objective-­C) or Android (Java) development.

As part of our development team, you will be:

  • In charged of developing new features and bug fixing either for our iOS or Android app.
  • Building Web API to support our mobile app.
  • Work closely with other development team members to establish workflows in order improve efficiency.

Requirements

  • Familiar with either iOS (Objective­C) or Android (Java) app development.
  • Comfortable with working on existing code base.
  • Independent and able to self­learn.

About Us

CLOSETStyles is a simple and fun way for women to buy and sell fashion out of their closets. We are a C2C Fashion Marketplace app supported by a Malaysia based Venture Company and enrolled into an Accelerator Program in Malaysia. The social platform helps women find their style mates and shop each others’ closets, cultivating a closet sharing culture across Asia. Visit our website at http://closetstyles.co

closetstyles.co

closetstyles.co

PHP developers for hire.

Dekatku are looking for talented PHP developers with 3-5 to work on an exciting customer project. If you have demonstrable experience and code to submit for review, we want you! Salary 5-7k depending on experience.
Please send cvs to nurdin.norazan@dekatku.com.

Dekatku Sdn. Bhd.

Dekatku Sdn. Bhd.

Implement Push Notifications for android and iOS (phonegap) – part 3

This tutorial is the third part of a three-part series on how to do push notifications integration with your app for android and iOS.

Install the PushPlugin phonegap plugin from its github location via the Cordova CLI:

cordova plugin add https://github.com/phonegap-build/PushPlugin
PushPlugin Phonegap Plugin

PushPlugin Phonegap Plugin

Add iOS and android platform using cordova CLI.

cordova platform add ios
cordova platform add android
cordova platform add

cordova platform add

Locate the PushNotification.js file that was installed into your project-root/plugins folder. This file must be copied into your project-root/www/js folder and referenced from the index.html currently.

https://github.com/phonegap-build/PushPlugin/blob/master/www/PushNotification.js

copy from phonegap plugin folder

copy from phonegap plugin folder

copy to www folder

copy to www folder

Write custom script for push notification plugin. Grab project id from Google Developer Console and put it inside this script. After that save as PushCustom.js in www/js.

// JavaScript Document
var pushNotification;

function onDeviceReady() {
		document.addEventListener("backbutton", function(e) {}, false);
		try {
			pushNotification = window.plugins.pushNotification;
			if (device.platform == 'android' || device.platform == 'Android' || device.platform ==
				'amazon-fireos') {
				pushNotification.register(successHandler, errorHandler, {
					"senderID": "xxxxxxxxxxxxx",
					"ecb": "onNotification"
				}); // required!
			} else {
				pushNotification.register(tokenHandler, errorHandler, {
					"badge": "true",
					"sound": "true",
					"alert": "true",
					"ecb": "onNotificationAPN"
				}); // required!
			}
		} catch (err) {
			txt = "There was an error on this page.\n\n";
			txt += "Error description: " + err.message + "\n\n";
			alert(txt);
		}
	}
	// handle APNS notifications for iOS

function onNotificationAPN(e) {
		if (e.alert) {
			// showing an alert also requires the org.apache.cordova.dialogs plugin
			navigator.notification.alert(e.alert);
		}
		if (e.sound) {
			// playing a sound also requires the org.apache.cordova.media plugin
			var snd = new Media(e.sound);
			snd.play();
		}
		if (e.badge) {
			pushNotification.setApplicationIconBadgeNumber(successHandler, e.badge);
		}
	}
	// handle GCM notifications for Android

function onNotification(e) {
	switch (e.event) {
		case 'registered':
			if (e.regid.length > 0) {
				// Your GCM push server needs to know the regID before it can push to this device
				// here is where you might want to send it the regID for later use.
				alert("regID = " + e.regid);
			}
			break;
		case 'message':
			// if this flag is set, this notification happened while we were in the foreground.
			// you might want to play a sound to get the user's attention, throw up a dialog, etc.
			if (e.foreground) {
				// on Android soundname is outside the payload.
				// On Amazon FireOS all custom attributes are contained within payload
				var soundfile = e.soundname || e.payload.sound;
				// if the notification contains a soundname, play it.
				// playing a sound also requires the org.apache.cordova.media plugin
				var my_media = new Media("/android_asset/www/" + soundfile);
				my_media.play();
			}
			break;
		case 'error':
			break;
		default:
			break;
	}
}

function tokenHandler(result) {
	alert('device token = ' + result);
	// Your iOS push server needs to know the token before it can push to this device
	// here is where you might want to send it the token for later use.
}

function successHandler(result) {}

function errorHandler(error) {}
document.addEventListener('deviceready', onDeviceReady, true);

Add the following script line to your index.html to reference the PushNotification.js and PushCustom.js.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
    <title></title>

    <link href="lib/ionic/css/ionic.css" rel="stylesheet">
    <link href="css/style.css" rel="stylesheet">

    <!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
    <link href="css/ionic.app.css" rel="stylesheet">
    -->

    <!-- ionic/angularjs js -->
    <script src="lib/ionic/js/ionic.bundle.js"></script>

    <!-- cordova script (this will be a 404 during development) -->
    <script src="cordova.js"></script>
    <script type="text/javascript" src="js/PushNotification.js"></script>

    <!-- your app's js -->
    <script src="js/app.js"></script>
  </head>
  <body ng-app="starter">

    <ion-pane>
      <ion-header-bar class="bar-stable">
        <h1 class="title">Ionic Blank Starter</h1>
      </ion-header-bar>
      <ion-content>
      </ion-content>
    </ion-pane>
  </body>
</html>

Build and run the application via eclipse (ADT installed) and Xcode6.

cordova build ios
cordova build android

Open your editor and create a file called simplepush.js.

Android setting

Go to your GCM console and locate the Server API key (click the API Access link in the menu on the left to locate they keys). http://blog.revivalx.com/2014/08/29/implement-push-notifications-for-android-and-ios-phonegap-part-1/

Get the registration id returned to our application from the console. I like to use the Android adb tool so I can run logcat to watch the console while my application is running. Assuming you have the android-sdk tools and platform-tools set on your environment path you can simply run adb logcat from the command line to show your device log.

Replacing the Sender key and device registration id with yours in simplepush.php.

IOS setting

Go to your apple developer account and locate iOS / APNs development certificates and provisioning profile then install it into your machine.

Get the token id returned to our Xcode console. Open your editor and replacing the token id and passphrase.

<?php
//enable it
//$deviceType = 'ios';
//$deviceType = 'android';

//operation begin
if($deviceType == 'ios'){

$deviceToken = 'xxxxx';
// Put your device token here (without spaces):

// Put your private key's passphrase here:
$passphrase = 'xxxxx';

// Put your alert message here:
$message = 'Technovault is awesome!!!';

////////////////////////////////////////////////////////////////////////////////

$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);

// Open a connection to the APNS server
$fp = stream_socket_client(
	'ssl://gateway.sandbox.push.apple.com:2195', $err,
	$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);

if (!$fp)
	exit("Failed to connect: $err $errstr" . PHP_EOL);

echo 'Connected to APNS' . PHP_EOL;

// Create the payload body
$body['aps'] = array(
	'alert' => $message,
	'sound' => 'default',
	'badge' => 1
	);

// Encode the payload as JSON
$payload = json_encode($body);

// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;

// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));

if (!$result)
	echo 'Message not delivered' . PHP_EOL;
else
	echo 'Message successfully delivered' . PHP_EOL;

// Close the connection to the server
fclose($fp);
}
else if($deviceType == 'android'){

$deviceToken = 'xxxxx';

$registrationIds = array($deviceToken);

// prep the bundle
$msg = array
(
    'message' 		=> 'Technovault is awesome!!!',
	'title'			=> '[Warning]',
	'subtitle'		=> 'This is a subtitle. subtitle',
	'tickerText'	=> 'Ticker text here...Ticker text here...Ticker text here',
	'vibrate'	=> 1,
	'sound'		=> 1
);

$fields = array
(
	'registration_ids' 	=> $registrationIds,
	'data'				=> $msg
);

$headers = array
(
	'Authorization: key=' . 'xxxxx',
	'Content-Type: application/json'
);

$ch = curl_init();
curl_setopt( $ch,CURLOPT_URL, 'https://android.googleapis.com/gcm/send' );
curl_setopt( $ch,CURLOPT_POST, true );
curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );
$result = curl_exec($ch );
curl_close( $ch );

echo $result;
}
else {
	echo "Error";
}

Now type the following from the command line where the script was created to run the code and send a push notification:
php simplepush.php

You should hear the notification and see it in your status bar like this on your Android and iOS devices.

Develop a simple to-do-list mobile app using phonegap/cordova for iOS and android -Part 3

This tutorial is the third part of a three-part series on how to create a simple to-do-list app for beginners.

In the first part of the tutorial series, setup development environment using certain IDE for iOS/android and preview your iOS and android hybrid app using emulator and actual device (smart phone). http://blog.revivalx.com/2014/11/02/develop-a-simple-to-do-list-mobile-app-using-phonegapcordova-for-ios-and-android-part-1/

In this second tutorial, you’ll learn how to develop iOS and android hybrid app using client side language and create multi page application for iOS and android hybrid app. http://blog.revivalx.com/2014/11/03/develop-a-simple-to-do-list-mobile-app-using-phonegapcordova-for-ios-and-android-part-2/

In this third tutorial, you will learn how to create a simple web service for your app. Your web service will enable to create, read, update and data using JSON ( Javascript Object Notation) to your database. We will not using SOAP (Simple Object Access Protocol) for this tutorial because JSON is easy to learn and simple compare to SOAP is too complex for beginner. It basically works on HTTP protocol.

URL Structure

In web service design the URL endpoints should be well formed and should be easily understandable. Every URL for a resource should be uniquely identified.

For example

GET – http://localhost:8888/todolist/todo/index
GET – http://localhost:8888/todolist/todo/display?taskId=1
POST – http://localhost:8888/todolist/todo/create
POST – http://localhost:8888/todolist/todo/update?taskId=1
POST – http://localhost:8888/todolist/todo/delete?taskId=1

Why we using JSON for mobile application? Why not we access directly to our database without using JSON instead PHP or JAVA. It is because hybrid mobile app support client side languages, not servers side languages. Hybrid mobile app consists these 3 languages are HTML5, CSS and Javascript. We can’t simply run PHP or JAVA in mobile app. This video (http://coenraets.org/blog/2013/05/architecting-a-phonegap-application-video-slides/) will answer these questions.

Getting started.

For this tutorial you need to have basic in PHP and Mysql. You need to have eclipse Helios (https://www.eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/heliossr2 ) to complete the project. Compare to previous tutorial we using eclipse Juno. It is because we develop an android app. For eclipse PHP we develop web service using PHP.

First you need to setup a web server in your machine. I’m using MAMP (stands for Mac, Apache, Mysql and Php) for this tutorial. It’s ok if your want to use other than this such as XAMPP or WAMP. No problem with that. But i suggest you using MAMP if you using Mac. There will be a lot of glitches if you using XAMPP or WAMP in your apple machine.

MAMP – http://www.mamp.info/en/downloads/

XAMPP – https://www.apachefriends.org/download.html

WAMP – http://www.wampserver.com/en/

Download MAMP and install to your machine. After finish installed MAMP to your machine, start apache server and mysql server. So far I didn’t get any issues starting my web server compare to XAMPP. If you got problem start up your apache server, make sure you check port 80 because maybe other applications using the same port especially skype. you need to terminate the application before start the apache server. This issue always happened to windows users.

If your apache and mysql server running successful, you will get like this (green light on both server status).

MAMP

MAMP

Then open your chrome browser. Why I’m using chrome rather than other browser because there are a tons of chrome extensions available in chrome marketplace. That’s why i choose to live with it. Type this to open your MAMP start page in your browser.

http://localhost:8888/MAMP/?language=English

Then click phpMyAdmin at top of the bar. You will see this page.

phpmyadmin

phpmyadmin

You need to create a database and a table for this tutorial. Click database tab. Then create ‘todolist‘. Copy this sql script to your sql tab to generate task table.

CREATE TABLE `tasks` (
`taskId` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(250) NOT NULL,
`description` varchar(500) NOT NULL,
`dateCreated` datetime NOT NULL,
`dateUpdated` datetime NOT NULL,
PRIMARY KEY (`taskId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

After executing these queries go through each tables and make sure that everything created correctly. Until now we are done with getting your system ready for development. Run your eclipse Helios to start develop web service. Right click in PHP explore > New > PHP Project.

eclipe helios

eclipe helios

Type todolist-api in project name. At content part, choose create project at existing location (from existing source). Type path name in directory field. /Applications/MAMP/htdocs/todolist-api  . Click Finish.

Right click in your project, select New > PHP File .

PHP File

PHP File

Type db_config.php and click Finish.

You need to create 5 more php files for db_connect.php, create_task.php, get_task_details.php, get_all_tasks.php, update_task.php and delete_task.php. You can check reference that I take from this site for this tutorial.

db_config.php – database configuration / setting.

db_connect.php – database connection.

create_task.php – create task details into database.

get_task_tasks.php – get task details base on task id from database.

get_all_tasks – retrieve all list of tasks.

update_task.php – update task into database base on task id.

delete_task.php – delete task from database base on task id.

Fill up all these PHP files using these code.

db_config.php

<?php
define('DB_USER', "root"); // db user
define('DB_PASSWORD', "root"); // db password (mention your db password here)
define('DB_DATABASE', "todolist"); // database name
define('DB_SERVER', "localhost"); // db server
?>

db_connect.php

<?php
class DB_CONNECT {

    // constructor
    function __construct() {
        // connecting to database
        $this->connect();
    }

    // destructor
    function __destruct() {
        // closing db connection
        $this->close();
    }

    /**
     * Function to connect with database
     */
    function connect() {
        // import database connection variables
        require_once __DIR__ . '/db_config.php';

        // Connecting to mysql database
        $con = mysql_connect(DB_SERVER, DB_USER, DB_PASSWORD) or die(mysql_error());

        // Selecing database
        $db = mysql_select_db(DB_DATABASE) or die(mysql_error()) or die(mysql_error());

        // returing connection cursor
        return $con;
    }

    /**
     * Function to close db connection
     */
    function close() {
        // closing db connection
        mysql_close();
    }

}

?>

create_task.php

<?php

/*
 * Following code will create a new task row
 * All task details are read from HTTP Post Request
 */

// array for JSON response
$response = array();

// check for required fields
if (isset($_POST['name']) && isset($_POST['description'])) {

    $name = $_POST['name'];
    $description = $_POST['description'];

    // include db connect class
    require_once __DIR__ . '/db_connect.php';

    // connecting to db
    $db = new DB_CONNECT();

    // mysql inserting a new row
    $result = mysql_query("INSERT INTO tasks(name, description, dateCreated, dateUpdated) VALUES('$name', '$description', NOW(), NOW())");

    // check if row inserted or not
    if ($result) {
        // successfully inserted into database
        $response["success"] = 1;
        $response["message"] = "Task successfully created.";

        // echoing JSON response
        echo json_encode($response);
    } else {
        // failed to insert row
        $response["success"] = 0;
        $response["message"] = "Oops! An error occurred.";

        // echoing JSON response
        echo json_encode($response);
    }
} else {
    // required field is missing
    $response["success"] = 0;
    $response["message"] = "Required field(s) is missing";

    // echoing JSON response
    echo json_encode($response);
}
?>

get_task_details.php

<?php

/*
 * Following code will get single task details
 * A task is identified by task id (taskId)
 */

// array for JSON response
$response = array();

// include db connect class
require_once __DIR__ . '/db_connect.php';

// connecting to db
$db = new DB_CONNECT();

// check for post data
if (isset($_GET["taskId"])) {
    $taskId = $_GET['taskId'];

    // get a task from task table
    $result = mysql_query("SELECT *FROM tasks WHERE taskId = $taskId");

    if (!empty($result)) {
        // check for empty result
        if (mysql_num_rows($result) > 0) {

            $result = mysql_fetch_array($result);

            $task = array();
            $task["taskId"] = $result["taskId"];
            $task["name"] = $result["name"];
            $task["description"] = $result["description"];
            $task["dateCreated"] = $result["dateCreated"];
            $task["dateUpdated"] = $result["dateUpdated"];
            // success
            $response["success"] = 1;

            // task node
            $response["task"] = array();

            array_push($response["task"], $task);

            // echoing JSON response
            echo json_encode($response);
        } else {
            // no task found
            $response["success"] = 0;
            $response["message"] = "No task found";

            // echo no tasks JSON
            echo json_encode($response);
        }
    } else {
        // no task found
        $response["success"] = 0;
        $response["message"] = "No task found";

        // echo no tasks JSON
        echo json_encode($response);
    }
} else {
    // required field is missing
    $response["success"] = 0;
    $response["message"] = "Required field(s) is missing";

    // echoing JSON response
    echo json_encode($response);
}
?>

get_all_tasks.php

<?php

/*
 * Following code will list all the tasks
 */

// array for JSON response
$response = array();

// include db connect class
require_once __DIR__ . '/db_connect.php';

// connecting to db
$db = new DB_CONNECT();

// get all tasks from task table
$result = mysql_query("SELECT *FROM tasks") or die(mysql_error());

// check for empty result
if (mysql_num_rows($result) > 0) {
    // looping through all results
    // tasks node
    $response["tasks"] = array();

    while ($row = mysql_fetch_array($result)) {
        // temp tasks array
        $tasks = array();
        $task["taskId"] = $row["taskId"];
        $task["name"] = $row["name"];
        $task["description"] = $row["description"];
        $task["dateCreated"] = $row["dateCreated"];
        $task["dateUpdated"] = $row["dateUpdated"];

        // push single task into final response array
        array_push($response["tasks"], $task);
    }
    // success
    $response["success"] = 1;

    // echoing JSON response
    echo json_encode($response);
} else {
    // no tasks found
    $response["success"] = 0;
    $response["message"] = "No tasks found";

    // echo no tasks JSON
    echo json_encode($response);
}
?>

update_task.php

<?php

/*
 * Following code will update a task information
 * A task is identified by task id (taskId)
 */

// array for JSON response
$response = array();

// check for required fields
if (isset($_POST['taskId']) && isset($_POST['name']) && isset($_POST['description'])) {

    $taskId = $_POST['taskId'];
    $name = $_POST['name'];
    $description = $_POST['description'];

    // include db connect class
    require_once __DIR__ . '/db_connect.php';

    // connecting to db
    $db = new DB_CONNECT();

    // mysql update row with matched pid
    $result = mysql_query("UPDATE tasks SET name = '$name', description = '$description', dateUpdated = NOW() WHERE taskId = $taskId");

    // check if row inserted or not
    if ($result) {
        // successfully updated
        $response["success"] = 1;
        $response["message"] = "Task successfully updated.";

        // echoing JSON response
        echo json_encode($response);
    } else {

    }
} else {
    // required field is missing
    $response["success"] = 0;
    $response["message"] = "Required field(s) is missing";

    // echoing JSON response
    echo json_encode($response);
}
?>

delete_task.php

<?php

/*
 * Following code will delete a task from table
 * A task is identified by task id (taskId)
 */

// array for JSON response
$response = array();

// check for required fields
if (isset($_POST['taskId'])) {
    $taskId = $_POST['taskId'];

    // include db connect class
    require_once __DIR__ . '/db_connect.php';

    // connecting to db
    $db = new DB_CONNECT();

    // mysql update row with matched taskId
    $result = mysql_query("DELETE FROM tasks WHERE taskId = $taskId");

    // check if row deleted or not
    if (mysql_affected_rows() > 0) {
        // successfully updated
        $response["success"] = 1;
        $response["message"] = "Task successfully deleted";

        // echoing JSON response
        echo json_encode($response);
    } else {
        // no task found
        $response["success"] = 0;
        $response["message"] = "No task found";

        // echo no tasks JSON
        echo json_encode($response);
    }
} else {
    // required field is missing
    $response["success"] = 0;
    $response["message"] = "Required field(s) is missing";

    // echoing JSON response
    echo json_encode($response);
}
?>

After you fill up the files, you need to install Curl in your machine. Curl is a command line tool for transferring data with URL syntax. Install curl via npm. Type this command to install. If you using windows, run this command in your command prompt.

npm install curl
npm install curl

npm install curl

npm install curl

npm install curl

Run this command to test create_task.php in your terminal.

curl POST

curl POST

Success status for create_task.php

{"success":1,"message":"Task successfully created."}

Run it again twice using different data.

Proceed all these curl commands for each URLs

get_task_details.php

curl http://localhost:8888/todolist-api/get_task_details.php?taskId=1

Success status for get_task_details.php

{
	"success": 1,
	"task": [{
		"taskId": "1",
		"name": "Breakfast",
		"description": "Nasi Lemak",
		"dateCreated": "2014-11-07 01:48:32",
		"dateUpdated": "2014-11-07 01:48:32"
	}]
}

get_all_tasks.php

curl http://localhost:8888/todolist-api/get_all_tasks.php

Success status for get_all_tasks.php

{
	"tasks": [{
		"taskId": "1",
		"name": "Breakfast",
		"description": "Nasi Lemak",
		"dateCreated": "2014-11-07 01:48:32",
		"dateUpdated": "2014-11-07 01:48:32"
	}, {
		"taskId": "2",
		"name": "Afternoon",
		"description": "Nasi Kukus",
		"dateCreated": "2014-11-07 01:53:14",
		"dateUpdated": "2014-11-07 01:53:14"
	}, {
		"taskId": "3",
		"name": "Dinner",
		"description": "Nasi Goreng",
		"dateCreated": "2014-11-07 01:53:31",
		"dateUpdated": "2014-11-07 01:53:31"
	}],
	"success": 1
}

update_task.php

curl -X POST -F taskId=1 -F name=Supper -F description=KFC http://localhost:8888/todolist-api/update_task.php

Success status for update_task.php

{"success":1,"message":"Task successfully updated."}

delete_task.php

curl -X POST -F taskId=1 http://localhost:8888/todolist-api/delete_task.php

Success status for delete_task.php

{"success":1,"message":"Task successfully deleted"}

Now we want to integrate PHP with the 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 description = $("#description").val();
    formData = {
        name: $("#name").val(),
        description: $("#description").val()
    }
    if (name == "") {
        alert("Please enter name");
    } else if (description == "") {
        alert("Please enter description");
    } else {
        $.ajax({
            type: "post",
            url: "http://demo.revivalx.com/todolist-api/create_task.php",
            data: formData,
            dataType: "json",
            success: function(data) {
                alert("Add task success");
                $("body").load(path + "pages/ListPage.html", function() {
                    $.getScript(path + "js/ListPage.js", function() {
                        if (currentPage.init) {
                            currentPage.init();
                        }
                    });
                });
            },
            error: function() {
                alert("Add task failure");
            }
        });
    }
};

DetailPage.js

currentPage = {};
currentPage.init = function() {
    console.log("DetailPage :: init");
    detailTask();
};
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 taskId = sessionStorage.taskId;
    var name = $("#name").val();
    var description = $("#description").val();
    formData = {
        taskId: sessionStorage.taskId,
        name: $("#name").val(),
        description: $("#description").val()
    }
    if (name == "") {
        alert("Please enter name");
    } else if (description == "") {
        alert("Please enter description");
    } else {
        $.ajax({
            type: "post",
            url: "http://demo.revivalx.com/todolist-api/update_task.php",
            data: formData,
            dataType: "json",
            success: function(data) {
                alert("Edit task success");
                $("body").load(path + "pages/ListPage.html", function() {
                    $.getScript(path + "js/ListPage.js", function() {
                        if (currentPage.init) {
                            currentPage.init();
                        }
                    });
                });
            },
            error: function() {
                alert("Edit task failure");
            }
        });
    }
};

function detailTask() {
    formData = {
        taskId: sessionStorage.taskId
    }
    $.ajax({
        type: "get",
        url: "http://demo.revivalx.com/todolist-api/get_task_details.php",
        data: formData,
        dataType: "json",
        success: function(data) {
            $('#name').val(data.task[0].name);
            $('#description').val(data.task[0].description);
        },
        error: function() {
            alert("Detail task failure");
        }
    });
}
currentPage.remove = function() {
    console.log("DetailPage :: delete");
    deleteTask();
};

function deleteTask() {
    formData = {
        taskId: sessionStorage.taskId
    }
    $.ajax({
        type: "post",
        url: "http://demo.revivalx.com/todolist-api/delete_task.php",
        data: formData,
        dataType: "json",
        success: function(data) {
            alert("Delete task success");
            $("body").load(path + "pages/ListPage.html", function() {
                $.getScript(path + "js/ListPage.js", function() {
                    if (currentPage.init) {
                        currentPage.init();
                    }
                });
            });
        },
        error: function() {
            alert("Delete task failure");
        }
    });
}

ListPage.js

currentPage = {};
currentPage.init = function() {
    console.log("ListPage :: init");
    listTasks();
};
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(taskId) {
    sessionStorage.setItem("taskId", taskId);
    $("body").load(path + "pages/DetailPage.html");
    $.getScript(path + "js/DetailPage.js", function() {
        if (currentPage.init) {
            currentPage.init();
        }
    });
};

function listTasks() {
    $.ajax({
        type: "get",
        url: "http://demo.revivalx.com/todolist-api/get_all_tasks.php",
        dataType: "json",
        success: function(data) {
            var ul = $('#taskList');
            var html = '';
            $.each(data.tasks, function(index, item) {
                html += '<li class="table-view-cell">';
                html += '<a class="navigate-right" onclick="currentPage.detailPage(' + item.taskId + ');" >';
                html += item.name;
                html += '</a></li>';
            });
            ul.append(html);
        },
        error: function() {
            alert("List task 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">Description:</li>
 
        <li class="table-view-cell"><input id="description" name="description" 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 TASK</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">Description:</li>
 
        <li class="table-view-cell"><input id="description" name="description" type="text"></li>
 
    </ul>
   </div>
   <div class="card" style="margin-bottom:40px;">
    	<button class="btn btn-positive btn-block" onclick="currentPage.edit();">EDIT TASK</button>
   </div>
   <div class="card" style="margin-bottom:40px;">
    	<button class="btn btn-negative btn-block" onclick="currentPage.remove();">REMOVE TASK</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="taskList" class="table-view"></ul>
</div>

Build and run your app. You can find the source code here: https://github.com/datomnurdin/com.revivalx.cordova.todomobile