A few weeks back I posted a simple jQuery Mobile demo that demonstrated paged search results. The idea was simple - present an input field to the user to search against a database of art and allow for paged results. Be sure to review that entry on the particulars. I thought it would be interesting to look into a cooler way of paging through the results - using swipe gestures.
Swipe gestures are simply the act of dragging your finger across the mobile device. jQuery Mobile supports listening in to both a left and right swipe event. I thought it would be cool to use a right swipe to move forward and a left swipe to go back. In theory - this should be simple. I've got navigation links already. If I listen in to my swipeleft/swiperight events I can fetch the URL and then perform the load myself. I thought it would be easy, but my first attempt failed. Let's look at what I did and then I'll explain why it failed.
$('#searchPage').live('swipeleft swiperight',function(event){
console.log(event.type);
if (event.type == "swipeleft") {
var prev = $("#prevlink");
if (prev.length) {
var prevurl = $(prev).attr("href");
console.log(prevurl);
}
}
if (event.type == "swiperight") {
var next = $("#nextlink");
if (next.length) {
var nexturl = $(next).attr("href");
console.log(nexturl);
}
}
});
});
$(document).ready(function() {
I began by creating a listener for swipeleft and swiperight. The event details will tell me which one was called and since the logic is very similar for both it made sense to just use one handler. I'm listening in on "searhPage", which if you look at the previous entry, is the page that displayed search results. I had not included an ID on that page so I simply added it to this version:
<div id="searchPage" data-role="page" data-theme="e">
Now we branch out based on the swipe action. I use a selector to get either the previous or next link. These links were used for buttons and contain the URL we need for the relevant page to load. Now it's possible that you may try to swipe left on the first page of results. I check the length of the selector result to see if we actually have something before I try to get the URL. Finally, I log the URL to see if it works.
Here is where things got odd. I began to test this and noticed that my links were all based on the first match. What I mean is, when I would do a swipe right, I'd always get the link for page 2, no matter what page I was on. When I would swipe left, I'd first get nothing (if I was on page one), but then I'd get the link for page 1 if I was on page 2 or any other page. It's like jQuery was caching the result of the selector and not refetching it on a swipe. Then I realized my problem.
As you navigate from page to page, jQuery Mobile will make an XHR request to load the page. But - notice the previous code block had an ID of searchPage. I was - basically - loading pages into my DOM that had the same ID. If I understand things right, I was basically making multiple pages with the same ID. On a whim I made a quick change. First - I made my page use a unique ID based on the starting position of the results. I then added a static class.
<div id="search#url.start#" data-role="page" data-theme="e" class="searchPage">
I then modified my event handler to listen in to the class, not the ID:
$('.searchPage').live('swipeleft swiperight',function(event){
This seemed to work well, but then I had a problem with my selectors. I could now possibly have multiple prevLink and nextLink items in my DOM. I remembered that jQuery let's you look for something inside another item. I also remembered jQuery Mobile provides a pointer to the current page. I tried this modification:
var prev = $("#prevlink",$.mobile.activePage);
And it worked! Here is the complete JavaScript block. Notice too I also actually added the navigation part as well:
<script>
$(document).ready(function() { $('.searchPage').live('swipeleft swiperight',function(event){
console.log(event.type);
if (event.type == "swipeleft") {
var prev = $("#prevlink",$.mobile.activePage);
if (prev.length) {
var prevurl = $(prev).attr("href");
console.log(prevurl);
$.mobile.changePage(prevurl);
}
}
if (event.type == "swiperight") {
var next = $("#nextlink",$.mobile.activePage);
if (next.length) {
var nexturl = $(next).attr("href");
console.log(nexturl);
$.mobile.changePage(nexturl);
}
}
event.preventDefault();
});
});
</script>
You can test this yourself below. Any comments?
Archived Comments
Nice. The swipe events are the wrong way round though; if you're swiping to the next page in abook you start from the right, therefore you trigger a swipeleft event and vice versa.
You can also specify a transition direction so when you go to a previous page (swiperight, heh) the transition would "follow" the motion.
Yep - you are right. That would make more sense. Trivial enough to change though. :)
Doesn't work :(
Can you explain how it isn't working for you?
Doesnt work for me either.
I sended link from chrome to phone (htc legend 2.2)
i inserted something in the search , i press submit the search key.it say no results.I then try to swipe to the right (go back) nothing happen.So i try swipe left, nothing happen.
Well, the swipe isn't meant to work when no results are found. Try searching for "e", it should return a lot of results that include pagination.
Worked great, thanks!
Thanks so much for posting this tutorial - it helps me understand the touch actions much better now.
One thing though.. your demo has a user interface flaw.. You have the "swipe left" go to previous screens where as the nature of the swipe to the left is to move forward. I think this is what is confusion people about your demo as well because I couldn't get it to work either.
also, your buttons to click to go to the post content somewhat interfere and sometimes get clicked accidentally while swiping.
just some thoughts.
Yeah, a few people commented on that. Perfect example of where my logical mind incorrectly merged with the analog world. ;)
OOPS.. shoudl have read the comments before posting one. It's ok though.. you developer types get a buy on all of that kind of stuff!!!
Heh, you should see the animation I just created in Adobe Edge. It was.... epic in it's badness.
Ohh I also meant to ask..
Can you post a simplified version of your html markup? I am trying to create a mobile version of my photography website and would like to have my galleries swipe-able but need to learn more about how you did it structurally.
It would be best to check the jQuery Mobile docs for that - or you can download my presentation (from the presentations tab), but the JQM docs are best. They did an excellent job at making it simple to work with.
swipe doesn't work for me either - iphone4 safari.
search worked, click works, swipe doesn't.
I'll check tomorrow. I've got an iPad2 now so it's easier to test.
I just tested on my iPad2 and it worked. Don't forget I made the mistake of doing it backwards. Search for "e", and swipe from left to right to advance to the next page.
Didn't work for me on iPod touch
What version of ios? Unfortunately, with no iPod Touch to test against, I can't help much. Check the support matrix here:
http://jquerymobile.com/gbs/
iPod Touch is not called out, although it should be considered the same as the iPhone probably.
Are the swipe gestures supposed to work on Android phones? I can get them to side between the data-role pages when using the button, but, the actual swipe gestures don't seem to work? Do I need to add actual jquery scripts? Thanks and by the way, I really appreciate your help...
Not quite sure what you mean by "Do I need to add actual jquery scripts" - you definitely need to include jQuery for anything in JQM to work. If your site is online, I can take a look.
Here is a link to a test page I set up following your easy to understand code, it works with the links, but dose not "swipe" with fingers with android phone?
http://www.backseatbettys.c...
If I can get it functioning properly I have some stuff I would like to add it to. Here is a link to how I have been doing nearly the same thing, but this also only works with the links, but, it does worl on regular PCs as well. It just slides html content set up as php includes:
http://www.socialdealer.com...
Again, thanks for any input you may have....
You didn't write the code though. As my blog entry explains above, you have to actually write event handlers for it.
Also - you want to upgrade to the latest jqm.
ios 4.3.1 iphone 4.
searched for "e", only two results. can't test pagination on that I guess.
Searched for "A", have quite a few results. But, no swiping happening :(
Oh there we go, I searched for "P" and lots of results were returned and was able to swipe.
Spamming your comment section. Going to try and implement it now. It is very sensitive though. Lots of accidental clicks going on. Still, good place to start.
Opened on an iPhone and while searching for "e" it gets looped on loading ;( and doesn't work.
Just tested on my iPad2 and it worked. Maybe refresh try again?
Went on the site the second time and works now. Weird. It may be, because I entered some garbled text the first time ("hgdh"), but I did try refreshing and then the same was happening for "e" and "a" (continues loop). May be something with iPhone cache though, anyway.
Swipe gesture sure is nice! :) Thanks, that demo helped a lot!
As a reminder, don't forget I screwed up the directions here (I mean swipe directions). When you take this code and put it into your million dollar idea, swap em - and then send me a check. ;)
Hi! there is posible to make this effect with touching page??
If you make a movement with your finger right to left go to the next page, but if you move left to right go back.
Anybody can help about this?
Gracias! ;)
I'm sorry - what you describe _is_ a swipe, is it not?
Yes!! I implemented in my RSS feed APP (like your tutorial about this), but I have a problem when I'm in the first entry detail I try to swipe to the next entry detail but I can't
Well, I'd need more info on why it is failing. If this is online where I can see, let me know.
I solved the problem.
I added:
$("#PageDetail).live("pageshow swipeleft swiperight"(function(e) {
...
And this I can see if event type is swipeleft and go to the next entry with some more code that I develop :)
This example is exactly what I needed. I have not implemented it in my site yet, but it seems straight forward enough. If not I'll bug you with a few questions.
I inserted your swipe function into my site, and I am getting a weird error. It says l.data("page") is undefined in code.jquery.com/jquery-1.5..... I have a ref to this script library included in my HTML, and am not sure why it does not read the particular var. Any help would be greatly appreciated.
Is it online where we can see?
Sorry for the long URL
http://kcpaintersworld.com/...
Interesting. I note you aren't using jQuery Mobile UI items, like pages. If you modify your container div to have data-role="page", does it work?
Hi again Raymond,
Nice example you have put together here, very helpful. For the time being I have just simplified it quite a bit to:
$("body").bind("swipeleft", function(e) {
$.mobile.changePage( '#nextPage, { transition: "slide" });
My issue is that I am using the multi page site template structure (putting all pages into one HTML file) and it will not work. Is there a workaround for this or would I have to abandon multi page?
Um... I don't know. That's weird - cuz afaik - whether you put the pages in one HTML or multiple, it should plain work. (Of course, you have a typo in your code above but I assume it was an accident when you typed.) Is the event not firing? Ie, can you add a console.log before the changePage?
Maybe it was the typo Ray, I have had a few of those obvious comma,semicolon,brackets issues today. I found a solution here at stackoverlow that did a good job.
I also wanted to be selective about which pages in the stack that I wanted to allow swipe gestures on. Link to stackoverflow is below:
http://stackoverflow.com/qu...