How to pass Ruby variables to a JavaScript function in a Rails view?

A few options:

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 &lt;.

<% a = "\\n<" %>
<%= javascript_tag do %>
  '<%= j(a)           %>' === '\\n&lt;'
  '<%= j(a).html_safe %>' === '\\n<'
<% end %>

to_json + html_safe

As mentioned by Vyacheslav, go upvote him.

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 %>
  data.key1 === 'val1'
  data.key2 === 'val2'
<% end %>

data- attributes

Add values to attributes, retrieve them with Javascript DOM operations.

Better with the content_tag helper:

<%= content_tag 'div', '', id: 'data', data: {key1: 'val1', key2: 'val2'} %>
<%= javascript_tag do %>
  $('#data').data('key1') === 'val1'
  $('#data').data('key2') === 'val2'
<% end %>

Sometimes called “unobtrusive Javascript”.

gon

Library specialized for the job: https://github.com/gazay/gon

Probably the most robust solution.

Gemfile:

gem 'gon'

Controller:

gon.key1 = 'val1'
gon.key2 = 'val2'

Layout app/views/layouts/application.html.erb:

<html>
<head>
  <meta charset="utf-8"/>
  <%= include_gon %>

View:

<%= javascript_tag do %>
  gon.key1 === 'val1'
  gon.key2 === 'val2'
<% end %>

See also

Leave a Comment