iPhone apps have a number of distinctive animation characteristics that add context and meaning for the user. For example, pages slide left as you drill down through links, and slide right as you navigate back. In this chapter, you’ll learn how to add characteristic behaviors like sliding, page flip, and more to your web app. These changes, in combination with Ajax and full screen mode, will make your web app almost indistinguishable from a native application.
I’ll be honest: making a web page animate like a typical native iPhone app is hard. Fortunately, an enterprising young lad from Philly named David Kaneda has written a JavaScript library called jQTouch that makes mobile web development a whole lot easier. jQTouch is an open source jQuery plug-in that handles virtually everything we learned in the previous chapter, as well as a boatload of much more complex stuff that would be truly painful to write from scratch.
You can download the latest version of jQTouch from http://jqtouch.com/.
We are going to build a simple calorie-tracking application called Kilo that allows the user to add and delete food entries for a given date. All told, there will be five panels: Home, Settings, Dates, Date, and New Entry. We’ll start off with two panels and work our way up as we go.
I’ll be assigning CSS classes to some of the HTML elements (toolbar
,
edgetoedge
, arrow
, button
,
back
, etc.). In every case, these classes correspond to
predefined CSS class selectors that exist in the default jQTouch
theme. Bear in mind that you can create and use your own classes by
modifying existing jQTouch themes or building your own from scratch; I’m just using the
defaults.
To begin, let’s create a file named index.html and add the HTML shown in Example 4-1 for the Home and About panels.
<html> <head> <title>Kilo</title> </head> <body> <div id="home"> <div class="toolbar"> <h1>Kilo</h1> </div> <ul class="edgetoedge"> <li class="arrow"><a href="#about">About</a></li> </ul> </div> <div id="about"> <div class="toolbar"> <h1>About</h1> <a class="button back" href="#">Back</a> </div> <div> <p>Kilo gives you easy access to your food diary.</p> </div> </div> </body> </html>
The HTML here basically amounts to a head
with a title, and a body with two children, both
div
s:
This div
(as well as the
about
div
that appears a few lines down)
will become a panel in the application by virtue of the fact that it
is a direct descendant of the body.
Inside each panel div
, there
is a div
with a class of toolbar
. This
toolbar
class is specifically predefined in the jQTouch
themes to style an element like a traditional iPhone toolbar.
This unordered list tag has the class
edgetoedge
. The edgetoedge
class tells
jQTouch to stretch the list all the way from left to right in the
viewable area.
On this line there is an li
that contains a link with its href
pointing at the About panel.
Including the arrow
class to the li
is
optional; doing so will add a chevron to the right side of the item
in the list.
The toolbar elements each contain a
single h1
element that will become the panel title. On
this line, there is a link with the classes button
and
back
, which tell jQTouch to make the button look and
act like a back button.
Note that the href
on the back button is set to #
. Normally, this would tell the
browser to return to the top of the current document. But when using
jQTouch, it navigates back to the previous panel instead. In more
advanced scenarios, you might want to use a specific anchor, such as
#home
, which would instruct the back button to navigate
to a particular panel regardless of what the previous panel
was.
With the basic HTML in place, it’s time to add jQTouch to the party. Once you’ve downloaded jQTouch and unzipped it in the same directory as the HTML document, you just add a few lines of code to the head of your page (Example 4-2).
For this and other examples in this book, you will need to download jQTouch from http://jqtouch.com, unzip it, and move the jqtouch and themes directories into the same directory as your HTML document. You will also need to go into the jqtouch directory and rename the jQuery JavaScript file (such as jquery.1.3.2.min.js) to jquery.js.
<link type="text/css" rel="stylesheet" media="screen" href="jqtouch/jqtouch.css"> <link type="text/css" rel="stylesheet" media="screen" href="themes/jqt/theme.css"> <script type="text/javascript" src="jqtouch/jquery.js"></script> <script type="text/javascript" src="jqtouch/jqtouch.js"></script> <script type="text/javascript"> var jQT = $.jQTouch({ icon: 'kilo.png', statusBar: 'black' }); </script>
I’m including the jqtouch.css file. This file defines some hardcore structural design rules that are very specific to handling animations, orientation, and other iPhone-specific minutiae. This file is required and there should be no reason for you to edit it.
I’m including the CSS for my selected theme, in this case, the “jqt” theme, which comes with jQTouch. The classes that I’ve been using in the HTML correspond to CSS selectors in this document. jQTouch comes with two themes available by default. You can also make your own by duplicating a default theme and making changes to it, or writing a new one from scratch.
jQTouch requires jQuery, so I include that here. jQTouch comes with its own copy of jQuery, but you can link to another copy if you prefer.
This is where I include jQTouch itself. Note that you have to include jQTouch after jQuery, or nothing’s going to work.
This brings us to the script block where
I initialize the jQTouch object and send in two property values:
icon
and statusBar
.
jQTouch exposes several properties that allow you to customize the behavior and appearance of your app. You’ll see several throughout the course of this book, and they are all optional. However, you’ll pretty much always be using at least a few of them.
In this case, icon
tells
jQTouch where to look for the custom Web Clip icon, and
statusBar
controls the color of the 20px strip at the
top of the app in full screen mode.
By the way, jQTouch assumes that you want
the app to run in full screen mode because, hey...that’s how you roll.
If you’d prefer to disallow full screen mode, you can add
fullScreen: false
to the property list.
The difference between the application before jQTouch (Figure 4-1) and after (Figure 4-2) is dramatic, but the truly astonishing thing is that you’ve just added gorgeous left/right sliding to your app with 10 lines of code. What’s more, you’ve also enabled full screen mode, defined a custom status bar color, and linked to your Web Clip icon. jQTouch is completely sick, and we’re just getting started.
Let’s now add the Dates panel. The Dates panel will have a
list of relative dates beginning with Today and going back to 5 days ago
(Figure 4-3). Add the HTML for the Dates panel
(shown in Example 4-3) right after the About
panel, just before the closing </body>
.
<div id="dates"> <div class="toolbar"> <h1>Dates</h1> <a class="button back" href="#">Back</a> </div> <ul class="edgetoedge"> <li class="arrow"><a id="0" href="#date">Today</a></li> <li class="arrow"><a id="1" href="#date">Yesterday</a></li> <li class="arrow"><a id="2" href="#date">2 Days Ago</a></li> <li class="arrow"><a id="3" href="#date">3 Days Ago</a></li> <li class="arrow"><a id="4" href="#date">4 Days Ago</a></li> <li class="arrow"><a id="5" href="#date">5 Days Ago</a></li> </ul> </div>
Like the About panel, the Dates panel has a
toolbar with a title and back button. After the toolbar, there is an
unordered edgetoedge
list of links. Notice that all of the
links have unique id
s (0 through 5)
but the same href
(#date
)—more on that in a bit.
Next, you have to update the Home panel with a link to the Dates panel. Add the following line to the Home panel in index.html:
<div id="home">
<div class="toolbar">
<h1>Kilo</h1>
</div>
<ul class="edgetoedge">
<li class="arrow"><a href="#dates">Dates</a></li>
<li class="arrow"><a href="#about">About</a></li>
</ul>
</div>
And just like that, we’ve added a new panel to the app (see Figure 4-4). Clicking on an item on the Dates panel doesn’t do anything yet. Let’s rectify that situation by adding the Date panel.
The Date panel looks a lot like the previous
panels, with a couple of exceptions (refer to Example 4-4). Add the HTML for the Date panel right
after the Dates panel, just before the closing
</body>
.
<div id="date"> <div class="toolbar"> <h1>Date</h1> <a class="button back" href="#">Back</a> <a class="button slideup" href="#createEntry">+</a> </div> <ul class="edgetoedge"> <li id="entryTemplate" class="entry" style="display:none"> <span class="label">Label</span> <span class="calories">000</span> <span class="delete">Delete</span> </li> </ul> </div>
The Date panel toolbar has an additional
button. When clicked, this button will display the New Entry panel
(which we have not yet built). I’ve given the link a class of
slideup
, which tells jQTouch that we want the target
panel to slide up from the bottom of the screen, rather than
horizontally like typical navigation.
The other unusual aspect of this panel is
that I’ve defined a list item with the style set to
display:none
, effectively making it invisible.
As you’ll see in a bit, I’m going to use this invisible list item as a template to display entries once they are created. At this point, there are no entries, so the panel will be empty aside from the toolbar.
Now that you’ve added the Date panel, clicking any item on the Dates panel will slide the empty Date panel (Figure 4-5) into view.
Example 4-5
shows the source code for the New Entry panel. Add this
code to the end of index.html, just
before the closing </body>
.
<div id="createEntry"> <div class="toolbar"> <h1>New Entry</h1> <a class="button cancel" href="#">Cancel</a> </div> <form method="post"> <ul> <li><input type="text" placeholder="Food" name="food" id="food" autocapitalize="off" autocorrect="off" autocomplete="off" /></li> <li><input type="text" placeholder="Calories" name="calories" id="calories" autocapitalize="off" autocorrect="off" autocomplete="off" /></li> <li><input type="submit" class="submit" name="action" value="Save Entry" /></li> </ul> </form> </div>
The first thing to point out about the New Entry panel is that instead of having a back button, it has a cancel button.
Cancel buttons in jQTouch behave just like back buttons, in that they remove the current page from view using the reverse animation of the way it came into view. However, unlike back buttons, cancel buttons are not shaped like a left arrow.
I used a cancel button for the New Entry panel because it slides up on the way in and will therefore slide down on the way out. It would be counterintuitive to click a left-pointing back button and then have the panel slide down.
This HTML form contains an unordered list
of three items: two text fields and a submit button. Embedding form
controls in an li
allows the jqt
theme to style the form as shown in
Figure 4-6.
Each of the text inputs has quite a few defined attributes:
type
Defines the form control to be a single-line text entry field.
placeholder
A string of text to display in the form input when the input is empty.
name
The name that will be associated with the value provided by the user when the form is submitted.
id
A unique identifier for the element in the context of the entire page.
autocapitalize
A Mobile Safari–specific setting that allows you to turn off the default autocapitalization feature.
autocorrect
A Mobile Safari–specific setting that allows you to turn off the default spellcheck feature.
autocomplete
Setting that allows you to turn off the autocomplete feature of Mobile Safari.
The class attribute of the submit input button needs explanation. The
iPhone will display a keyboard whenever your cursor is in a field.
The keyboard has a Go button in the bottom-right corner that submits
the form when clicked. When you are hijacking the submit function as
we are doing here, submitting from the Go button on the keyboard
does not remove the cursor from the active field, and therefore the
keyboard does not slide out of view. To remedy this,
jQTouch offers a convenience method that automatically
removes the cursor from the active field when a form is submitted.
To take advantage of this feature, you just add the
submit
class to the submit element of the form.
Figure 4-7 shows the New Entry form in action. At this point, I’ve done nothing to actually save the entry when the user clicks Save Entry. We’ll cover that in Chapter 5.
We haven’t yet created a button that will allow users to navigate to the Settings panel, so let’s add one to the toolbar on the Home panel (see Figure 4-8). All it takes is a single line of HTML, shown in bold:
<div id="home"> <div class="toolbar"> <h1>Kilo</h1> <a class="button flip" href="#settings">Settings</a> </div> <ul class="edgetoedge"> <li class="arrow"><a href="#dates">Dates</a></li> <li class="arrow"><a href="#about">About</a></li> </ul> </div>
This is the line of HTML that adds the
button. Notice that I’ve assigned the flip
class to the
link. The flip
class instructs jQTouch to transition
from the Home panel to the Settings panel by rotating the page on
its vertical axis. To add an extra dimension to the process, the
page actually zooms out a bit during the animation, similar to the
default Weather app on the iPhone. Fancy, no?
In comparison with the New Entry panel, the HTML for the Settings panel is going to look pretty familiar (Example 4-6). There is one more text input and some of the attributes have been omitted or have different values, but conceptually they are identical. Add this to your HTML document just as you’ve done for the other panels. When you’re done, the Settings panel should look like Figure 4-9.
As with the New Entry form, the Settings form does not currently save any of the information associated with it. Its submission handler will be described in the next chapter.
<div id="settings"> <div class="toolbar"> <h1>Settings</h1> <a class="button cancel" href="#">Cancel</a> </div> <form method="post"> <ul> <li><input placeholder="Age" type="text" name="age" id="age" /></li> <li><input placeholder="Weight" type="text" name="weight" id="weight" /></li> <li><input placeholder="Budget" type="text" name="budget" id="budget" /></li> <li><input type="submit" class="submit" name="action" value="Save Changes" /></li> </ul> </form> </div>
So there you have it. With fewer than 100 lines of code, we’ve created an iPhone-esque UI for a five-panel application, complete with three different page transition animations. Not too shabby, right? See Example 4-7 for a complete listing of the final HTML.
<html> <head> <title>Kilo</title> <link type="text/css" rel="stylesheet" media="screen" href="jqtouch/jqtouch.css"> <link type="text/css" rel="stylesheet" media="screen" href="themes/jqt/theme.css"> <script type="text/javascript" src="jqtouch/jquery.js"></script> <script type="text/javascript" src="jqtouch/jqtouch.js"></script> <script type="text/javascript"> var jQT = $.jQTouch({ icon: 'kilo.png', statusBar: 'black' }); </script> </head> <body> <div id="home"> <div class="toolbar"> <h1>Kilo</h1> <a class="button flip" href="#settings">Settings</a> </div> <ul class="edgetoedge"> <li class="arrow"><a href="#dates">Dates</a></li> <li class="arrow"><a href="#about">About</a></li> </ul> </div> <div id="about"> <div class="toolbar"> <h1>About</h1> <a class="button back" href="#">Back</a> </div> <div> <p>Kilo gives you easy access to your food diary.</p> </div> </div> <div id="dates"> <div class="toolbar"> <h1>Dates</h1> <a class="button back" href="#">Back</a> </div> <ul class="edgetoedge"> <li class="arrow"><a id="0" href="#date">Today</a></li> <li class="arrow"><a id="1" href="#date">Yesterday</a></li> <li class="arrow"><a id="2" href="#date">2 Days Ago</a></li> <li class="arrow"><a id="3" href="#date">3 Days Ago</a></li> <li class="arrow"><a id="4" href="#date">4 Days Ago</a></li> <li class="arrow"><a id="5" href="#date">5 Days Ago</a></li> </ul> </div> <div id="date"> <div class="toolbar"> <h1>Date</h1> <a class="button back" href="#">Back</a> <a class="button slideup" href="#createEntry">+</a> </div> <ul class="edgetoedge"> <li id="entryTemplate" class="entry" style="display:none"> <span class="label">Label</span> <span class="calories">000</span> <span class="delete">Delete</span> </li> </ul> </div> <div id="createEntry"> <div class="toolbar"> <h1>New Entry</h1> <a class="button cancel" href="#">Cancel</a> </div> <form method="post"> <ul> <li><input type="text" placeholder="Food" name="food" id="food" autocapitalize="off" autocorrect="off" autocomplete="off" /></li> <li><input type="text" placeholder="Calories" name="calories" id="calories" autocapitalize="off" autocorrect="off" autocomplete="off" /></li> <li><input type="submit" class="submit" name="action" value="Save Entry" /></li> </ul> </form> </div> <div id="settings"> <div class="toolbar"> <h1>Settings</h1> <a class="button cancel" href="#">Cancel</a> </div> <form method="post"> <ul> <li><input placeholder="Age" type="text" name="age" id="age" /></li> <li><input placeholder="Weight" type="text" name="weight" id="weight" /></li> <li><input placeholder="Budget" type="text" name="budget" id="budget" /></li> <li><input type="submit" class="submit" name="action" value="Save Changes" /></li> </ul> </form> </div> </body> </html>
jQTouch allows you to customize its default behavior by
sending a variety of property settings into the constructor. We’ve seen
this previously with icon
and statusBar
, but
there are many others that you should be aware of. See Table 4-1.
3.142.35.54