views:

211

answers:

5

I'm having an issue with rails not actually executing JS in a template. I have a respond to block in my controller that is like this:

respond_to do |format|
  format.js   {}      
end

and the proper file in the views, but when it renders it actually just prints the JS, like the mime type is wrong. (the file is add_item.js.erb)

For example if I had this as a test in my view:

<%= "alert('running');" %>

but when that action gets executed in the controller the page redirects and the HTML out put is the JS itself:

alert('running');
A: 

Try this:

<script type="text/javascript">
<%= "alert('running');" %>
</script>

Not sure what you're trying to do, but you can't simply load some javascript text code in a browser and expect it to run.

Andre Goncalves
Nope, that's not working, and sure you can just load some JS into your browser and it should run, I don't understand what you mean.
Joseph Silvashy
+1  A: 

This behaviour of Rails is correct. However you do not provide how you call this JS page in your view (link_to_remote ?)

What most people forget is that other JS helper methods (link_to_remote etc) perform eval(response). If you write custom JavaScript (like I did with jQuery) you have to add eval(...) by yourself.

EDIT Here an example:

$.ajax({
  url: "foo",
  type: 'post',
  success: function(data) {
    eval(data);
  }
});
Marcel J.
right, I did write my own jQuery for this, where do you use the `eval(...)` method? do did you encapsulate your js with it?
Joseph Silvashy
I added an example for how to use `eval()` in jQuery's `$.ajax` to match the behaviour of standard Rails JS helpers.
Marcel J.
A: 

How are you calling that action? Are you using an :update option in a remote helper?

I've seen it behave this way if you are using a remote helper with an :update option set and then trying to send back a specific replace_html or similar call using rjs on the controller side.

paulthenerd
A: 

Got it, It was a JS problem, I'm using the ajax method that jQuery provides as such.

$("a.add_line_item").click( function() {
  $.ajax({
    url: this.href,
    dataType: "script",
    beforeSend: function(xhr) {xhr.setRequestHeader("Accept", "text/javascript");},
  });
 return false;
});
Joseph Silvashy
+1  A: 

I was going to comment on the author's answer but there's too much code to post... You could tighten up the JS a little. First you probably want to set headers globally and not on every request and if you're making a post you need to do a little more work:

$(document).ajaxSend(function(event, xhr, settings) {
  xhr.setRequestHeader("Accept", "text/javascript, application/javascript");     
});

Using getScript would also make the code shorter:

$("a.add_line_item").click(function() {
  .getScript(this.href); 
});

I also have a blog post about making post requests from jQuery to Rails that you might be interested in.

Andy Gaskell
Excellent answer. this really cleaned my code up nicely. Thanks!
Joseph Silvashy