The idea behind Weheartplaces is that I want to be able to bookmark places to go on my desktop computer, and then sync these places to my mobile so I can access them offline.
I’ve created a json API to weheartplaces, here are my bookmarks in json format. I’m loading these bookmarks using backbone.js and then displaying them using jquery mobile. Here’s a little breakdown of how I’m doing it:
List view
Create a list view like this:
<ul data-role="listview" data-inset="true" data-theme="c" data-dividertheme="b">
</ul>
This is automatically converted into a nice looking list view by jquery mobile. You then iterate over all the elements in your Backbone collection to add them to the list:
for bookmark in Bookmarks.models
a = $("<a />")
a.text(bookmark.get('place').name)
a.attr 'href', "#bookmarks-#{bookmark.cid}"
a.wrap("<li />").parent().appendTo(ul)
Notice the url that each bookmark points to - #bookmarks-12345. I use backbone routes to recognize this URL and display the correct content.
Combining the jquery and backbone routers
When you click a link - jquery mobile intercepts the click and looks for a div with the same name as the anchor fragment of the url you just clicked on. So for example:
<a href="#home">Home</a>
Will cause jquery to show this div:
<div id="home">some content...</div>
The problem is that in my list view, I’m linking to pages that don’t exist yet - so I have to add some code to the jquery mobile routing code to create and show an empty div.
// This code goes in $.mobile.changePage...
if( url ){
to = $( "[id='" + url + "']" ),
fileUrl = getFileURL(url);
if(to.length == 0){ // Page could not be found
console.log("Routing to " + url + "...");
to = $("<div data-role='page' id='" + url + "'><div data-role='header'><h1> </h1></div><div data-role='content'><img src='images/ajax-loader.png' /></div></div>").appendTo('body')
enhancePage();
}
}
Jquery will display this page, and change the anchor fragment of the current URL. Backbone detects the URL change by watching for a hashchange
event, and will then call your matching route - in my case:
class HomeController extends Backbone.Controller
routes :
"home" : "home"
"bookmarks-:cid" : "show"
Showing the bookmark
Once that magic has happened, the show method on the HomeController will be called:
show: (cid) ->
new ShowBookmarkView { model : Bookmarks.getByCid(cid) }
This creates a new ShowBookmarkView, and that view generates the HTML (using underscore.js templates) that is inserted into the currently active page.
$(".ui-page-active").html(@template({bookmark : @model}))
If I get time I will put a small demo file up on github to show how all this hangs together - but feel free to post questions below.