Matt Rowland
Matt Rowland

Reputation: 379

Rails 3 and jQuery - How to add Ruby code into an element

I'm trying to use jQuery, jQuery form plugin, and Ruby on Rails to create an AJAX image uploader.

I've got all the image uploading and ActiveRecord creating done, but the AJAX part itself won't work - it should cause a <div> to re-render a collection of Picture partials. However, the Ruby code I'm trying to insert is being rendered as a string instead of being executed.

application.js:

$(document).ready(function(){
    $("#upload input").change(function(event){
        $(this).parent().ajaxSubmit({
            beforeSubmit: function(a,f,o) {
                o.dataType = 'json';
            },
            complete: function(XMLHttpRequest, textStatus) {
                $("#img_div").html('<%= escape_javascript(render(@picture.idea.pictures)) %>');
            },
        });
    });
});

Binds the form to ajaxSubmit when the file field is changed, which works fine. The .html() is what seems to have the problem, as the string <%= escape_javascript(render(@picture.idea.pictures)) %> is simply printed in the <div>.

_form.html.erb:

<div id="img_div"><%= render @picture.idea.pictures %></div>

That line works fine on page refresh to render the collection.

And I know there's not a problem with the Ruby code because I previously had that exact line in a create.js.erb file. I would continue to use that approach, except now that I am using ajaxSubmit, I can't get the create action to be rendered as JS - it's always rendered as HTML.

So in theory I can solve the problem one of two ways - figure out why the ruby code is rendered as a string in application.js, or get pictures#create to be rendered as JS.

Am I doing something wrong for those things to not happen?

EDIT:

Ok, so it seems like I can't use Ruby code or variables at all in applications.js, and trying to pass the Ruby collection into JavaScript doesn't work because then I can't access all the attributes I need to recreate the correct HTML.

What I need is a way to ensure that the pictures#create action is called as JS. Then I can use format.js to ensure that create.js.erb is used, where I know my code works. Any advice?

Upvotes: 0

Views: 5972

Answers (2)

vinga
vinga

Reputation: 2012

The problem is that you are trying to run ruby code in JavaScript on browser size:

'<%= escape_javascript(render(@picture.idea.pictures)) %>'

Instead this you should set with HTML method what has already been rendered by render(@picture.idea.pictures)

Upvotes: 0

Sam 山
Sam 山

Reputation: 42863

You can only embed ruby code in javascript if it is in a script in the view. Anything in public/javascripts/ never hits the server so it cannot find the ruby variables.

What you want to do is store the ruby variable in a javascript variable just before you include your scripts.

<head>
 <script type="text/javascript">
   var youJsVariable = <%= ruby_array %>;
 </script>
 <%= javascript_include_tag :defaults, 'application' %>
</head>

This way you don't have to write a lot of inline scripts which bug the heck out of the unobtrusive folks.

Upvotes: 2

Related Questions