Alternative for link_to_remote's :update in rails3 - ruby-on-rails

Im in the process of converting my rails code which developed in version 2 to rails 3. Earlier I used link_to_remote function to create a link.In that I displayed the page on a div field using ':update' option.
<%= link_to_remote #processes_tree[x]["name"],:update => "toprightdiv", :url => { :action => "editproduct", :id => #processes_tree[x]["id"]}%>
Now In rails the link_to_remote is not available ,So I used link_to.But in it the :update option is not available.So I am not able to show the page in the div field.When ever I click the link a new page getting displayed for the link.Is there any alternative way available i n rails3.Please help me to solve the issue.

This is a very general question regarding unobtrusive javascript in rails (googling that phrase would get all you need to know).
Generally you need to use link_to and set :remote to true. Then do the update by handling the response in a .js view or equivalent.
You may also benefit from this screencast demonstrating the rationale for the change:
http://railscasts.com/episodes/205-unobtrusive-javascript

The :update option isn't supported by the new link_to :remote => true.
You will either have to
use the legacy plugin
write the JS/AJAX yourself instead of using :remote => true
use render :update { |page| p.replace_html ... }

Related

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

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?
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.
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.
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.

Rails 2 to Rails 3 : using link_to instead of link_to_remote (including remote and update)

A quick and easy answer I'm sure.
I'm upgrading a Rails project from version 2 to version 3 and replacing a load of the link_to_remote with link_to's as per the Rails 3 update. Even something as simple as :
<%= link_to "Check Time",
{:action=>:get_time}, :remote=>true, :update=>'current_time' %>
<div id='current_time'></div>
doesn't seem to work. The request (using get method) is going through ok and the rendered html is :
Check Time
Routes.rb entry :
get "monitoring/get_time"
As I say I'm sure this is a very obvious issue on my part!
The :update option isn't supported by the new link_to :remote => true.
You will either have to
use the legacy plugin
write the JS/AJAX yourself instead of using :remote => true
use render :update { |page| p.replace_html ... }
The :update parameter is gone. You need to handle the DOM update yourself using Unobtrusive JavaScript. Also, make sure you actually included the csrf_meta_tag helper in your layout.
I wrote an article about using unobtrusive JavaScript in Rails 3.

Rails 3: How to make an Ajax call?

I would like to have a link (is there a better option?) on my page which will make an Ajax request when clicked. (I would like to update a field in my database when the link is clicked.)
What is the simplest way to achieve this ?
Could you refer me to some tutorials ?
Really simple. In your view, have a link/button like so. Important bit being :remote => true
<%= link_to 'Update Thingy', update_thingy_path, :confirm => 'You sure you wanna update?', :remote => true %>
or
<%= button_to('Update Thingy', {:action => 'update_thingy', :thingyid => 314}, :method => :get, :remote => true) %>
Obviously, you have to get update_thingy_path to resolve to some action as normal. The difference is when you render you are going to be rendering some *.js.erb instead of *.html.erb. In that update_thingy.js.erb, you just put whatever javascript you want to run in the client. You might wanna notify the user that the update happened for example (in jQuery):
$('#notice').html("Thingy was update.")
Or if whatever javascript you're returning is really simple, in the controller you can do something like the following instead of having a whole js.erb for a one-liner.
render :js => "alert('Blah')"
You're really going to be using two technologies to accomplish this: javascript on the client-side, and rails on the server-side.
The general idea is that you want to:
(1) add your web methods on the server side with rails, and then
(2) use something like jQuery to get your client-side js calls up to the server to fire off the web methods.
Two writeups I found by googling for : rails3 ajax
http://www.stjhimy.com/posts/7-creating-a-100-ajax-crud-using-rails-3-and-unobtrusive-javascript
http://www.simonecarletti.com/blog/2010/06/unobtrusive-javascript-in-rails-3/
API Reference for using jQuery's ajax post() method:
http://api.jquery.com/jQuery.post/

Rails controller not rendering correct view when form is force-submitted by Javascript

I'm using Rails with jQuery, and I'm working on a page for a simple site that prints each record to a table. The only editable field for each record is a checkbox. My goal is that every time a checkbox is changed, an ajax request updates that boolean attribute for the record (i.e., no submit button).
My view code:
<td>
<% form_remote_tag :url => admin_update_path, :html => { :id => "form#{lead.id}" } do %>
<%= hidden_field :lead, :id, :value => lead.id %>
<%= check_box :lead, :contacted, :id => "checkbox"+lead.id.to_s, :checked => lead.contacted, :onchange => "$('#form#{lead.id}').submit();" %>
<% end %>
</td>
In my routes.rb, admin_update_path is defined by
map.admin_update 'update', :controller => "admin", :action => "update", :method => :post
I also have an RJS template to render back an update. The contents of this file is currently just for testing (I just wanted to see if it worked, this will not be the ultimate functionality on a successful save)...
page << "$('#checkbox#{#lead.id}').hide();"
When clicked, the ajax request is successfully sent, with the correct params, and the action on the controller can retrieve the record and update it just fine. The problem is that it doesn't send back the JS; it changes the page in the browser and renders the generated Javascript as plain text rather than executing it in-place.
Rails does some behind-the-scenes stuff to figure out if the incoming request is an ajax call, and I can't figure out why it's interpreting the incoming request as a regular web request as opposed to an ajax request.
I may be missing something extremely simple here, but I've kind-of burned myself out looking so I thought I'd ask for another pair of eyes. Thanks in advance for any info!
In your controller you need to specify the proper response. Since you didn't post the controller I'll just try to fill in the blanks.
def update
# Update something
respond_to do |format|
format.js # this renders your rjs file
end
end
Specifying the format tells the rails app to interpret the javascript instead of just sending it back as text.
The other option instead of using rjs is to do an inline rjs block like this:
render :update do |page|
page.replace_html 'user_list', :partial => 'user', :collection => #users
page.visual_effect :highlight, 'user_list'
end
Only use the inline rjs if you will be doing minimal changes to the interface that can be put into one or two lines. Anything more should be in it's own rjs file.
This question is related to this one, but the answer varies slightly. I had to create a new way to submit the form, since the default jQuery submit() method does not submit as a 'script' and certainly does not fire the code that Rails generates in the onsubmit="..." handler via the form_remote_tag helper.
The solution was to create a new function as the linked answer suggests, but the contents are slightly different:
jQuery.fn.submitWithAjax = function() {
jQuery.ajax({data:jQuery.param(jQuery(this).serializeArray()) + '&authenticity_token=' + encodeURIComponent('<%= form_authenticity_token %>'), dataType:'script', type:'post', url:'/update'});
return false;
};
This is brittle right now-- notice that I insert rails' form_authenticity_token into the Javascript, but really the method (post) and the url (/update) should also be generated rather than hardcoded.
Things are working A-OK now.

Where did link_to_function disappear to in Rails 3?

I was just playing around with Rails 3 beta and noticed that link_to_function is now gone. I presume there's an alternate method of achieving the same result (onclick event?) but I was wondering if there's a more Rails-3'y way of doing it. TIA.
Rails 3 seems to have done away with Prototype Helper in favour of a less obtrusive/JS library agnostic approach. The goal is to eliminate all inline javascript generated by Rails. Prototype Helper generated pretty much all of the javascript.
Now any of the non remote variants of helpers will generate the proper javascript for a remote call in your JS library of choice just by supplying the :remote => true option.
Unfortunately this doesn't hold true for the x to function methods. For the time being there are the prototype legacy helpers which are no longer a core part of Rails.
You could also use call as defined in ActionView::Helpers::PrototypeHelper::JavascriptGenerator::GeneratorMethods to supply javascript code to :onclick as an html_option for link_to, but that's not exactly pretty.
Examples:
Rails < 3 | Rails 3
link_to_remote "target", url | link_to "target", url, :remote => true
form_remote_for #post | form_for #post, :remote => true
etc....
Or something to that effect. I'm having trouble finding official documentation to back up my claims. So the release notes will have to do for now.
Before you can use it, you'll need to include the proper js source files. Ensure that you are loading prototype.js and rails.js, or the library and driver for JS framework of choice in their place.
Remember, Rails 3 is in beta now. But that doesn't mean it's done. I honestly have no idea how link_to_function will be replaced. It goes against the ideal of unobtrusive javascript.
To answer my own question, seems this works and is sufficient for what I need:
link_to "name", nil, :onlick => "alert('Hello, world!')"
link_to_remote can be done like this
link_to "target",:remote => true
and to do a ajax post/get you have
link_to "target", {:controller =>
controller, :action => method, }, :remote => true
In rails 2 it was like this
link_to_remote "target", :url =>
{:controller => controller, :action =>
method, }, :remote
=> true

Resources