21
© Copyright IBM Corporation 2013 Trademarks Create a mobile-friendly to-do list app with PHP, jQuery Mobile, and Google Tasks Page 1 of 21 Create a mobile-friendly to-do list app with PHP, jQuery Mobile, and Google Tasks Vikram Vaswani Founder and CEO of Melonfire Melonfire 13 December 2013 Want a build a simple mobile app to create and manage your to-do lists? It's easy with the Slim PHP micro-framework, jQuery Mobile, and the Google Tasks API. I'll show you how I did it. To view the introductory video Create a mobile-friendly to-do list app with PHP, jQuery Mobile, and Google Tasks please access the online version of the article. I used to keep track of my to-do list with a Windows desktop application. I'd pop it open every time I remembered something important, type in a brief label, assign a due date, and save it. The application would launch every time I logged in to the system, so I'd immediately know what needed attention and when. This Windows app worked well, except for two limitations: I couldn't check my to-do list or add tasks when I was away from my computer. “ Then I found Google Tasks. It enabled me to check my tasks, and add new ones, while I was on the go. ” Google Tasks is integrated with Gmail (though not many people are aware of it), and it lets you create and manage to-do lists online. Since you can access your task list through a browser, it's easy to add, view, and close tasks even while you're on the move. Get the code at JazzHub What you'll need to build your to-do list app • An Apache/PHP development environment • A Google account for testing purposes Slim This PHP micro-framework will add structure to your PHP code. Google APIs Client Library for PHP This library provides a robust OAuth implementation and wrapper objects that simplify access to all the Google APIs. jQuery Mobile

Mo Php Todolist App PDF

Embed Size (px)

DESCRIPTION

Mo Php Todolist App PDF

Citation preview

Page 1: Mo Php Todolist App PDF

© Copyright IBM Corporation 2013 TrademarksCreate a mobile-friendly to-do list app with PHP, jQuery Mobile,and Google Tasks

Page 1 of 21

Create a mobile-friendly to-do list app with PHP, jQueryMobile, and Google TasksVikram VaswaniFounder and CEO of MelonfireMelonfire

13 December 2013

Want a build a simple mobile app to create and manage your to-do lists? It's easy with the SlimPHP micro-framework, jQuery Mobile, and the Google Tasks API. I'll show you how I did it.

To view the introductory video Create a mobile-friendly to-do list app with PHP, jQueryMobile, and Google Tasks please access the online version of the article.

I used to keep track of my to-do list with a Windows desktop application. I'd pop it open everytime I remembered something important, type in a brief label, assign a due date, and save it.The application would launch every time I logged in to the system, so I'd immediately know whatneeded attention and when.

This Windows app worked well, except for two limitations: I couldn't check my to-do list or addtasks when I was away from my computer.

“ Then I found Google Tasks. It enabled me to check mytasks, and add new ones, while I was on the go. ”

Google Tasks is integrated with Gmail (though not many people are aware of it), and it lets youcreate and manage to-do lists online. Since you can access your task list through a browser, it'seasy to add, view, and close tasks even while you're on the move.

Get the code at JazzHub

What you'll need to build your to-do list app• An Apache/PHP development environment• A Google account for testing purposes• Slim

This PHP micro-framework will add structure to your PHP code.• Google APIs Client Library for PHP

This library provides a robust OAuth implementation and wrapper objects that simplify accessto all the Google APIs.

• jQuery Mobile

Page 2: Mo Php Todolist App PDF

developerWorks® ibm.com/developerWorks/

Create a mobile-friendly to-do list app with PHP, jQuery Mobile,and Google Tasks

Page 2 of 21

This framework gets your application's user interface up and running quickly, with minimalplatform and browser compatibility issues.

READ: OAuth 2.0 authentication

What you'll need to know

Like many other Google products, Google Tasks exposes a Tasks API that allows third-partyapplications to connect to it and build custom applications around its data. This API, which followsthe REST model, can be accessed through any REST-capable development toolkit, and alreadyhas client libraries for many common programming languages, including my favourite, PHP.

To understand the PHP example code I show here, you should know the basics of classes andobjects in PHP and be comfortable working with REST. You should also be familiar with HTML,CSS, and jQuery.

Let's get started!

Configure dependent libraries and components

First, set up Slim.

If you're not familiar with Slim, it's a PHP micro-framework for rapid development of webapplications and APIs. Don't be fooled by the name: Slim includes a sophisticated URL router andsupport for page templates, flash messages, encrypted cookies, and middleware. It's extremelyeasy to understand and use, and it comes with great documentation and an enthusiastic developercommunity.

Step 1. Create the application directory structure with the Slim and GoogleOAuth libraries

Change to the web server's document root directory (typically /usr/local/apache/htdocs onLinux, or C:\Program Files\Apache\htdocs on Windows) and create a new subdirectory for theapplication. Name this directory tasks.

shell> cd /usr/local/apache/htdocsshell> mkdir tasks

This directory will be referenced in this article as $APP_ROOT.

Assuming you have downloaded the Slim framework and the Google OAuth library described inthe previous section, extract these libraries to $APP_ROOT/vendor. Also transfer the index.php and.htaccess files from the Slim download archive to your $APP_ROOT directory, and edit the index.phpfile to reflect the correct path to the Slim.php file.

Your directory structure should now look like this:

Page 3: Mo Php Todolist App PDF

ibm.com/developerWorks/ developerWorks®

Create a mobile-friendly to-do list app with PHP, jQuery Mobile,and Google Tasks

Page 3 of 21

Step 2. Define a virtual host

To make it easier to access the application, it's a good idea to define a new virtual host and setit to the working directory. To do this, edit the Apache configuration file (httpd.conf or httpd-vhosts.conf) and add the following lines to it:

NameVirtualHost 127.0.0.1<VirtualHost 127.0.0.1> DocumentRoot "/usr/local/apache/htdocs/tasks" ServerName tasks.melonfire.com</VirtualHost>

These lines define a new virtual host whose document root corresponds to the $APP_ROOT. In theabove listing, the name of this host is tasks.melonfire.com. Remember that you will need tochange this to either localhost or another domain under your control.

Restart the web server to activate these new settings. Note that it might be necessary to updateyour network's local DNS server to let it know about the new host as well.

Once you're done, point your browser to your new host. You should see the Slim frameworkwelcome page:

Page 4: Mo Php Todolist App PDF

developerWorks® ibm.com/developerWorks/

Create a mobile-friendly to-do list app with PHP, jQuery Mobile,and Google Tasks

Page 4 of 21

Step 3. Register your application with the Google Apps Platform

Before you can use the Google Tasks API, you need to register your web application with Google.To do this, log in to Google using your Google Account credentials and visit the Google CloudConsole. Create a new project, assign it a name, and then turn on access to the Google TasksAPI. Your project in the Google Cloud Console should look something like this:

Page 5: Mo Php Todolist App PDF

ibm.com/developerWorks/ developerWorks®

Create a mobile-friendly to-do list app with PHP, jQuery Mobile,and Google Tasks

Page 5 of 21

Next, register your web application to obtain an OAuth 2.0 client id and secret. Make note of thesevalues, are you will need them for the Google PHP OAuth client.

Remember to also set the application redirect URL at this point. This is the URL to which Googlewill redirect the client browser after completing the OAuth authentication process. In this example,this URL is set to http://tasks.melonfire.com/login:

Page 6: Mo Php Todolist App PDF

developerWorks® ibm.com/developerWorks/

Create a mobile-friendly to-do list app with PHP, jQuery Mobile,and Google Tasks

Page 6 of 21

While you're logged in, you should also visit Gmail, which includes an integrated Google Tasksinterface, and add a few sample task lists and tasks to it. This is useful to check that the PHPapplication is working correctly. The Google Tasks interface in Gmail looks something like this:

This probably seems like a lot of hoops to jump through, but the good news is that you only haveto do it once.

Understanding the Tasks APIThe Google Tasks API works by accepting REST requests for actions on resources andresponding with the requested information. A resource is simply a URL referencing the object orentity on which the actions are to be performed — such as /lists or /users. An action is one ofthe four HTTP "verbs" — such as GET (retrieve), POST (create), PUT (update), and DELETE(remove).

The Google Tasks API includes two primary resources: tasks and task lists. A user can havemultiple task lists, each of which can have multiple tasks. Tasks always exist within a task list. TheGoogle Tasks API considers the first task list created by a user to be his or her "default" task list.

The Google Tasks API encodes responses in JSON format. Below is an example of an APIresponse, which issues an authenticated GET request to https://www.googleapis.com/tasks/v1/lists/@default/tasks, the API endpoint for retrieving the user's default task list.

Listing 1. Sample Google Tasks API response{ "kind": "tasks#tasks", "etag": "\"zhaMOBt\"", "items": [ { "kind": "tasks#task",

Page 7: Mo Php Todolist App PDF

ibm.com/developerWorks/ developerWorks®

Create a mobile-friendly to-do list app with PHP, jQuery Mobile,and Google Tasks

Page 7 of 21

"id": "MTc3Mz", "etag": "\"zhaMOBt\"", "title": "Milk", "updated": "2013-11-11T07:46:09.000Z", "selfLink": "https://www.googleapis.com/tasks/v1/lists/MTc3Mz/tasks/MTc3MzQ1", "position": "00000000000637427684", "status": "needsAction" }, { "kind": "tasks#task", "id": "MTc3Mz", "etag": "\"zhaMOBt\"", "title": "Bread", "updated": "2013-11-11T07:46:11.000Z", "selfLink": "https://www.googleapis.com/tasks/v1/lists/MTc3Mz/tasks/MTc3MzQ6", "position": "00000000000717532232", "status": "needsAction" }, { ... } ]}

As Listing 1 shows, the Tasks API generates a JSON-encoded response containing a list oftasks. Each task entry contains some useful meta-data, such as the task title, due date, self URL,and status. It's now quite easy to decode this JSON and convert it into an HTML representationsuitable for display in a web browser. Most of the time, though, you won't be issuing raw GET andPOST requests to the Tasks API. The Google PHP OAuth client and its service objects provide aconvenient wrapper around such requests, encapsulating all related functionality into PHP objectsand methods.

Listing tasksListing 2 uses the Google OAuth library with the Slim framework to connect, authenticate anddisplay a summary of task lists and tasks.

Listing 2. OAuth authentication flow and task list retrieval<?phpsession_start();require_once 'vendor/Slim/Slim.php';require_once 'vendor/google-api-php-client/src/Google_Client.php';require_once 'vendor/google-api-php-client/src/contrib/Google_TasksService.php';

\Slim\Slim::registerAutoloader();$app = new \Slim\Slim();$app->config(array( 'debug' => true, 'templates.path' => './templates'));$client = new Google_Client();$client->setApplicationName('Project X');$client->setClientId('YOUR-CLIENT-ID');$client->setClientSecret('YOUR-CLIENT-SECRET');$client->setRedirectUri('http://tasks.melonfire.com/login');$client->setScopes(array( 'https://www.googleapis.com/auth/tasks'));$app->client = $client;$app->tasksService = new Google_TasksService($app->client);

Page 8: Mo Php Todolist App PDF

developerWorks® ibm.com/developerWorks/

Create a mobile-friendly to-do list app with PHP, jQuery Mobile,and Google Tasks

Page 8 of 21

$app->get('/login', function () use ($app) {

if (isset($_GET['code'])) { $app->client->authenticate(); $_SESSION['access_token'] = $app->client->getAccessToken(); $app->redirect('/index'); exit; }

// if token available in session, set token in client if (isset($_SESSION['access_token'])) { $app->client->setAccessToken($_SESSION['access_token']); }

if ($app->client->getAccessToken()) { if (isset($_SESSION['target'])) { $app->redirect($_SESSION['target']); } else { $app->redirect('/index'); } } else { $authUrl = $app->client->createAuthUrl(); $app->redirect($authUrl); }

});

$app->get('/index', 'authenticate', function () use ($app) { $lists = $app->tasksService->tasklists->listTasklists(); foreach ($lists['items'] as $list) { $id = $list['id']; $tasks[$id] = $app->tasksService->tasks->listTasks($id); } $app->render('index.php', array('lists' => $lists, 'tasks' => $tasks));});

$app->get('/logout', function () use ($app) { unset($_SESSION['access_token']); $app->client->revokeToken();});

$app->run();

function authenticate () { $app = \Slim\Slim::getInstance(); $_SESSION['target'] = $app->request()->getPathInfo(); if (isset($_SESSION['access_token'])) { $app->client->setAccessToken($_SESSION['access_token']); } if (!$app->client->getAccessToken()) { $app->redirect('/login'); }}

Listing 2, which should be saved as $APP_ROOT/index.php, begins by loading the Slim and GoogleOAuth client libraries, together with the Google Tasks service object. It initializes a new Slimapplication object and a new Google_Client object. Needless to say, the Google_Client objectmust be configured with the same client id, client secret, and redirect URL defined earlier in theGoogle Cloud Console. A Google_TasksService service object is also initialized; this serves as theprimary control point for interacting with the Google Tasks API through PHP.

Page 9: Mo Php Todolist App PDF

ibm.com/developerWorks/ developerWorks®

Create a mobile-friendly to-do list app with PHP, jQuery Mobile,and Google Tasks

Page 9 of 21

Slim works by defining router callbacks for HTTP methods and endpoints. This is done simply bycalling the corresponding method —get() for GET requests, post() for POST requests, and soon — and passing the URL route to be matched as the first argument to the method. The secondargument to the method is a function, which specifies the actions to be taken when the route ismatched to an incoming request. Listing 2 sets up three such router callbacks: /index, /login, and/logout. Let's look at each of these in turn:

• The /login callback handles the OAuth authentication flow. A complete discussion of thisflow is outside the scope of this article, although you can get exhaustive details throughthe Google API documentation. Briefly, this callback uses the Google_Client object'screateAuthUrl() method to generate a URL to the Google authentication page (see the nextfigure) and then redirects the client browser to this URL. Once the user authenticates theapplication and confirms the data it has access to, Google redirects the client back to the /login URL, which retrieves an access token and stores it in the session. This access tokengives the client access to the Google Tasks API.

• Successful OAuth authentication redirects the client to the application's index page,located at /index. This callback uses the configured Google_TasksService object and itslistTasklists() method to retrieve a list of the authenticated user's task lists. The codethen iterates over this collection of task lists and for each list, it invokes the service object'slistTasks() method to retrieve the individual tasks within the list. This information is thentransferred to the view, which takes care of rendering it to the user. I'll show you the viewscript further along.

• The /logout method destroys the session, thereby nullifying the access token stored in it.For additional security, it also invokes the client object's revokeToken() method, which alsoinvalidates the token on Google's servers.

You've already seen that the /index callback takes care of retrieving the user's task lists and thetasks for each list. This information is stored in PHP variables and transferred to the view, whichis responsible for formatting it into a human-readable list. The view script should be located at$APP_ROOT/templates/index.php and it looks like this:

Page 10: Mo Php Todolist App PDF

developerWorks® ibm.com/developerWorks/

Create a mobile-friendly to-do list app with PHP, jQuery Mobile,and Google Tasks

Page 10 of 21

Listing 3. Index page

<!DOCTYPE html><html><head> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="http://code.jquery.com/ mobile/1.3.2/jquery.mobile-1.3.2.min.css" /> <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> <script src="http://code.jquery.com/mobile/1.3.2/ jquery.mobile-1.3.2.min.js"></script></head><body> <div data-role="page"> <div data-role="header"> Tasks </div> <div data-role="content"> <div data-role="collapsible-set" data-inset="false"> <?php foreach ($lists['items'] as $list): ?> <?php $id = $list['id']; ?> <div data-role="collapsible"> <h2><?php echo $list['title']; ?></h2> <ul data-role="listview"> <?php if (isset($tasks[$id]['items'])): ?> <?php foreach ($tasks[$id]['items'] as $task): ?> <li> <h3><?php echo $task['title']; ?></h3> </li> <?php endforeach; ?> <?php endif; ?> </ul> </div> <?php endforeach; ?> </div> </div> </div></body></html>

Listing 3 sets up a listview page formatted according to standard jQuery Mobile conventions.The primary page element is a <div> element with a data-role="page" attribute. Within this areseparate <div> elements for the page header, footer, and content. The page content consists of aseries of collapsible <div> elements, with each such element representing one of the user's tasklists. Clicking the title of a list unfolds its tasks.

To see how this works, visit http://tasks.melonfire.com/index (replace the URL with that of yourown virtual host) in your browser. You should see a task listing like this:

Page 11: Mo Php Todolist App PDF

ibm.com/developerWorks/ developerWorks®

Create a mobile-friendly to-do list app with PHP, jQuery Mobile,and Google Tasks

Page 11 of 21

Creating and deleting task listsOf course, displaying tasks is just the first step; you'd also like users to be able to add new tasksand task lists. So, let's define a new route in $APP_ROOT/index.php:

<?php

// ... other routes

$app->get('/add-list', 'authenticate', function () use ($app) { $app->render('add-list.php');});

With this, a request to /add-list will result in the $APP_ROOT/templates/add-list.phptemplate being rendered to the user. The next listing shows the contents of this template. Theauthenticate() function is a custom function that is executed before the route callback isexecuted; look in Listing 2 and you'll see that it checks for an access token and redirects the clientto the login page if no such token is found, prompting a re-login.

Listing 4. Task list creation form<!DOCTYPE html><html><head> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.2/ jquery.mobile-1.3.2.min.css" /> <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> <script src="http://code.jquery.com/mobile/1.3.2/ jquery.mobile-1.3.2.min.js"></script></head>

Page 12: Mo Php Todolist App PDF

developerWorks® ibm.com/developerWorks/

Create a mobile-friendly to-do list app with PHP, jQuery Mobile,and Google Tasks

Page 12 of 21

<body> <div data-role="page"> <div data-role="header"> Add List </div> <div data-role="content"> <div data-role="collapsible-set"> <form method="post" action="/add-list"> <label for="title">Title:</label> <input name="title" id="title" data-clear-btn="true" type="text"/> <input name="submit" value="Save" type="submit" data-icon="check" data-inline="true" data-theme="a" /> <a href="/index" data-role="button" data-inline="true" data-icon="back" data-theme="a">Back</a> </form> </div> </div></body></html>

Listing 4 consists of a form with a single field, for the title of the new task list. On submission,the form data will be POST-ed back to the /add-list route, which now needs to be extended tohandle the form input. Here is the additional code:

Listing 5. Task list creation

<?php

// ... other routes

$app->post('/add-list', 'authenticate', function () use ($app) { if (isset($_POST['submit'])) { $title = trim(htmlentities($_POST['title'])); if (empty($title)) { $title = 'Untitled List'; } $tasklist = new Google_TaskList(); $tasklist->setTitle($title); $result = $app->tasksService->tasklists->insert($tasklist); $app->redirect('/index'); }});

Listing 5 sanitizes the title submitted through the form and then creates a new Google_TaskListobject. This object represents a task list resource in the Google Tasks API. The object'ssetTitle() method is used to assign a title, and the service object's insert() method is then usedto save the new task list to Google Tasks.

Here is the form, as well as the results of submitting it:

Page 13: Mo Php Todolist App PDF

ibm.com/developerWorks/ developerWorks®

Create a mobile-friendly to-do list app with PHP, jQuery Mobile,and Google Tasks

Page 13 of 21

If you now check the Google Tasks interface within Gmail, you should see your newly-added tasklist there as well. Try it for yourself and see!

If you're allowing users to add lists, you also need to give them a way to delete them. The inverseof the service object's insert() method is its delete() method, which accepts a task list identifierand deletes the corresponding list from Google Tasks. Here is the route definition:

Listing 6. Task list deletion<?php

// ... other routes

$app->get('/delete-list/:lid', 'authenticate', function ($lid) use ($app) { $app->tasksService->tasklists->delete($lid); $app->redirect('/index');});

Listing 6 sets up a new route, /delete-list, which accepts a list identifier as part of the requestURL. This request URL is then parsed by Slim's routing framework, the list identifier is extracted,and the service object's delete() method is used to remove the corresponding list from GoogleTasks.

All that's left now is to update the index page listing with additional buttons to add and remove lists.Here is the code for the revised index page:

Listing 7. Index page<!DOCTYPE html><html><head> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.2/ jquery.mobile-1.3.2.min.css" /> <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> <script src="http://code.jquery.com/mobile/1.3.2/ jquery.mobile-1.3.2.min.js"></script></head><body> <div data-role="page"> <div data-role="header"> Tasks </div> <div data-role="content"> <div data-role="collapsible-set" data-inset="false">

Page 14: Mo Php Todolist App PDF

developerWorks® ibm.com/developerWorks/

Create a mobile-friendly to-do list app with PHP, jQuery Mobile,and Google Tasks

Page 14 of 21

<?php foreach ($lists['items'] as $list): ?> <?php $id = $list['id']; ?> <div data-role="collapsible"> <h2><?php echo $list['title']; ?></h2> <ul data-role="listview"> <?php if (isset($tasks[$id]['items'])): ?> <?php foreach ($tasks[$id]['items'] as $task): ?> <li> <?php if ($task['status'] == 'needsAction'): ?> <h3><?php echo $task['title']; ?></h3> <?php else: ?> <h3 style="text-decoration:line-through" ><?php echo $task['title']; ?></h3> <?php endif; ?> <?php if (isset($task['due']) && ($task['status'] == 'needsAction')): ?> <p>Due on <?php echo date('d M Y', strtotime($task['due'])); ?></p> <?php endif; ?> <?php if (isset($task['completed']) && ($task['status'] == 'completed')): ?> <p>Completed on <?php echo date('d M Y', strtotime($task['completed'])); ?></p> <?php endif; ?> </li> <?php endforeach; ?> <?php endif; ?> </ul> <a href="/delete-list/<?php echo $id; ?>" data-inline="true" data-role="button" data-icon="delete" data-theme="a">Remove list</a> </div> <?php endforeach; ?> </div> </div> <a href="/add-list" data-inline="true" data-role="button" data-icon="plus" data-theme="b">Add new list</a> </div></body></html>

In addition to new buttons to add and delete lists, this version of the view script also has someadditional enhancements. Due dates are now displayed for tasks, and completed tasks have aline drawn through them, while tasks that are still due (status="needsAction") don't. Here's what itlooks like.

Page 15: Mo Php Todolist App PDF

ibm.com/developerWorks/ developerWorks®

Create a mobile-friendly to-do list app with PHP, jQuery Mobile,and Google Tasks

Page 15 of 21

Creating and deleting tasksJust as it's possible to add and delete task lists, so too is it possible to add and delete tasks withina list. Here are new /add-item and /delete-item routes for this purpose:

Listing 8. Task addition and deletion<?php

// ... other routes

$app->get('/add-task/:tid', 'authenticate', function ($tid) use ($app) { $app->render('add-task.php', array('id' => $tid));});

$app->post('/add-task', 'authenticate', function () use ($app) { if (isset($_POST['submit'])) { $title = trim(htmlentities($_POST['title'])); $due = trim(htmlentities($_POST['due'])); $id = trim(htmlentities($_POST['id'])); if (empty($title)) { $title = 'Untitled Task'; } if (empty($due)) { $due = 'tomorrow'; }

Page 16: Mo Php Todolist App PDF

developerWorks® ibm.com/developerWorks/

Create a mobile-friendly to-do list app with PHP, jQuery Mobile,and Google Tasks

Page 16 of 21

$task = new Google_Task(); $task->setTitle($title); $task->setDue(date(DATE_RFC3339, strtotime($due))); $result = $app->tasksService->tasks->insert($id, $task); $app->redirect('/index'); }});

$app->get('/delete-task/:lid/:tid', 'authenticate', function ($lid, $tid) use ($app) { $app->tasksService->tasks->delete($lid, $tid); $app->redirect('/index');});

Every task must be associated with a task list and so, the /add-task route callback is set up toreceive a task list identifier as a GET request parameter. It then renders the $APP_ROOT/templates/add-task.php template, which contains a form to add new tasks and is described in this listing:

Listing 9. Task creation form

<!DOCTYPE html><html><head> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.2/ jquery.mobile-1.3.2.min.css" /> <link rel="stylesheet" type="text/css" href="http://dev.jtsage.com/cdn/ datebox/latest/jqm-datebox.min.css" /> <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> <script src="http://code.jquery.com/mobile/1.3.2/ jquery.mobile-1.3.2.min.js"></script> <script src="http://dev.jtsage.com/cdn/datebox/latest/ jqm-datebox.core.min.js"></script> <script src="http://dev.jtsage.com/cdn/datebox/latest/ jqm-datebox.mode.calbox.min.js"></script> <script src="http://dev.jtsage.com/cdn/datebox/i18n /jquery.mobile.datebox.i18n.en_US.utf8.js"></script></head><body> <div data-role="page"> <div data-role="header"> Add Task </div> <div data-role="content"> <div data-role="collapsible-set"> <form method="post" action="/add-task"> <input name="id" type="hidden" value="<?php echo $id; ?>" /> <label for="title">Title:</label> <input name="title" id="title" data-clear-btn="true" type="text"/> <label for="due">Due:</label> <input name="due" id="due" type="date" data-role="datebox" data-options='{"mode": "calbox", "useFocus": true, "themeDateToday": "e"}' /> <input name="submit" value="Save" type="submit" data-icon="check" data-inline="true" data-theme="a" /> <a href="/index" data-role="button" data-inline="true" data-icon="back" data-theme="a">Back</a> </form> </div> </div></body></html>

Page 17: Mo Php Todolist App PDF

ibm.com/developerWorks/ developerWorks®

Create a mobile-friendly to-do list app with PHP, jQuery Mobile,and Google Tasks

Page 17 of 21

Listing 9 contains a form with two visible fields, one for the task title and the other for the task duedate. To simplify date entry, the date input field is configured to use the jQuery Mobile DateBoxplugin, which displays a graphical date picker for point-and-click date entry. Since tasks must beassociated with a task list, the task list identifier received as a GET parameter is also specified inthe form as a hidden field.

Once the form is submitted, the data entered into it is sanitized and used to initialize a Google_Taskobject. This object, together with the hidden task list identifier, is then passed to the serviceobject's insert() method, which takes care of adding it to the Google Tasks system via a RESTinvocation. And finally, the /delete-task route callback, like the /add-task callback, is configuredto receive both a task list identifier and a task identifier. It then uses the service object's delete()method to remove the specified task from the specified task list.

With the routes and business login in place, all that's left is to update the index page with additionalbuttons for task addition and deletion. Since I'll soon explain how to update a task's status, this is agood time to also add a button for this functionality. Here is the revised template:

Listing 10. Index page<!DOCTYPE html><html><head> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.2/ jquery.mobile-1.3.2.min.css" /> <link rel="stylesheet" type="text/css" href="http://dev.jtsage.com/cdn/datebox/latest/jqm-datebox.min.css" /> <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> <script src="http://code.jquery.com/mobile/1.3.2/ jquery.mobile-1.3.2.min.js"></script> <script src="http://dev.jtsage.com/cdn/datebox/latest/ jqm-datebox.core.min.js"></script> <script src="http://dev.jtsage.com/cdn/datebox/latest/ jqm-datebox.mode.calbox.min.js"></script> <script src="http://dev.jtsage.com/cdn/datebox/i18n/ jquery.mobile.datebox.i18n.en_US.utf8.js"></script></head><body> <div data-role="page"> <div data-role="header"> Tasks </div> <div data-role="content"> <div data-role="collapsible-set" data-inset="false"> <?php foreach ($lists['items'] as $list): ?> <?php $id = $list['id']; ?> <div data-role="collapsible"> <h2><?php echo $list['title']; ?></h2> <ul data-role="listview"> <?php if (isset($tasks[$id]['items'])): ?> <?php foreach ($tasks[$id]['items'] as $task): ?> <li> <div class="ui-grid-b"> <div class="ui-block-a"> <?php if ($task['status'] == 'needsAction'): ?> <h3><?php echo $task['title']; ?></h3> <?php else: ?> <h3 style="text-decoration:line-through"> <?php echo $task['title']; ?></h3> <?php endif; ?>

Page 18: Mo Php Todolist App PDF

developerWorks® ibm.com/developerWorks/

Create a mobile-friendly to-do list app with PHP, jQuery Mobile,and Google Tasks

Page 18 of 21

<?php if (isset($task['due']) && ($task['status'] == 'needsAction')): ?> <p>Due on <?php echo date('d M Y', strtotime($task['due'])); ?></p> <?php endif; ?> <?php if (isset($task['completed']) && ($task['status'] == 'completed')): ?> <p>Completed on <?php echo date('d M Y', strtotime($task['completed'])); ?></p> <?php endif; ?> </div> <div class="ui-block-b"></div> <div class="ui-block-c"> <?php if ($task['status'] == 'needsAction'): ?> <a href="/update-task/<?php echo $id; ?>/ <?php echo $task['id']; ?>" data-inline="true" data-role="button" data-icon="check" data-theme="a">Done!</a> <?php endif; ?> <a href="/delete-task/ <?php echo $id; ?>/<?php echo $task['id']; ?>" data-inline="true" data-role="button" data-icon="delete" data-theme="a">Remove task</a> </div> </div> </li> <?php endforeach; ?> <?php endif; ?> </ul> <br/> <a href="/add-task/<?php echo $id; ?>" data-inline="true" data-role="button" data-icon="plus" data-theme="a">Add new task</a> <a href="/delete-list/<?php echo $id; ?>" data-inline="true" data-role="button" data-icon="delete" data-theme="a">Remove list</a> </div> <?php endforeach; ?> </div> <a href="/add-list" data-inline="true" data-role="button" data-icon="plus" data-theme="b">Add new list</a> </div> </div></body></html>

As shown in Listing 10, the markup for each task list has been updated to turn each list into atwo-column grid. The left column contains the task title and due date. The right column containsactions possible for that task, such as updating it or deleting it. Finally, a new button at the endmakes it possible to update the list with new tasks.

The process of adding a new task to a task list looks like this:

Page 19: Mo Php Todolist App PDF

ibm.com/developerWorks/ developerWorks®

Create a mobile-friendly to-do list app with PHP, jQuery Mobile,and Google Tasks

Page 19 of 21

Updating task status

So, your application now supports adding and deleting tasks and task lists. The last bit offunctionality you need is to mark tasks as complete. Listing 10 already includes a button for thisfunctionality, linked to the /update-task route. Listing 11 completes the circle, by specifying thebusiness logic for this route.

Listing 11. Task update

<?php

// ... other routes

$app->get('/update-task/:lid/:tid', 'authenticate', function ($lid, $tid) use ($app) { $task = new Google_Task($app->tasksService->tasks->get($lid, $tid)); $task->setStatus('completed'); $result = $app->tasksService->tasks->update($lid, $task->getId(), $task); $app->redirect('/index');});

The /update-task route callback receives both list and task identifiers and uses this information toretrieve task information from the Google Tasks API. This information is then used to populate anew Google_Tasks object, and the object's setStatus() method is used to change the task statusto "completed." The service object's update() method is then used to push the new task entry toGoogle's servers.

The process of marking a task as complete looks like this.

Page 20: Mo Php Todolist App PDF

developerWorks® ibm.com/developerWorks/

Create a mobile-friendly to-do list app with PHP, jQuery Mobile,and Google Tasks

Page 20 of 21

Summary

You're done! You got a crash course in how to integrate data from the Google Tasks API with aPHP application using a combination of jQuery Mobile, the Google PHP OAuth library, and theSlim PHP micro-framework. The examples in this article introduced you to the Google Tasks JSONformat and showed you how to retrieve task listings; add, modify and delete tasks; and build acustomized interface to the task lists in a user's Google Account.

As these examples illustrate, the Google Tasks API is a powerful and flexible tool when you wantto build creative new applications around task management. Play with it sometime, and see whatyou think!

RELATED TOPICS: PHP jQuery Mobile Google Tasks

Page 21: Mo Php Todolist App PDF

ibm.com/developerWorks/ developerWorks®

Create a mobile-friendly to-do list app with PHP, jQuery Mobile,and Google Tasks

Page 21 of 21

About the author

Vikram Vaswani

vikram-vaswani.in

© Copyright IBM Corporation 2013(www.ibm.com/legal/copytrade.shtml)Trademarks(www.ibm.com/developerworks/ibm/trademarks/)