Mobile web frameworks are taking off, and developers now have a number of options for making great-looking mobile-optimized web applications with relative ease. In the past I covered jQTouch, a jQuery-based JavaScript framework (see part one and part two of my work), but ran into frustrations when trying to integrate it with the likes of Devise. Meanwhile, jQuery Mobile, from the jQuery Group themselves, has been released and shows great promise, especially if you need to get a mobile version up and running within an existing application.
To start, I recommend reading through Jarod Santo’s excellent introduction to using jQuery Mobile with Rails 3. It goes through the steps of integrating the mobile framework into a standard CRUD scaffold. However, to make your app both mobile and desktop-savvy, you’ll probably want to do some browser detection like that covered in the Railscasts episode on mobile web apps. Depending on the mobile devices you want to support (jQuery Mobile should eventually support most mobile platforms) you may need to change the regular expression Ryan uses to detect mobile browsers.
Just for clarification: You’ll need to bounce back and forth between the two tutorials, especially if you’re still getting comfortable with Rails 3. Start with Jarod’s tutorial to get your application set up and jQuery installed. Then follow the Railscasts example to add mobile detection, but replace any jQTouch-specific steps and views with those from the jQuery Mobile tutorial. Your views will be named index.mobile.erb, show.mobile.erb, etc., and sit alongside your standard browser-friendly views.
We’re going to use Devise to handle our app’s authentication, so if you haven’t done so yet, install Devise and create a User model. (New to Devise? Refer to the Railscasts tutorial and the GitHub project.) Specifically, we’ll be working more with the Devise views in a minute.
This is by no means a template for creating your mobile app, but here are some ideas to help you get started.
First off, here is a mobile application layout. Mine’s a little different from Jarod’s in that I’ve moved rendering of the header
div to my layout file. Here I’ve got a Nifty Generators-like @title
value that gets set in individual views, but is rendered in the right place. Otherwise, I have a straightforward conditional to display either a Sign In or Sign Out button. Any thoughts on how to properly display my app’s flash messages here?
Since I moved the header
div to the layout, I’ve removed it from the views corresponding to posts_controller.rb
. That makes things look something like this:
If you haven’t done so already, generate a copy of the Devise views into your application:
We’re going to add mobile versions of a few Devise view templates. To start, let’s make a mobile sign in form:
The shared links (displayed depending on the Devise modules your application is using) could be made to look a little more like buttons:
Finally, here’s a mobile login form:
Let’s say that anyone can access the Posts controller’s index
and show
methods, but a user must be logged in to do anything else. The following before filter will take care of that:
If you used the built-in Rails scaffold generator you may need to specify what to do when the mobile MIME type is used for create
, update
and destroy
; for example:
This should be enough to get you started, though as I said it’s not the end-all, be-all template for creating apps with Rails and jQuery Mobile. What I’ve shared here is working for me in development but I’m not ready to move any of this to production just yet. Experiment with it and some of the options available in jQuery Mobile, keeping in mind that jQuery Mobile is currently in its first alpha release. You’ll find some quirks, but I think in the long run this framework will be a winner for creating cross-platform mobile web apps. As you make discoveries of your own, I hope you’ll share them here in the comments.
Ruby on Rails news and tips, and other ideas and surprises from Aaron at Everyday Rails. Delivered to your inbox on no particular set schedule.