andyMatthews.net

Adding iPhone style swipe to delete button to a listview component in jQuery Mobile

Update: I've released a jQuery plugin called swipeButton which you can simply drop into your project.

While developing the mobile website over at Goba.mobi this week I decided that I wanted to add a little flair and drop in a "swipe" menu allowing users quick access to actions that they would normally have to view the details page to use. Luckily jQuery Mobile makes it easy...so with just a little CSS, a little JavaScript, and some built-in events I made it happen; in just one day. Here's how I did it.

If you'd like to see this code in action, check out the demo. The original concept was to allow a user to cancel an event that they had created. The appearance would be similar to the iPhone's standard swipe to show a cancel button action pictured here.

Here's the listview code, note that the button itself isn't hardcoded. Because the swipe action isn't something that older devices can recreate I felt safe in making this a pure JavaScript/CSS solution.

I'm tying into jQuery Mobile's pageshow event. This fires when each new page is loaded, and ready to display. Because I'm only adding this behavior to certain pages in my app, I'm also going to check the target id. This id is found at the root of every jQuery Mobile page. In the example above, the id is "swipedelete". The code below is commented, but I'll point out a few things of note. It might seem like a duplicate, but $('.aDeleteBtn').remove(); should actually be in there twice. Once when this "page" gets focus, and again, when someone swipes to the right.

$(function(){
$('div').live('pageshow',function(event,ui){
if ( event.target.id.indexOf('swipedelete') >= 0) {
// remove any existing swipe areas
$('.aDeleteBtn').remove();
// add swipe event to the list item
$('ul li').bind('swiperight', function(e){
// reference the just swiped list item
var $li = $(this);
// remove all buttons first
$('.aDeleteBtn').remove();
// create buttons and div container
var $deleteBtn = $('<a>Delete</a>').attr({
'class': 'aDeleteBtn ui-btn-up-r',
'href': 'some/link/page.html?nID=' + $li.data('nid')
});
// insert swipe div into list item
$li.prepend($deleteBtn);
});
}
}
};

The final piece we need is the CSS. jQuery Mobile makes great use of themes, but they don't have a red theme yet. So I modified one of their built in themes to allow for the red "delete" button we're looking for.

.aDeleteBtn {
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
float: right;
height: 15px;
line-height: 15px;
margin: 3px 10px 0 0;
padding: 0.6em;
position: absolute;
right: 0;
top: 0;
z-index: 10;
}
/* red color buttons */
.ui-btn-up-r { border: 1px solid #953403; background: #2567ab; font-weight: bold; color: #fff; cursor: pointer; text-shadow: 0 -1px 1px #953403; text-decoration: none; background-image: -moz-linear-gradient(top, #ec4a0b, #ad390c); background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, #ec4a0b),color-stop(1, #ad390c)); -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#ec4a0b', EndColorStr='#ad390c')"; }
.ui-btn-up-r a.ui-link-inherit { color: #fff; }
.ui-btn-hover-r { border: 1px solid #953403; background: #f15c22; font-weight: bold; color: #fff; text-shadow: 0 -1px 1px #014D68; background-image: -moz-linear-gradient(top, #f15c22, #f15c22); text-decoration: none; background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, #f15c22),color-stop(1, #f15c22)); -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#f15c22', EndColorStr='#f15c22')"; }
.ui-btn-hover-r a.ui-link-inherit { color: #fff; }
.ui-btn-down-r { border: 1px solid #225377; background: #79ae21; font-weight: bold; color: #fff; text-shadow: 0 -1px 1px #225377; background-image: -moz-linear-gradient(top, #bc770f, #e6590c); background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, #bc770f),color-stop(1, #e6590c)); -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#bc770f', EndColorStr='#e6590c')"; }
.ui-btn-down-r a.ui-link-inherit { color: #fff; }
.ui-btn-up-r, .ui-btn-hover-r, .ui-btn-down-r { font-family: Helvetica, Arial, sans-serif; }

I'll be writing a tutorial on theming jQuery Mobile in the coming weeks, but for now you just need a few tidbits. jQuery Mobile is built around single letter themes. Currently they run from a-e. Every class in the jQM repertoire is built around the .ui prefix. Everything else spreads out from there. To add, or change the theme on any element, simply add the appropriate class, and change the letter on the end until it looks like you want. If it doesn't then check back for my theming tutorial to get it looking spot on!

I hope that this swipe to delete tutorial helps you out. Remember that you can take a look at the finished product if you like. In the next few days I'll be writing a second part to this article showing you how to create an entire "swipe menu" like one found in Twitter for iPhone.