Creating a Mobile Version for Your Single Page Backbone.js App using jQuery Mobile

SupportBee, our Customer Service Software is a single page app powered by Backbone.js and Bootstrap CSS framework. Even though bootstrap offers responsive layouts out of the box, they work well only for simple sites (like our marketing site) and not for web applications. Also, there are many desktop features that don’t make sense on mobiles (for example keyboard shortcuts) and need to be disabled. Mobile apps also add some unique requirements - Buttons and links need to changed to be usable and screen transitions need to look smooth and pleasing. You can write a lot of custom CSS and javascript to solve these problems but instead of re-inventing the wheel, we decided to use jQuery Mobile.

This blog post talks about some of the challenges we faced and solutions we found/came up with. The first challenge was making Backbone.js, Bootstrap and jQuery Mobile play well with each other.

Making jQuery Mobile, Backbone & Bootstrap play well

In our desktop app, we use backbone.js for organizing our code (Models, Views, Collections) and also for routing. Bootstrap is used for styling. When you throw jQuery Mobile into the mix, it affects both the functionality (routing for example) and styling (forms, buttons etc). To get all the three to work together, you need to configure some options in jQuery Mobile. You can find the details on the configuration options here.

Fastclick for more responsive clicks

Out of the box, mobile browsers introduce a 300ms delay to detect double taps etc. Most applications don’t care about double taps and a 300ms delay is pretty unacceptable. To avoid this, checkout Fastclick.js, a library from Financial Times that can fix this for you. It is very simple to use and works out of the box with just a couple of lines of javascript code. What’s more, it handles dynamically added elements very easily.

$.mobile.changePage is Your Friend

If you have routes (basically you have many screens) in your backbone.js application, you need to use changePage to actually change the content on the screen. changePage will take a jQuery object and show it on the screen (with an animation if you specify one). You can pass it options to disable hashchanges etc. If you are using animations, you need to make sure you pick the right direction etc. We use a small utility method for this as shown in the gist below

Rendering Dynamically Generated Content

When you load a static jQuery Mobile page, the library enhances your markup (based on data-role etc) and makes your page mobile friendly. However when you are inserting dynamically generated content, you need to manually trigger the create method on new markup. See the ‘Enhancing New Markup’ section on this page. The trick is to trigger this after the changePage call is finished (so the view is visible and attached to the dom) and the best way to achieve this is to handle the pagechange event. The code looks like this

Backbone Helpers To Render Mobile/Desktop Specific Code

As we talked before, there are many features that you don’t want on Mobiles. For example, we switch off keyboard shortcuts on mobile phones. To selectively run code on desktop/mobile (and later tablets), you can create a helper like this

You can detect browser (mobile/desktop) in javascript but we setup some variables during the initial page load server side using the Mobile Fu gem and create some javascript helpers that check these variables (SB.Utils.isMobile function).

Another technique that we use is to define tagName as a function in the Backbone view. You need to be on Backbone.js 0.9.0 or above to be able to use this feature. This allows you to render a different tag for mobiles and desktops. For example, we use a table for listings in the desktop view and a list in the mobile view. So we use a tr for ticket summary view on the desktop and an li on the mobile. The code looks like this

Mobile Specific Templates

Although Boostrap provides responsive grids and CSS helpers, they work well on mobiles only for the simplest of layouts. For SupportBee, we needed to render mobile specific templates for many screens and wrote a helper to make it easy

This helper checks for a _mobile template and renders that in the mobile view. If the mobile template is not present, it renders the desktop template. SB.Views.Templates is an object created by Jammit that contains compiled handlebars templates.

Testing Locally on Phone Without Going Nuts

If you are testing a simple application, you can access it using the IP address of your local dev laptop on the network. However we need to be able to test with subdomain and found the neat xip.io hack very handy. Basically if you local server has the IP address of 192.169.1.10, test.192.168.1.10.xip.io would point to your local machine and also preserve the subdomain (you still have to be on the same network). More information here.

SimpleDialog2, Notify and Other Useful Plugins

We tried using jQuery Moblie Dialog but ran into an issue where it would always throw you one page back when closing the dialog. Someone else also reported it on Stack Overflow. After a day of unsuccessful debugging, we tried SimpleDialog2 and it worked like a charm. We also ended up using Notify for mobile friendly success/error/info notifications. We also experimented a bit with iScrollView Plugin but kept running into some strange issue or the other.

We hope this post can help you in creating a mobile version for your single page app. If you have any comments or questions, we would love to hear them. If you are interested in writing code like this, we are hiring an intern. We are very comfortable working remotely so you don’t have to relocate anywhere. Write to us!



blog comments powered by Disqus
Hana Mohan
Hana Mohan