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?
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.
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.
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.
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 <
.
<% a = "\\n<" %>
<%= javascript_tag do %>
'<%= j(a) %>' === '\\n<'
'<%= 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
- 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With