Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I'm wondering what the best practice is for passing variables to JavaScript functions in a rails view. Right now I'm doing something like:

<% content_for :javascript do %> 
  <script type="text/javascript">
    Event.observe(window, 'load', function(){          
        js_function(<%= @ruby_array.to_json %>, <%= @ruby_var %>); )}
  </script>
<% end %>

Is this the right way to go about it?

like image 957
TenJack Avatar asked Mar 17 '10 18:03

TenJack


People also ask

Can you use JavaScript with Ruby on 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.

What is VAR in Ruby?

Ruby variables are locations which hold data to be used in the programs. Each variable has a different name. These variable names are based on some naming conventions.

How do variables work in Ruby?

Ruby Class VariablesClass variables begin with @@ and must be initialized before they can be used in method definitions. Referencing an uninitialized class variable produces an error. Class variables are shared among descendants of the class or module in which the class variables are defined.


2 Answers

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

  • Injecting variable values into javascript and HAML in RoR

- content_for :javascripts_vars do
  = "var costs_data = #{@records[:cost_mode][:data].to_json}".html_safe
  = "var graph_data = #{@records[:cost_mode][:graph].to_json}".html_safe
like image 34
Vyacheslav Loginov Avatar answered Sep 21 '22 20:09

Vyacheslav Loginov