Rendering a partial via coffeescript prints literal - ruby-on-rails

I'm trying to render a partial from coffeescript when a button is clicked, so I have one of my coffeescript files "script.js.coffee" with the following code:
$('[id^="btn_add_rep_dia_"]').click ->
id = this.id.substring(16)
$("#dia" + id).append("<%= j render('repeticions/form') %>")
But what's happenning is that at the end of $("#dia" + id) appears litterally the text "<%= j render('repeticions/form') %>". The partial is located in "repeticions" folder and it's called "_form.html.haml"
I have also tested the last code line as:
$("#dia" + id).append("<%= escape_javascript( render partial: 'repeticions/form') %>")

You are trying to execute an erb (embedded ruby) template inside a .coffee file. Rails doesn't know that it should pre-process the file before sending it to the client.
If you are using a Rails version > 3.2, then simply renaming your coffeescript file from script.js.coffee to script.js.coffee.erb should be enough to instruct rails to interpret the erb style template strings (<%...%>).

You can't render a partial from a plain coffeescript file. If you wanted to do this approach, I suggest turning that button into a link_to with remote: true which will enable you to use ajax in rails.

Related

Integrate ruby variable into a js

How I can integrate ruby variable into a js file. I would like to render a partial relative to the current step of registration of my User.
But I can't succeed it, Rails do not translate #flat.current_step in his value (which is a integer). Any ideas ?
$('.flats').replaceWith("<%= j render partial: 'flats/steps/step#{#flat.current_step}' %>");
Error
ActionView::Template::Error (Missing partial flats/steps/_step#{#flat.current_step}
Ruby does not interpolate the #{} when wrapped in single quotes. Change your call to:
$('.flats').replaceWith('<%= j render partial: "flats/steps/step#{#flat.current_step}" %>');

Rails path-helpers doesn't work in js.coffee.erb

In my Rails 3.2 app (Ruby 1.9) I get following error when using path helpers in Coffeescript.
undefined local variable or method `new_user_session_path'
In my partial _usermenu.html.haml that works fine:
= link_to t('user.login'), new_user_session_path
In my app/assets/javascripts/metamenu.js.coffee.erb that throws above error:
$.get("<%= new_user_session_path %>")
Isn't it possible to use x_path and x_url helpers in coffeescript erb's?
This is because you are not within the view context inside of your assets. Adding an erb extension to the file doesn't change this, it simply allows you to evaluate embedded ruby.
If this is a one-off scenario, your best bet is to simply use the string itself.
$.get("/sign_in")
If you really wanted to you could create a partial that output a script tag that output your helper methods into js variables and access them that way.
# in your layout
<%= render 'url_helpers' %>
# in app/views/layouts/_url_helpers.html.erb
<script>
window.new_user_session_path = "<%= new_user_session_path %>";
# add more if necessary
</script>
# in your coffeescript
$.get(#new_user_session_path)
Also worth keeping in mind that this will obviously never work for member routes where your passing an instance of a model to the url helper as that is definitely not available to coffeescript. Remember, in production assets are precompiled so you can't use anything dynamic. For that you can only really rely on setting up actions in your controller to respond to JS calls.
Old post, but still accessible from Google.
In rails 4 (and certainly at least 3 too) you can use the route helpers to insert your js files easily:
assets/javascript/my_file.js.coffee.erb
<% self.class.include Rails.application.routes.url_helpers %>
window.index_route = '<%= index_path %>'

How to use rails code / pass variables to a .coffee javascript file?

What would be the best way to pass values inside a .coffee script? Renaming the file to .erb breaks my app so what are the alternatives?
checkout this rails guide. this section : 2.3.3 JavaScript/CoffeeScript and ERB
You can use rails code in .coffee-script file. It's built-in feature.
2nd Edit___
If the file is in assets pipeline then you need to add .erb extension at end of coffee file so that the rails tag works otherwise there is no need to add .erb extension if you moves the file in views folder rails tag works there.
You can either (1) move the file into your app/views directory (so it won't be in the asset pipeline), or (2) pass the information via query string.
(1) app/views/users/script.js.coffee.erb
var username = <%= #user.name %>
(2) I'm using this function
<%= link_to "User", user_path(#user, :username => #user.name) %>
...
var username = getParameterByName('username')
Untested but this is the general idea.

Can I use CoffeeScript in the views executed on render.js?

What do I need to do so that I can use CoffeeScript in the Rails JS views? For example:
def index
format.js { render :layout => false }
end
What would I need to do in order for Rails to use index.js.coffee?
Johnny's answer is correct. If you look at the pull request linked to from the CoffeeBeans page, you have dhh saying
Once we have a fast, clean implementation, it's welcome in core. 3.2 is a more likely target, though.
I briefly talked with Sam Stephenson and Josh Peek about this at Railsconf, since this was a missing feature people had asked me about after my CoffeeScript talk. After all, Rails 3.1 is pushing CoffeeScript as a default pretty hard; it seems odd that there are places where pure JS has to be used. Sam's reaction was that this wouldn't be efficient, because you'd have to fire up the CoffeeScript compiler on every page request, even in production. That's because code like
<%= coffee_script_tag do %>
alert "coffee script is #{verb}!"
<% end %>
creates an ERB interpolation (not a CoffeeScript interpolation—unfortunate that both use the same syntax), potentially yielding a different string of CoffeeScript code on every request. And there's no way to tell, from the coffee_script_tag implementation, whether the given code is going to be the same every time (i.e. whether there's an ERB interpolation or not).
Now, the CoffeeScript compiler is very fast, but compiling to JavaScript is still going to add a little extra time to each request. So the Rails team is hesitant to encourage the practice.
For the sake of efficiency, and to avoid the ambiguity between ERB interpolations and CoffeeScript interpolations, you should probably keep your CoffeeScript somewhere (perhaps as a .coffee file in the same directory as your view) and compile it to JavaScript by hand.
It's not yet supported in 3.1. You will need to use Coffeebeans.
Update: It is now supported in rails 3.2
This is now working in Rails 3.2. For example, I have a resource named book. This resource has a file at app/views/books/index.html.erb with the following:
<%= link_to 'test me', new_book_path(color: 'blue'), remote: true %>
Then I have a file at app/views/books/new.js.coffee at ≈ with the following code:
test = ->
'this is a test'
console.log test()
console.log( "<%= params[:color] %>" )
I see:
'this is a test'
'blue'
in my browser console.
if you dont want to install coffeebeans, heres a sort of quick and dirty way to do it by hacking into the erb outputter a bit :
<%
require 'coffee-script';
def coffee_script; CoffeeScript.compile yield '' end %>
<script type="text/javascript">
<% compiled = coffee_script do |_erbout|%>
->
console.log 'works! this part is coffeescript!'
<% end %>
<% _erbout.concat compiled %>
</script>

Embedding an ejs template inside of an erb template

I'm building a javascript-heavy rails 3 app. It uses underscore.js, which has a very elegant templating mechanism built on top of ejs ( http://embeddedjs.com/).
The problem: embeddedjs borrows heavily from the erb syntax, so including ejs templates in an erb template causes rendering problems with the view.
Is there a way to include "non-erb" sections in an erb file? This would let me define ejs templates inside erb files. Right now I'm using a hack where I have a helper that reads the raw contents of a file containing ejs templates, and outputting that as a raw string in the erb template.
I use this trick to solve the problem:
// Using custom tags to be able to use regular for templates in templates
var ejs = require('ejs');
ejs.open = '{{';
ejs.close = '}}';
// Using html extension for custom ejs tags
app.register('.html', ejs);
app.set('views', __dirname + '/views');
app.set('view engine', 'html');
This changes <% %> to {{ }}, and let me use <% %> for templates which are used by JS. This works for me as I don't have classic style templates (<% %>).
If you have a lot of those you may want to do the same trick but for underscore.js templates.
You could save ejs as a seperate file and than render it as a text (which won't be evaluated as erb) inside script tag.
Inside your erb partial:
<script id="my_awesome_template" type="text/x-ejs">
<%= render :text => File.open("app/views/controller_name/_my_awesome_template.html.ejs").read %>
</script>`
In your JavaScript file:
new EJS({element: document.getElementById('my_awesome_template')}).render(data)
Escape your Underscore variables: (The ones you do not want erb to interpolate)
<%= foo %> becomes:
<%%= foo %>

Resources