Newbie Post: Rendering javascript views in Rails

I’ve found the Rails method of “remote => ‘true’” to be extremely useful. In most of my website designs, a user action (such as clicking a button), will generate a modal and prompt the user for further action. In both HTML frameworks I’ve used (bootstrap and foundation), the modals are triggered by javascript. This fits in nicely with the Rails remote attribute, since this causes the browser to send an ajax request, and expect a javascript reply…. as per the rails documentation

For example, if we create a hyperlink using the “link_to” rails helper like so:

<%= link_to “Create a new conference room >> “, {controller:”user” , action:”number”}, remote:”true”, class:”button” %>

This will create HTML code as follows:

<a data-remote=”true” href=”/user/number”>Create a new conference room &gt;&gt; </a>

Not the HTML5 data attribute “data-remote” being set to “true”. When this link is clicked, an AJAX request is sent, and pure javascript should be returned. For an experienced developer, it is trivial to use render js: and write javascript code directly within the controller. But this has certain disadvantages:

  • Not exactly rails conforming… you should leave rendering to views and controllers to controlling logic
  • Even if you code javascript directly into the controller and render it, you cannot use rails html helpers. One scenario when this is a bummer would be when you would like to return a form via javascript. Normally Rails expects a CSRF token to be included in each form. When a form is built using html helpers, this token is included automatically. When using your own code, this token will be missing, leading to errors

The solution is to still use render within your controller, but use it to render a *.js.erb file rather than the normal .html.erb file. So for example, to server the link above, we create a method for “number” in the controller “user” and use render like so:

def number
render “numberForm”
end

We then create a numberForm.js.erb in the app/views/user/ directory and fill it in using javascript and html helpers, for example:

$(‘#modalBody’).html(‘<%= form_tag (“/conference_opts/newConference”),({:remote=>true}) do %><%= text_field_tag “confName”, nil, placeholder: “Enter a conference name” %><%= text_field_tag “confNumber”, nil, placeholder: “Enter a two number conference number” %><%= text_field_tag “confPIN”, nil, placeholder: “Enter a conference PIN” %><%= submit_tag “Create Conference”, class: “button”, style: “float:right;” %><% end %>’);
$(‘#CreateModal’).foundation(‘reveal’, ‘open’);

Note the use of the form_tag html helper to safely generate the html form from within javascript.