Injecting variable values into javascript and HAML in RoR
This should work ie. put all inline ruby inside of #{}
:
requester_name: "#{current_user.first_name + ' ' + current_user.last_name if current_user}",
requester_email: "#{current_user.email if current_user}",
Direct #{}
works for simple strings, but is not the most scalable / safe solution in general.
For example, the literal backslash in Ruby would cause you problems in Javascript where it will be interpreted as a newline character:
- a = "\\n"
:javascript
'#{ a }' !== "\\n"
From this awesome Rails cast, the following techniques can be used:
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.
Maintain html_safe
status of input,
so needs html_safe
otherwise special HTML chars like <
would get escaped into <
.
- a = "\\n<"
:javascript
'#{ j(a) }' === '\\n<'
'#{ j(a).html_safe }' === '\\n<'
to_json + html_safe
Works because JSON is almost a subset of Javascript object literal notation.
Works on any hash object, including strings, arrays and integers which are converted to JSON fragments of the corresponding data type.
- data = { key1: 'val1', key2: 'val2' }
:javascript
data = #{ data.to_json }
data.key1 === 'val1'
data.key2 === 'val2'
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
$('#data').data('key1') === 'val1'
$('#data').data('key2') === 'val2'
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
gon.key1 === 'val1'
gon.key2 === 'val2'