Rails 3 make ajax using jquery and execute .js.erb - javascript

I have the following haml code:
%input{:value => "", :type => "button",:class => "SendBtn", :onclick => "$.get('#{send_path}',{parameter:$('#parameter').val()}); "}
This input executes an event in the controller.
// This is my controller
def send
if request.xhr?
// do stuff
end
end
But my js code in the corresponding .js.erb file is not being executed. It is returned as the response of the get request.
// send.js.erb
alert('hello');
How is the rails way to have this code executed?

Your problem is not Rails related, it's jQuery. With the get method you are just fetching more or less plain text. This will not get executed. You could do an eval on the text but there is a better way. Use the getScript method from jQuery. This will fetch and execute your code.
As a side note, there are two things that are bothering me in your code:
You are using inline JavaScript. try to remove this by using a data- attribute for your send path, like this data: { sendPath: send_path }, and retrieving it with $(yourInput).data('sendPath') in your application.js file.
From my personal view I do not like to put executing JavaScript code in ERB templates. I find that this fragments the front end logic of my app. For me it worked better to put the logic in .js files and communicate with the server over JSON.

As #topek said, you have to use $.getScript. Also in your situation better approach is to use button_to with :remote => true property instead of plain input.
<%= button_to "Do Something",
{ :controller => :somecontroller, :action=> :something },
{ :remote => true }
%>
Also you can pass attributes to button_to (but you have add parameter to your route definition).
<%= button_to "Do Something",
{ :controller => :somecontroller, :action=> :something, :param => #object.id },
{ :remote => true } %>
Here goes documentation for button_to: http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-button_to

Related

How to avoid to evaluate a JavaScript response?

I am using Ruby on Rails 4. In my previos question I asked about how to handle JavaScript events of a link_to :remote element "a là Rails Way". However I would like to make the AJAX to do not evaluate the JavaScript response (whatever it is) so that I can implement my custom behaviors.
In my case the AJAX response that should be ignored is generated by clicking the following link:
link_to('destroy', article_path(#article), :method => :delete, :remote => true, :id => 'css_id')
On success it will return a JS redirect but I would like to simply catch the success response and do not evaluate the subsequent redirect.
$('#css_id').on('ajax:success', function(event, xhr, status) {
alert("success!");
\\ Here I would like to do not evaluate the JS response.
});
How can I make that?
You can write a javascript behavior and just call this behavior in your .js.erb file since you can avoid writing more js codes inside the template. It should be something like this.
EX: in the create.js.html:
App.createProdict() #pass the required params.
And this App.createProduct is a js behavior.

Iterate through array passed from controller

I'm using Ruby on Rails.
Here is my code for the view, where I make a post to the controller, passing parameter "tplangroup.id":
<div id="collapse">
<%= form_tag(tplans_collapse_tplans_path, :method => 'post', :remote => true ) do %>
<%= hidden_field_tag(:tplangroup_id, tplangroup.id) %>
<% end %>
</div>
Here is my code on the controller end, where it parses the necessary data and shoots back array "#ordered_tplans"
def collapse_tplans
#collapsed_tplangroup = Tplangroup.find(params[:tplangroup_id])
tplans_from_tplangroup = #collapsed_tplangroup.tplans
#ordered_tplans = tplans_from_tplangroup.order("favrank DESC")
return #ordered_tplans
end
Since I called :remote => true in the original form located in the view, it passes this array to a file called "collapse_tplans.js"
My question is: what is the best way/practice to parse through this array now passed to the js file, and display its contents in the view? Do I use rails code in the js file to manipulate the object? Or do I do it all in javascript/jquery? What is the best practice, and could you provide any example?
Thanks!
Really kind of depends on how you want to go about it, as with all code, there are many ways to skin a cat. I find the easiest way is to use the return ujs as an erb file (collapse_tplans.js.erb) and from there, choose the element on the page you want to attach the retuned object to, and call a standard erb or haml partial where your iterations can be done clearly.
e.g.
In collapse_tplans.js.erb
$('#my_wacky_element').append("<%= j render(:partial => 'collapse_tplans', :locals => { :ordered_tplans => #ordered_tplans }) %>");
Then in
_collapse_tplans.html.erb
<ul>
<%= ordered_tplans.each do |tplan| %>
<li><%= tplan.attribute %></li>
Here is a RailsCast on how to pass data to js from rails:
http://railscasts.com/episodes/324-passing-data-to-javascript?view=asciicast

link_to_remote: how do I abort the action, if a javascript variable is false?

I tried doing this:
<%= link_to_remote '', {:url => { :action=> :edit_content,
:id=>content.id,
:controller=>#contents_controller},
:before=>"false;",
:complete => "click_content_after();"},
:class=>'edit' %>
but the link still executes... the before block has no influence on the behavior of the link.
there is a :confirm option, but I don't want there to ALWAYS be a dialog... as I have js variables that watch the state of the page.
You can customize browser side call logic by passing in JavaScript code snippets :condition optional parameter and not :before. Read link_to_remote API documentation.
I tested it in my old Rails 2.3.2 application and this works as expected. When :condition => "true" the call to remote is performed and not when :condition => "false".
<%= link_to_remote "Temp", :update => "temp_update", :url => { :action => "temp" },
:condition => "false", :complete => "alert('complete!');" %>
You can add a :condition parameter (e.g. :condition=>"return false;") that should be evaluated before making the remote call, and will prevent the remote call if it returns false.
link_to_remote will abort only if :complete returns false.

sending variable to a javascript file in RoR

I am using ajax to call a RoR rails function and am new to this.
The function is
def destroy
#fav_company = FavouriteCompany.find(params[:id])
respond_to do |format|
format.js { render :layout=>false }
end
end
In my destroy.js.erb I have
$('#profile_alerts').show();
$('#Fav#{#fav_company.id}').hide();
The first line is working but not the second line. I am suspecting it is unable to access #fav_company.
What should I do? thanks
=====
Some additional information, the call I am making to this function is a link_to with remote => 'true' as such:
<%=link_to "destroy",{:controller=>"favourite_companies",:action=>"destroy", :id=>"#{fav.id}"}, {:remote => true } %>
This:
$('#Fav#{#fav_company.id}').hide();
Should be:
$('#Fav #{#fav_company.id}').hide();
Assuming #fav_company.id presents a variable in the DOM
Since your javascript code is in an ERB file I think you should be using $('#Fav<%=#fav_company.id%>').hide();.
Try to use:
$('#Fav#{escape_javascript({#fav_company.id}).html_safe}').hide();
==================================================================================
Ok, my code, but I does another task:
albums/show.html.haml
= link_to t('write.comment'), new_album_comment_path(#album, :format => :js, :id => #album.id), :remote => true
comments/new.js.haml
$("#comment_form").html("#{escape_javascript(render :partial => "comments/form").html_safe}");
also all code here https://github.com/barthezslavik/mebel - if you found something useful, I'll be happy

Monitoring a server-side process on Rails application using AJAX XMLHttpRequest

I'm using the following in the web page but can't get a response from the server while it's processing
<script type="text/javascript">
<!--
function updateProgress() {
//alert('Hello');
new Ajax.Request('/fmfiles/progress_monitor', {
parameters: 'authenticity_token=' + encodeURIComponent(AUTH_TOKEN),
onSuccess: function(response) {
alert(response.responseText);
fillProgress('progressBar',response.responseText);
}
});
}
//-->
</script>
<% form_for( :fmfile, :url => '/fmfiles', :html => { :method => :post, :name => 'Form_Import', :enctype => 'multipart/form-data' } ) do |f| %>
...
<%= f.file_field :document, :accept => 'text/xml', :name => 'fmfile_document' %>
<%= submit_tag 'Import', :onClick => "setInterval('updateProgress()', 2000);" %>
The 'create' method in fmfiles_controller.rb then happily processes the file and gets the right results (as per the submit button on the form). If I uncomment the '//alert('Hello')' line I get a dialog saying Hello every 2 seconds ... as expected.
However, the server never logs any call to 'progress_monitor' method in 'files' not even a failed attempt.
If I click the link
Run
it makes a call to the server, gets a response and displays the dialog, so I assume the routes and syntax and naming is all OK.
I really don't know why this isn't working. Is it because 2 methods in the same controller are being called via URLs?
I'm using Rails 2.1.0 in a development environment on OS X 10.5.5 and using Safari 3.1.2
(N.B. This follows on from another question, but I think it's sufficiently different to merit its own question.)
If you are not seeing messages in your log file for the call to 'progress_monitor' then it is possible that the request is never being sent.
Try this:
Try using the full URL instead of the relative URL for the Ajax.Request. I have had problems with relative URLs on some browsers with the Ajax.Request.
Enable Firebug or the IE Developer Toolbar. You should be able to see if the call to progress_monitor works or not. If there is a java script error then you will see the error clearly using these tools.

Categories

Resources