brendanlim / mobile-fu

Automatically detect mobile requests from mobile devices in your Rails application.
http://www.intridea.com/2008/7/21/mobilize-your-rails-application-with-mobile-fu
MIT License
707 stars 195 forks source link

mobile-fu and jQuery Mobile #17

Open sjoonk opened 13 years ago

sjoonk commented 13 years ago

I am using mobile-fu with jQuery Mobile. As you know, the jQuery Mobile convert a normal HTTP request to Ajax style request. When I use mobile-fu with jQuery Mobile, It seems the mobile-fu doesn't understand mobile format and render the normal html template, not the mobile template.

Any Idea?

dmfrancisco commented 13 years ago

Try this code, maybe it will fix your issue:

class ApplicationController < ActionController::Base
  protect_from_forgery
  has_mobile_fu # Detect the device type
  before_filter :set_request_format

  def set_request_format
    request.format = :mobile if is_mobile_device?
  end
end
pauloconp commented 13 years ago

Great! Thanks for the solution.

houen commented 12 years ago

@dmfrancisco You just saved my bacon! Thanks :-) Seeing as jquery-mobile has just been released to v. 1.0 and can be expected to grow a lot, I'm adding this to the wiki

lyslim commented 12 years ago

Right, setting the request format to mobile definitely solve the issue, but why checking the ajax request at the first place in the method set_mobile_format? @benlangfeld, can you comment?

Many thanks.

benlangfeld commented 12 years ago

I can't comment on the behaviour of mobile-fu as a plugin. If you find any issues with the gem, please file them on my fork as the code is completely different.

lyslim commented 12 years ago

But both the gem and the plugin share such method?

https://github.com/benlangfeld/mobile-fu/blob/master/lib/mobile-fu.rb#L66

benlangfeld commented 12 years ago

@gareth (https://github.com/benlangfeld/mobile-fu/commit/93d875d3200016bfb4c0338da3a834de86885583) or @revgum (https://github.com/benlangfeld/mobile-fu/commit/41dd15c253fc52824d02fe80dbaa4e81e980f536) might recall the reason for this

gareth commented 12 years ago

Afraid I can't shed any light on this. My commit was only to make force_mobile_format use the same flow as set_mobile_format (https://github.com/brendanlim/mobile-fu/pull/16) - I don't remember knowing why the .xhr? check was already there.

pipplo commented 12 years ago

I think I am having a similar problem. I wanted to add some more details.

When using mobile_fu everything works fine until I try some ajax requests. I have an ajax action def ajax_select_user, after completion I call render

respond_to do |format|
    format.js { render select_user }
end

This code will call the associated select_user.js.erb which is expected. Inside select_user.js.erb I have some javascript to fill in some HTML. I call some partials in the .js.erb files

$("#selected_user").replaceWith("<%= escape_javascript( render(:partial => "selected_user") ) %>")

Now, I want selected_user.mobile.erb to be displayed since this is a mobile ajax request. selected_user.html.erb is called instead.

pipplo commented 12 years ago

Ok I have some more details on this. As it is mobile_fu will have difficulty with the scenario I put up.

In an XHR request the type will be set to :js not :mobile. This is desired because we need the correct javascript response type. When in :js mode if you call render the ActionView will first look for :js (this is good for calling your .js.erb file) and will also look for :html. :html is hardcoded here

https://github.com/rails/rails/blob/master/actionpack/lib/action_view/lookup_context.rb

# Override formats= to expand ["*/*"] values and automatically
# add :html as fallback to :js.
def formats=(values)
  if values
    values.concat(default_formats) if values.delete "*/*"
    values << :html if values == [:js]
  end
  super(values)
end

Ideally it would be nice to change that fallback value dynamically somehow. From :html to :mobile if it's a mobile site. I'm not really sure how that could be done.

I have found a workaround. I was able to add this code to the to of my .js.erb view template.

<% self.formats = [:js, :mobile] %>

I imagine you could do something like this at the top of all of the .js.erb files used in ajax requests..

<% self.formats = [:js, :mobile] if is_mobile_device? %>
pipplo commented 12 years ago

@lyslim if you set it to :mobile instead of :js then ajax requests don't work right.

lyslim commented 12 years ago

Yes, but I guess this could be done on controller side by calling the class method respond_to :mobile, :html, :js ?

PS, I found setting the format directly also won't work when browsing full site from mobile device, as then we actually need html format.

benlangfeld commented 10 years ago

This project is abandoned. Please see the active fork at http://github.com/benlangfeld/mobile-fu. Please test with the released gem and master branch of the new home for the project, and file an issue on the other repo if you still have problems.

See #40.