Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get rails controller variable in js file

I have a variable in rails controller like

def index
@approveflag = true
end

I need to access this variable in my javascript code, I used the code given below in index.html.erb

<script>
alert("<%=@approveflag%>")
<script>

It works fine with result "true".But when I moved this code to its corresponding .js file it gives an alert with result string ""<%=@approveflag%>"". What is the reason. How can I solve this?

Thanks in advance.

like image 717
Anna Avatar asked Jun 26 '14 10:06

Anna


People also ask

Can you use JavaScript with Rails?

Rails uses a technique called "Unobtrusive JavaScript" to handle attaching JavaScript to the DOM. This is generally considered to be a best-practice within the frontend community, but you may occasionally read tutorials that demonstrate other ways. When clicked, the link background will become red.

What is JS Erb in rails?

.js.erb files are for controller actions, such as create, when you want javascript to be executed when the action completes. For example, when you want to submit a form via ajax and want display an alert when everything is done, you would put the $('#business_submit'). click(...) in your application.

What is Rails ujs?

Rails UJS (Unobtrusive JavaScript) is the JavaScript library that helps Rails do its magic when we use options like remote: true for many of the html helpers. In this article I'll try to explain the main concept of how this works to make it transparent for the user.


4 Answers

I personally don't like mixing js with erb so I would do something like this:

in index.html.erb

<%= content_tag :div, '', id: 'mycontainer', data: { source: @approveflag } %>

in js

$('#mycontainer').data('source')
alert($('#mycontainer').data('source'))

And you have the value from that instance variable, you can add a data attribute in a link_to if you want.

like image 110
alexsmn Avatar answered Oct 04 '22 16:10

alexsmn


You cannot use the js files for this, they are part of the asset pipeline, they are compiled/compressed, and preferably only downloaded once by your client (browser). So they should not change. So at the time the js-files are precompiled, the instance variable is not set and would not make any sense anyway.

But there are a few options.

You can declare a javascript variable in your view, which your javascript can use (for global data)

Code (I use haml):

:javascript
  var approveFlag = #{@approveflag} ;

You can declare data-tags on elements, if the data belongs to a specific element. But for instance, you could also a data-tag on body element

For instance

%body{:'data-approveflag' => @approveflag}

Or something like

= link_to 'Collapse', '#', 'data-collapse-div' => 'class-to-collapse'

Alternatively you can use ajax/json to download the data. This is clean, but adds an extra delay, so only do this is if the data is not required immediately.

like image 37
nathanvda Avatar answered Oct 04 '22 16:10

nathanvda


I recommend that you to use the 'gon' gem

I'm usually more oriented to straight options that don't imply installing, but trust me using 'gon' is very direct and clean

In your Gemfile add this lines

# To use controller variables as javascript variables
gem 'gon'

Do a bundle install to get/install the gem

In your app/views/layouts/application.html.erb add the following line

<%= include_gon %>

Then in your controller pass your variable to gon as simple as this

gon.your_variable = @controller_variable

And in your javascripts retrieve your variable (in this case to show an alert)

alert (gon.your_variable) ;

And That's it !

For more examples and details see the Wiki page - https://github.com/gazay/gon/wiki

like image 27
Mauricio Gracia Gutierrez Avatar answered Oct 04 '22 14:10

Mauricio Gracia Gutierrez


In my project I need sometimes user language related translations. So what I did is, I created a simple js file to store the localized text:

var TRANSLATION_ARRAY = []

function store_translation(key, value) {
  TRANSLATION_ARRAY[key] = value
}

function get_translation(key) {
  return TRANSLATION_ARRAY[key]
}

In den index.html.erb or other components I do this to store the localized text:

store_translation('text_id', "<%= translate_with_user_language('text_id') %>")

In my plain js file located in app/assets/javascripts i get the localized text by:

get_translation('text_id')

Works very well. You can use this approach also for other purposes not only translations.

like image 24
Alexander Bahlk Avatar answered Oct 04 '22 15:10

Alexander Bahlk