Last week I finally got to play with jQTouch, a jQuery based framework for building mobile-ready web sites. It was... rough to say the least. I'm very happy with the final result, but it took a bit of work to figure out how jQTouch wanted to work and what I should be doing with it. What follows are some basic notes, discoveries, and tips. I warn you though - most likely some of what follows could be a misunderstanding on my part.

  1. First and foremost, jQTouch is really meant for web applications that are menu driven. When designing your application, you want to think in terms of menus and sections. Your primary UI will be menus and forms.

  1. jQTouch works by convention. By using a button with a certain class, you build a back button. By using a link, you implicitly create an Ajax request. None of this was very clear to me at all.

  1. The demos, for the most part, work around the idea of one file. The file contains all the menus and "pages" for the application. I don't think this is very realistic. A simple application can do this, but anything dynamic and of intermediate complexity will want separate files.

  1. Given the above, here is a very basic, but complete template.

<html> <head> <script src="js/jquery.js"></script> <script src="js/jqtouch.min.js" type="application/x-javascript" charset="utf-8"></script> <style type="text/css" media="screen">@import "css/jqtouch.min.css";</style> <style type="text/css" media="screen">@import "themes/jqt/theme.min.css";</style>

<script> $.jQTouch({ icon: 'jqtouch.png', statusBar: 'black-translucent' }); </script> </head>

<body>

<div id="home"> <div class="toolbar"><h1>Your App</h1></div>

<ul class="rounded"> <li class="arrow"><a href="#about">About</a></li> <li class="arrow"><a href="#unicorn">Unicorn</a></li> </ul> </div>

<div id="about">

<div class="toolbar"> <h1>About</h1> <a class="button cancel" href="#">Return</a> </div>

<p> Hello World </p>

</div>

<div id="unicorn">

<div class="toolbar"> <h1>Unicorn</h1> <a class="button cancel" href="#">Return</a> </div>

<p> Hello, Unicorns </p>

</div>

</body> </html>

From top to bottom, here is what you need:

  • Need to load jQuery and the jQTouch JS library.
  • Need to load the JQTouch CSS, and one theme file. jQTouch ships with two themes.
  • You need to startup jQTouch. There are many initialization options (detailed here).
  • Now for the important part. Your "home" DIV is your home page. It consists of a toolbar and a set of links. Those classes are recognized by jQTouch and help generate the UI. Notice the links! They are both anchor links. This means they are expected to be within the file itself.
  • Scrolling down, you see two blocks that match up with the anchor links above. Once again each one has a toolbar.

That's basically it for a simple app. Here is a screen shot of the home page:

And here is a shot of one of the "pages":

Because of the CSS conventions we used, that's all you have to do. Clicking the menu link loads the page. Clicking Return brings you back home. It just plain works.

  1. So hey, notice how that page doesn't render terribly nicely? The toolbar is fine, but the actual page content ain't so hot. This is something that really bugged me. All of the demos focused on menus and forms, but never showed "simple" content in a nice display. I asked about this on the Google Group (by the way, another big tip is to use the jQTouch Google Group) and the suggestion was to add CSS. I'm kinda surprised this doesn't exist already. Here is the CSS I added for my application.

<style> .body { -webkit-border-radius: 8px; -webkit-box-shadow: rgba(0,0,0,.3) 1px 1px 3px; padding: 10px 10px 10px 10px; margin:10px; background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#4c4d4e), to(#404142)); word-wrap:break-word; }

.body a { color: white; }

.body p { margin-bottom: 10px; } </style>

I then wrapped the paragraphs in my 2 "pages" with the div class="body" tags. The result is a better looking page (imho):

  1. So, I mentioned earlier that by default, jQTouch expects your pages to be in the same page. I don't think that makes much sense for a dynamic application. Luckily it's easy enough to work around. Any link that is not an anchor link is automatically converted to an AJAX get request. Let's add a link to our menu:

<ul class="rounded"> <li class="arrow"><a href="#about">About</a></li> <li class="arrow"><a href="#unicorn">Unicorn</a></li> <li class="arrow"><a href="cylon.html">Cylon</a></li> </ul>

Next we add a cylon.html file. Remember this is loaded via Ajax. Therefore, we just need our toolbar and body divs.

<div id="about">

<div class="toolbar"> <h1>Cylons</h1> <a class="button cancel" href="#">Return</a> </div>

<div class="body"> <p> Remember the basic rule. If the person is ugly, they can't be a Cylon in disguise. </p> </div>

</div>

  1. Ok, so what if you don't want to use AJAX for the request? For example, I had a logout link and I needed it to reload the entire page. This blog entry by Tim Golen describes all the way links work. If you don't feel like clicking the link, just add rel="external" to your links.

  1. So the fact that AJAX is used to load stuff brought up two interesting problems for me. The first problem was authentication. My application has a login screen and I present the jQTouch UI after you logged in. I did this with a simple location() call in onRequestStart. This breaks when the AJAX request calls a page and you've logged off. I don't have my solution yet - but what I'm going to do is detect the AJAX request (which is super easy) and output something jQTouch can pick up on. Speaking of that...

  2. The second issue I had was trying to do crap when the page loaded. I built my pages with the assumption that I could just use $(document).ready. This kinda worked. Well, no, not really. Most likely it was something I did wrong. jQTouch provides a set of events that you can listen to for your application. The event you want to use is pageAnimationEnd. The example in their docs though assume a one page app and makes use of bind. I had to make use of live instead. Here is an example:

$('#somepage').live('pageAnimationEnd', function(event, info){ if (info.direction == 'in') {

In this example, somepage is the ID of the main div around the page. info.direction will either be in or out. I used "in" as a way of handling the page load and "out" as a way of handling the page ending. This was pretty useful for me as the page in question needed a JavaScript interval. So I started it up when the page loaded and killed it when the page ended.

That's all I have for now. I linked to the Google Group above (but here it is again) - I'll also point out the Wiki: http://code.google.com/p/jqtouch/w/list. It is a bit more fleshed out then I remember it from last time. I've pasted a zip of my simple demo above. It should work fine anywhere. For my testing I use Safari shrunk as small as possible. I've also tested my application on both my Nexus One and an iPod Touch, and in both it looks fantastic. So despide the "roughness" of the framework for me, I definitely think it's pretty darn cool! I hope these tips help, and if anyone wants to add some additional tips, be my guest.

Download attached file.