Phonegap and jQuery mobile

This weekend I’ve been playing with Phonegap and jQuery Mobile and I have to say that I am fairly impressed.

Phonegap

For those of you who do not know, Phonegap is a system that allows you to write a web app and wrap it up to make it a native app.  The benefits it provides is it completely removes the barriers to entry for someone like me who doesn’t have the time to learn another language. It is a wrapper application that exposes the native phone features (vibrate, camera, contacts etc) via JavaScript.

jQuery mobile

jQuery mobile (jQm) is a parallel project to jQuery, and uses jQuery at it’s core. It’s a plugin which provides a core set of functionality to rapidly build web apps. It gives you widgets, and consistent styling with minimal effort. The best thing is that you get a the benefits that jQuery gives you at the same time.

Building the app

There is a couple of articles out there on combining these two technologies, but they dont really go into much detail. Thats why I’m writing this, to let you know how I went about starting

Firstly download and install Phonegap. Once installed start a new project.  To get jQm working you should download it and include it into your project index. When you combine this with the jQm page structure it gives you a simple web app.

The tricky bit comes trying to get JavaScript actions to run on each page whilst still maintaining code structure, readability, etc.

Disclaimer: Whilst this method works, I am not advocating it as ‘the’ way to do a PhoneGap/jQuery mobile app.  This is a way that worked which I am comfortable with. If you know of any other then please leave a comment below.

Start off setting the index page up to contain the jQm boilerplate template, making sure that you leave the references to the PhoneGap javascript in the head.

You now have a page which runs in PhoneGap using jQuery mobile, congratulations.

What I did for all the custom code was to wrap it in a jQuery plugin. This meant that my javascript looks like this.

(function( $ ){

	var variables = {
	}

	var methods = {
		init : function( ) {
			console.log("sjy init called");
			//do any initialisation thats required
			return this;
		},
		pageTwo : function() {
			console.log("pageTwo called");
			//do what needs to be done on this page
			return this;
		}
	 };

	$.fn.sjy = function( method ) {
		//code taken from http://docs.jquery.com/Plugins/Authoring#Namespacing
		// Method calling logic
		if ( methods[method] ) {
			return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
		} else if ( typeof method === 'object' || ! method ) {
			return methods.init.apply( this, arguments );
		} else {
			console.error( 'Method ' +  method + ' does not exist.' );
		}
	};

})( jQuery );

What this code does is wrap up my code in a plugin, and does some nice namespacing. When you call the function $.sjy() it calls the init function. If you pass in parameters, the first one is used for a method name and the rest are parameters passed to that function.

eg:

$.sjy('pageTwo');

will call the function pageTwo inside my plugin.

Next is to link to a page and get it to use the plugin when the page loads. jQm does some really clever stuff with page loading that means the jQuery goto of

$(document).ready(function{
...
});

is out of the question. This is because jQm takes links and loads them in background using ajax, it then injects the content into the DOM before transitioning to it. This means that the ready function will not be called when you navigate to a new page.

This is where this piece of handy code comes in.

jQuery("div[data-role*='page']").live('pageshow', function(event, ui) {
	var thisId = $(this).attr("id") || "init";
	$(this).sjy(thisId);
});

This uses the live function which will call the closure whenever a page is show. What it does is get the id of the page about to be shown, and passes that to my plugin. All you need to do is make sure that there is a unique id for each page in your app, and that there is a corresponding function in your plugin.

Hey presto, an app that retains its readability and such, whilst still being able to develop.

Please do comment if you have any other tips and tricks that can help.

Leave a Reply