dimitry_n
dimitry_n

Reputation: 3019

Passing a local variable into another view's JS - Rails

Is there a way to grab / fetch a variable inside js between two different views? Say I have an index view with does:

<% foo.each do |foo| %>
  <%= link_to 'bar', bar_path %> 
<% end %>

Then in bar I want to add some jQuery to a specific element with foo.id selector:

$('div#<%= foo.id %>').fadeOut(); // I know the interpolation wouldn't work here

I know I can pass foo.id to bar with my path or send it via the locals hash, but how would I "grab" it with jQuery?

Upvotes: 2

Views: 303

Answers (3)

Richard Peck
Richard Peck

Reputation: 76774

Is there a way to grab / fetch a variable inside js between two different views

Not without hacking.

JS is an client-side technology, meaning it loads in the browser, not on the server. This is famous for causing so many issues for developers trying to bind to dynamically-named objects, much like what you're trying to do.

There are several ways around this. I'll go through them for you:


Class

The first way is to use a broader identifier, such as element type or class.

You're currently trying to select foo.id, which means you're going to have to pass that data directly to JS somehow. Inefficient.

A much better way would be to use something like this:

$("a.bar").on("click", function(e){
   $(this).fadeOut();
});

--

URL

According to this resource, there are no inbuilt ways to pull query strings from JS: How to get the value from the GET parameters?

You may be able to do something like this:

$(document).ready(function(){
   foo = window.location.search.substring(1); //Considering you have http://url.com/your/foo/id
   $("#" + foo).fadeOut();
});

--

ERB

There is a final alternative, although this only works if you don't precompile your JS (which I'm not sure is actually feasible any more). That is to use ERB directly in your JS, rather like what you've done in the question.

Whilst this works for dynamic references (such as paths), I don't think it can pull data from a controller. Unless, of course, you put the script directly in your view - which goes against the conventions of MVC.

#app/views/bar/show.html.erb
<script>
   // your code here
</script>

Upvotes: 1

Gautam
Gautam

Reputation: 1812

I think you need to create a js.erb file and in that pass a variable defined in your controller action. The code insde js.erb would look like this :

<% fields_html = render "fields", :entity => @model %>
$("#fields-list").html("<%= escape_javascript fields_html %>") 

Here fields is a partial I have created. :entity is basically passing of the variable value. @model is the variable defined inside controller action. fields-list is the id of the field I want to load using jquery.

Upvotes: 0

Raphael Ottoni
Raphael Ottoni

Reputation: 516

You can easily pass variables to JS using a gem called gon.

gem "gon"

All you have to do is add this gem to you Gemfile and then you can call gon inside any controller like this:

class PaymentsController < ApplicationController

  def new
    ...
    gon.controller = "payments"
    gon.action    = "new"
    gon.message   = "Hello World!"
    ...
  end 
end

And now, at any javascript (in following case, coffeescript) you can:

$ ->

  # Check if it is the target controller and action
  if gon? && gon.controller is "payments" &&  gon.action is "new"
    alert gon.message 

Upvotes: 1

Related Questions