By TenJack


2010-03-17 18:44:45 8 Comments

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?

6 comments

@Brad Parks 2019-02-20 13:22:27

Note that if you aren't using escape_javascript in a view, you can include it in your ruby code like so:

require 'action_view/helpers/javascript_helper'
include ActionView::Helpers::JavaScriptHelper
# escape_javascript is available here.

or if that wont work for you, then copy the source of the function in to your code, if need be:

  JS_ESCAPE_MAP = {
    '\\'    => '\\\\',
    "</"    => '<\/',
    "\r\n"  => '\n',
    "\n"    => '\n',
    "\r"    => '\n',
    '"'     => '\\"',
    "'"     => "\\'"
  }

  JS_ESCAPE_MAP["\342\200\250".dup.force_encoding(Encoding::UTF_8).encode!] = "&#x2028;"
  JS_ESCAPE_MAP["\342\200\251".dup.force_encoding(Encoding::UTF_8).encode!] = "&#x2029;"

  # Escapes carriage returns and single and double quotes for JavaScript segments.
  #
  # Also available through the alias j(). This is particularly helpful in JavaScript
  # responses, like:
  #
  #   $('some_element').replaceWith('<%= j render 'some/element_template' %>');
  def escape_javascript(javascript)
    if javascript
      result = javascript.gsub(/(\\|<\/|\r\n|\342\200\250|\342\200\251|[\n\r"'])/u) { |match| JS_ESCAPE_MAP[match] }
      javascript.html_safe? ? result.html_safe : result
    else
      ""
    end
  end

@shilovk 2015-10-09 10:36:36

In HAML can data are presented so:

.position{data: {latitude: @claim.latitude.to_json, longitude: @claim.longitude.to_json}}

:javascript
   var latitude = $('.position').data('latitude');
   var longitude = $('.position').data('longitude');

@Ciro Santilli 新疆改造中心法轮功六四事件 2014-06-27 16:38:22

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

@MQuy 2013-09-16 07:11:57

I found that gem client variable, it helps you to do it easily.

@Radim Köhler 2013-09-16 07:31:17

Please, try to read this stackoverflow.com/help/deleted-answers, to get more understanding how to not answer. Namely: "Answers that do not fundamentally answer the question": barely more than a link to an external site

@Vyacheslav Loginov 2012-09-26 12:55:51

- 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

@Zepplock 2010-03-17 18:51:18

There's a technique called "unobtrusive javascript". Here's a Railscast about it: link text . It works both with prototype an jQuery. There are also plugins that can help simplify some of the tasks described in the article.

Related Questions

Sponsored Content

42 Answered Questions

[SOLVED] How do I remove a property from a JavaScript object?

48 Answered Questions

93 Answered Questions

[SOLVED] How do I remove a particular element from an array in JavaScript?

  • 2011-04-23 22:17:18
  • Walker
  • 6249437 View
  • 7806 Score
  • 93 Answer
  • Tags:   javascript arrays

58 Answered Questions

[SOLVED] How do I include a JavaScript file in another JavaScript file?

89 Answered Questions

[SOLVED] How to validate an email address in JavaScript

20 Answered Questions

[SOLVED] How do you use a variable in a regular expression?

  • 2009-01-30 00:11:05
  • JC Grubbs
  • 701079 View
  • 1284 Score
  • 20 Answer
  • Tags:   javascript regex

38 Answered Questions

[SOLVED] How do you get a timestamp in JavaScript?

86 Answered Questions

[SOLVED] How do JavaScript closures work?

4 Answered Questions

19 Answered Questions

[SOLVED] Is it possible to apply CSS to half of a character?

  • 2014-05-09 16:16:57
  • Mathew MacLean
  • 237550 View
  • 2746 Score
  • 19 Answer
  • Tags:   javascript html css

Sponsored Content