How to upgrade the :update=>'div_id' option of remote_form_for from Rails 2 to Rails 3?

北战南征 提交于 2020-01-01 03:38:06

问题


I can't figure out how to upgrade this code from Rails 2 to Rails 3:

<% remote_form_for(item, :update => 'div_id') do |f| %>
... 

I tried this:

<%= form_for :item, :remote => true, :url => { :controller => "items", :action => "create" }, :update => 'div_id' do |f| %>
...

It creates the new item but it fails in updating the content within <div id="div_id"></div> tags. It seems Rails 3 no longer supports the ":update" option for a remote form_for. Any suggestion?


回答1:


You could use RJS, but that's being deprecated too (and for good reason). The simplified, best-practices way to handle this in Rails 3+ is as follows (assuming jQuery):

# your_view.html.erb
<div id="receiver-id"></div>

<%= form_for :some_model, :remote => true, :id => 'form-id' do |f| %>
  ...
<% end %>


# application.js (or any other .js loaded on the page)
$(function(){
  $('#form-id').bind('ajax:success', function(xhr, data, status){
    $('#receiver-id').html(data);
  });
});

The ajax:success hook gets called by the jquery-ujs (aka jquery-rails, aka rails-ujs) remote link/form handler. See for yourself. There are lots of other callbacks/hooks available for you to use, too. If you wanted to make this even more flexible, you could use live instead of bind, and bind to a class that dictates where the ouput goes (e.g. "sidebar") and then all remote links/forms with the sidebar class would have their HTML response go to div#sidebar.




回答2:


The most straightforward way to do this would be to write a javascript view template, e.g. create.js.erb which would look something like this:

$('#div_id').html("<%= escape_javascript(render(@item)) %>");

(depending on your setup, of course, I'm assuming an @item variable and an associated _item partial)

Edit:
coreyward is right. This is the RJS way which is more of the old fashioned Rails 2.x "Rails way". It's probably more familiar, but has issues. Your specific case is one of them, actually, as typically you might bind to an HTML element to update using the record's id (e.g. div #item_1), and in the create case there is no id available beforehand, complicating matters.

Binding via clientside JS eliminates this issue. RJS works in something of a vacuum, making assumptions about the state of the client's HTML and having no access to it.




回答3:


I know the question is old but I when migrating to Rails 3 I found a pretty good way of doing this, so I thought I would post it here in case anyone else is in a similar solution.

In layouts/update_page.js.erb I put this file:

$j('#<%=@update_div_id||"list_div"%>').html('<%= escape_javascript render(:partial => (@partial_div||"index"), :locals => @local_hash) %>');

This is mainly used for searches that use remote, so in the index action in the controller, I just added the following code.

respond_to do |format|
  format.html
  format.js {render 'layouts/update_page'}
end

Since remote is being used, it will always try to use javascript first, so it will render the update_page.js.erb file from above. For us, we almost always use the div#list_div on our index pages, so we update that by the default, however if you need to update something different, you can pass in @update_div_id, and if you need to render a different page, you can pass in @partial_div.

To clarify, for a lot of things, it is probably better practice to use the callbacks, but I found this to be a much easier way, when we had to migrate over nearly 100 of these calls.



来源:https://stackoverflow.com/questions/7044027/how-to-upgrade-the-update-div-id-option-of-remote-form-for-from-rails-2-to-r

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!