Onichan
Onichan

Reputation: 4516

Pass Variable into escape_javascript

This passes the string productID instead of the variable which == 5. How can I pass the variable, not the string?

<script>
$(document).ready(function(){
    $(".test").click(function(){
      var productID = 5;
      $("#productModal").html("<%= escape_javascript(render 'layouts/modal', :product_id => "productID").html_safe %>"); 
      $("#modal").modal();
    });
});
</script>

also tried:

$("#productModal").html("<%= escape_javascript(render 'layouts/modal', :product_id => " + productID + ").html_safe %>");

This also just outputs + productID + instead of 5

Upvotes: 2

Views: 1492

Answers (1)

Richard Peck
Richard Peck

Reputation: 76774

If you wanted to fix the code you've provided, you'd be best doing the following:

<script>
$(document).ready(function(){
    $(".test").click(function(){
      var productID = 5;
      $("#productModal").html("<%=j render('layouts/modal', product_id: " + productID + ").html_safe %>"); 
      $("#modal").modal();
    });
});
</script>

However there are several big problems with this code.


Unobtrusive

Firstly, why are you using <script> tags?

This would suggest you've put this inside a view, which is very bad practice.

The most effective way is to use the unobtrusive javascript pattern, which is what the Rails asset pipeline is able to support:

#app/assets/javascripts/application.js
$(document).on("click", ".test", function(e) {
    var productID = 5;
    $("#productModal").html(productID); 
    $("#modal").modal();
});

This not only means you're able to use this code throughout your application (modularity), but also ensures you're able to call the correct

--

Accessibility

Secondly, you'll notice I have excluded the escape_javascript code above.

This is because the asset pipeline does not handle ERB / Rails code.

Javascript is client-side; Rails is server-side.

This is important, as when you call render etc - your javascript will not be able to do this unless it's called from the server, especially if the partial requires a variable which is set on DOM load.

For this, you'll need to use ajax:

#config/routes.rb
get "modal", to: "application#modal"

#app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
   def modal
      @productID = params[:product_id]
      respond_to do |format|
         format.js { render "layouts/modal", product_id: @productID }
      end
   end
end

#app/assets/javascript/application.js
$(document).on("click", ".test", function(e) {
   var productID = 5;
   $.get("modal", {product_id: productID}, function(data) { 
      $("#productModal").html(data); 
      $("#modal").modal();
   });
});

A small caveat here is that if you append .erb to the JS file (javascripts/application.js.erb), you'll be able to use render. However, this can only happen when the file is invoked; thus passing any variable to the partial will not work.


Update

Here's what worked in the end:

#app/assets/javascripts/application.js
$(document).on("click", ".testinggg", function(e) { 
   var productID = 5; 
   $.get("modal", {product_id: productID}, function(data){ 
     $("#productModal").html(data); 
     $("#modal").modal(); 
   }, "html"); 
});

Upvotes: 2

Related Questions