Ruby on Rails - Send JavaScript variable from controller to external Javascript asset file
Yes, you can!
Rewrite your JS code into function with one argument (timelimit) and put it into some external file. Then you can call the function from view and pass that @timeleft
variable as JS function argument.
Short example:
#controller
@time_left = Time.now.to_i - 3.hours.to_i
.
#javascript
function count_down(time_left) {
$('#countdown').countdown(time_left)
}
.
#view
<%=javascript_tag "count_down(#{@time_left})" -%>
javascript_tag
Example not tested, it is only idea not complete solution. Don't forget to load that JS file. You can use other JS rails helper javascript_include_tag.
retro's technique of using a function parameter is a possibility, but you have to properly escape the variable you are passing with either escape_javascript or to_json + html_safe as explained below.
However, since you want to affect external files, the best techniques will be to use gon. Another good possibility is to use data- attributes.
gon
Gem specialized for the job: https://github.com/gazay/gon
Probably the most robust solution.
Gemfile:
gem 'gon'
Controller:
gon.timeleft = 1
Layout app/views/layouts/application.html.erb
:
<html>
<head>
<meta charset="utf-8"/>
<%= include_gon %>
<%= javascript_include_tag 'application' %>
Asset file:
gon.timeleft === 1
data- attributes
Add values to attributes, retrieve them with JavaScript DOM operations.
Sometimes called "unobtrusive Javascript".
View head:
<%= javascript_include_tag 'application' %>
View body:
<%= content_tag 'div', '', id: 'data', data: {timeleft: '1'} %>
Asset file:
$(function() {
parseInt($('#data').data('key1')) === 1
})
The following illustrate how escape_javascript
and to_json
work for you to use on top of retro's answer.
escape_javascript
Alias: j
.
Works only on strings.
Escapes characters that can have special meanings in JavaScript strings, like backslash escapes, into a format suitable to put inside JavaScript string literal quotes.
Maintains html_safe
status of input,
so needs html_safe
otherwise special HTML chars like <
would get escaped into <
.
<% a = "\\n<" %>
<%= javascript_tag do %>
f('<%= j(a) %>') // === '\\n<'
f('<%= j(a).html_safe %>') // === '\\n<'
<% end %>
to_json + html_safe
Works because JSON is almost a subset of Javascript object literal notation.
Works not only on hash objects, but also on strings, arrays and integers which are converted to JSON fragments of the corresponding data type.
<% data = { key1: 'val1', key2: 'val2' } %>
<%= javascript_tag do %>
var data = <%= data.to_json.html_safe %>
f(data.key1) \\ === 'val1'
f(data.key2) \\ === 'val2'
<% end %>