Not To Do App

HTML 5 mobile web app from start to finish

 

It seems that these days the first app that anyone interested in mobile apps codes is a to-do list.
The market places are overflowing with to do list managers, advanced to do list tracking and so forth.
So to break away from the crowd, we're going to not make a to-do list and make a not to do list app instead.

The app should be simple with a basic list of tasks which are not to be done and the ability to store the tasks in local storage for the user.
Let's start by designing the basic look of the app in mobjectify and then add functionality with javascript.

We're going to cover the design along with adding of custom jQuery Mobile theme swatches, and then add functionality. You can skip to any section directly if you want.


Mocking up the Design

Open up the mobjectify editor. To the left is a list of available components you can add.

Create a page and give it a header with some heading like 'Not To Do'.
We can now add a list, this is going to be our main task list. Add some items to the list to get a feel of how it will look once it is actually running.
Click the generate button to see the design styled by jQuery Mobile.

Since the primary focus of our app is going to be the list, it makes more sense to have it full screen rather than inset.
Change the inset setting of the list to 'Fill Screen'
Also let's give the option to add a new task to the list. We can do this by adding a form and in the form we will have an input box and button

So far so good, let's link our tasks to a confirmation page asking the user whether to mark the tasks as done or not done.
Create a new 'page' and give it the name 'confirm', also let's rename our original page to 'index' to make it more meaningful

Click on the list items and in the 'link to' field, enter #confirm to link it to the confirm page.

Finally let's add some header items to the list to make it more seamless.
We can add one list item to denote the task list and another at the bottom to act as a separator and heading for the add functionality.
To style a list item as a heading, click it and select 'Use as heading'.
List items are always added at the bottom of the list so we need to rearrange them by dragging to the correct position.

We can now design the confirm page, which will basically have options to mark the task as 'Done' or 'Not Done' and we also want a 'Cancel' button incase the user decides to back out.

We will be linking the 'Cancel' button to the index page so that clicking cancel will take the user back to the task list.
To do this, in the button editing options click on 'More..', and set the button type to 'Link' and target as #index

Create two additional pages with names 'done' and 'notdone' so that we can have a message encouraging or showing our disappointment with the user, and we link these to the 'Done' and 'Not Done' buttons as before.

Click here to see our mocked up app

The app looks alright so far, and you can simply choose to use the export functionality to get the html for the mockup, but it's currently using the default colors provided by jQuery Mobile with no customizations.
Let's modify the theme a little to customize it as per our needs.

Add Custom theme colors

jQuery Mobile provides five color swatches as part of the default theme.
You can build a decent mobile web app using these colors, but what if we require colors that our not available by default?

In our app, we would like to change the 'Done' and 'Not Done' buttons to a red and green colored button respectively to make it more intuitive, but they are not available by default, so let's customize the jQuery Mobile theme as per our requirements.
Go to the 'themes' section to define the colors used by your application.

Click on the 'Create New' button, and a new custom swatch is created with no existing styling.
Since we are currently only interested in the button color, click the button in the new unstyled swatch, and the color setter is loaded.

By default, the colors are set for the 'up' state of the button, you can click on the 'Hover' and 'Down' tabs in the color setter to style these states.
We first style the red button by setting its text color and border and giving it a reddish gradient as the background.

If you click on the Hover tab, you will see that the colors from the up state have been loaded by default, modify the background gradient a little and hover on the preview button in the color setter to view the effects.

Similarly, modify the background gradient a little for the down state and click on the preview button to see the changes in action.

Now click the save button and the colors are applied to the swatch we had created.

We could style the body and toolbar as well, however it's not really required and any button styled using this swatch would have the correct colors.
You should however style the body and toolbar if you would be using the swatch to color non-button elements.

We similarly create a new swatch and define the colors in order to have a green button

If you wish to use a pre-existing theme, such as our very own Glossify or a theme created in the jQuery Mobile themeroller, you can use the custom css as a source for your swatch styling as well.
On the theme editor page, click the 'Use custom css' button and upload your theme css file. Existing swatches will be replaced by the swatches found in the custom css file.

Now let's apply the selected colors to our components. We can apply a swatch to a component by clicking on the theme selector button in the editor and selecting a swatch
The theme selector by default shows the selected swatch as '#' to denote that the default will be used.

Adding attributes

Before we start adding code for the actual functionality, we need to give some of our controls certain attributes so that we can then identify these components in our code. The simplest way to do this would be to identify these components using either an id or a class.

Let's start with the index page, we need some way to identify the list and the 'Add' button in our code, only then can we modify the list items or specify functionality for the 'Add' button. Click on the 'Add' button in the editor center panel, and enter 'add' in the 'id' field.

Similarly give the list an id of 'task_list'.

You are free to use any id for a component as long as it's unique, class names can be anything you want and do not even need to be unique.

On the 'Confirm' page, we need to add functionality to the 'Done' and 'Not Done' buttons, here however the functionality for both is the same, i.e. to remove the item from the list, so we need not have separate ids for both, we can instead give them both the same class name 'remove_task'

So this is our end design all mocked up.

If all you require is the design of the app, you can click on the 'Export' button to get the css and html files for our mockup.

Javascript

Now that we have a basic design ready, switch to the Code tab so that we can add the javascript to actually manage the task list. We can store our task list as a Javascript array and we just need functions to add or remove from the list and to refresh the list on the page.

var ntd = {};
/** Read the new task and add it to the list */
ntd.add = function(event) {
    // Read the task from the input
    var task=$('input').val();
    if (task) {
        // Add the task to array and refresh list
        ntd.list[ntd.list.length] = task;
        ntd.refresh_list();
        // Clear the input
        $('input').val('');
    }
    event.preventDefault();
};
/** Remove the task which was marked as selected */
ntd.remove = function() {
    // Remove from array and refresh list
    ntd.list.splice(ntd.selected,1);
    ntd.refresh_list();
};
/** Recreate the entire list from the available list of tasks */
ntd.refresh_list = function() {
    var $tasks = $('#task_list'), i;
    // Clear the existing task list
    $tasks.empty();
    if (ntd.list.length) {
        // Add the header
        $tasks.append('<li data-role="list-divider">Not To Do&#39;s</li>');
        for (var i=0;i<ntd.list.length;i++){
            // Append each task
            var li = '<li><a data-rel="dialog" data-task="' + i
                    + '" href="#confirm">' + ntd.list[i] + '</a></li>'
            $tasks.append(li);
        }
    }
    // Add the header for addition of new tasks
    $tasks.append('<li data-role="list-divider">Add a task</li>');
    // Use jQuery Mobile's listview method to refresh
    $tasks.listview('refresh');
};

Notice how we've modified the list items to include a data-rel="dialog" attribute when the tasks are appended, this will load our confirm page as a dialog instead of the default transition.

The code for refreshing the list is written such that it can generate a list similar to the one in the mockup, using a Javascript array of tasks.
It's better to bind functionality specific to a particular page, in it's own pageinit event. That way it would be easier to manage the code if you were to split your pages across multiple files.

// Initialize the index page
$(document).delegate('#index','pageinit', function() {
    // Initialize the not to do list to an empty list
    ntd.list = [];
    $('#add').bind('vclick', ntd.add);
    $('li a').live('vclick', function() {
        ntd.selected = $(this).data('task');
    });
    // Refresh the list everytime the page is reloaded
    $('#index').bind('pagebeforeshow', ntd.refresh_list);
});

// Bind the 'Done' and 'Not Done' buttons to task removal
$(document).delegate('#confirm', 'pageinit', function(){
    $('.remove_task').bind('vclick', ntd.remove);
});

// Make the transition in reverse for the buttons on the done and notdone pages
$(document).delegate('#done, #notdone', 'pageinit', function(){
    // We reverse transition for any button linking to index page
    $('[href="#index"]').attr('data-direction','reverse');
})

Integrate with HTML5 local storage

Our app so far would be able to create and maintain a task list, but all tasks would be lost if the page was reloaded.
We want to be able to save the task list, so that it can be used multiple times.
Let's use the browser's localStorage object to store and maintain the task list.

The localStorage object basically acts like a key value store for strings.
We need to store our array as a string for which we can use the JSON object to convert the array into a JSON string and vice versa. Please note that in order to support older browsers not having the JSON object, you will probably need to provide it yourself, which can easily be done using json2.js by Douglas Crockford

Firstly we need to initialize the list in localStorage or from localStorage. We can do this by replacing the

// Initialize the not to do list to an empty list
ntd.list = [];
at the start of the pageinit event of the index page with

// If no list is already present, initialize it
if (!localStorage.ntd_list) {
    localStorage.ntd_list = "[]";
}
// Load the list by parsing the JSON from localStorage
ntd.list = JSON.parse(localStorage.ntd_list);

And we need code to save back the list to localStorage when modified, so we just add the following line to our ntd.refresh function as it is being called anytime the list is modified.

// Store back the list
localStorage.ntd_list = JSON.stringify(ntd.list || []);

If you're going to be creating multiple projects on Mobjectify, it's best to namespace data that you store into localStorage, which we've done here by using ntd_ in front of our list variable name.
This is because localStorage will be shared by all your projects and you might end up overwriting data meant for different projects unless it is namespaced in some manner.

That's it, click on the generate button to test your app in the device view, or if you've logged in to your account, click on 'Test' to run your app in a new browser tab.
Click here to view the fully functional Not to Do App.

Want to customize the look of your app beyond the functionality offered by Mobjectify? Check out our tutorial on how to Supercharge your jQuery Mobile theme

 

comments powered by Disqus