开发者

Rails 3 Handling Javascript for Mobile Users

I have a mobile version of my site that I'm developing. I'm using the technique described in Ryan Bates' Railscast episode to do the mobile detection. In a nut, you have to w开发者_运维百科rite a controller action that detects whether this is a mobile browser, and if so, set the request format to "mobile". So you can have views with the name format "file.mobile.erb" alongside "file.html.erb".

This works great. But I have a remote script execution to support, and I'd consequently like to have it serve up a mobile version of the Javascript as well.

Here's the form declaration in the view:

<%= form_for :humanity, :url=>{:action=>"human"}, :remote=>true do |h| %>

On the desktop version, it calls the controller action properly. In the log:

Processing by CardsController#human as JS

But when I call it from the mobile version, the log doesn't pick it out as JS:

Processing by CardsController#human as */*

So I first have to figure out how to get the form to tell the controller that it wants Javascript. Assuming I can do that, then I think this modification to @rbates' code should lock me in (as suggested by a commenter on that Railscast post). This is in application_controller.rb, in the prepare_for_mobile method:

if mobile_device?
    if request.format == :js
        request.format = :mobilejs
    else
        request.format = :mobile
    end
end

So I have a "human.mobilejs.erb" file ready to fire, except it can't until the controller rightfully acknowledges that it's getting a JS request!

Looking forward to your generous assistance!

Aaron


Add !request.xhr? in the following function in your application_controller.rb

def prepare_for_mobile
  session[:mobile_param] = params[:mobile] if params[:mobile]
  request.format = :mobile if mobile_device? && !request.xhr?
end

It will respond to .js request with format.js

Also, as genkilabs suggested, use mobile_fu. It is awesome.


Aaron, you're actually on the right track. However, instead of checking for something like request.format == :js (or worse, request.xhr? which will kill you if you use a framework like jQuery Mobile), you will want to check for a mime type. Here what I did basically:

if mobile_device? and request.format.to_s == "text/html"
  request.format = :mobile
elsif mobile_device? and request.format.to_s == "text/javascript"
  request.format = :mobilejs
end

Then you can include a format.mobilejs {} block and do pretty much what you would do with a regular js block (render out a Javascript template, etc.)


I got it working, but it feels like a nasty, hacky solution.

Following a hint on another SO post, I overrode the rendering in the controller action, like so:

if mobile_device?
   render :file => "#{RAILS_ROOT}/app/views/cards/human.mobilejs.erb"
end

I had already registered "mobilejs" as a javascript mime type in /config/initializers/mime_types.rb:

Mime::Type.register_alias "text/javascript", :mobilejs

So it started hitting my mobile-only script. Hooray! But thereafter, every partial that I was trying to add in my script failed out, because it was also expecting a mobilejs format. So I created a new copy of each of those partials with a mobilejs extension, and it's working. Yucky, but it works.


I'm not sure I totally understand your question, but perhaps you could use something like mobile-fu for detection.

https://github.com/brendanlim/mobile-fu

This gives you methods like, is_mobile_device? # => Returns true or false depending on the device

Then just set the JS file you want to use by yielding from your layout. ie. in your layout put:

<!DOCTYPE html>
<html>
<head>
  <title>sweet app</title>
  <%= stylesheet_link_tag "jquery", :media => :screen %>
  <%= stylesheet_link_tag "main", :media => :screen %>
  <%= javascript_include_tag :defaults %>
  <%= yield :script_includes %>
  <%= csrf_meta_tag %>
</head>

Then in the view you are rendering you can choose which js tag to put there. So in some_view.html.erb or some_view.mobile.erb

<% content_for :script_includes do %>
  <% if is_mobile_device? %>
  <%= javascript_include_tag "jquery-mobile.js" %>
  <% else %>
  <%= javascript_include_tag "jquery-unmovable.js" %>
  <% end %>
<% end %>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜