interpreting coffeescript in a layout - ruby-on-rails

I am adding some view specific .js code to the header of the page using content_for like so
<% content_for :head do %>
<script lang="text/javascript">
$.getJSON("<%= book_chapters_path(#book) %>", function(data){
});
</script>
<% end %>
now how would I switch that js code to coffescript, can I put in a code block to tell rails to convert it to javascript, or even just add "lang/coffeescript" and rails would then just handle it.

In layout:
<% content_for :head do %>
<%- javascript_tag do %>
<%= render :partial => "cs/coffee-partial" %>
<%- end %>
<%- end %>
Where cs/coffee-partial is a views/cs/_coffee-partial.html.coffee.
You can even pass local variables to render and output them into your coffee-partial:
<%= render :partial => "cs/coffee-partial", :locals => {:version => '0.1', :name => 'varName'} %>
And then:
lib =
version: '<%= version %>'
'<%= name %>': 'some value'

You can use this gem: https://github.com/markbates/coffeebeans

Related

Rails 4 show ajax loader on remote=true form submission

I'm new to rails and am having trouble figuring out where in the "magic" I can handle an event to show an ajax loader when my ajaxified form is submitted, and hide the loader when my ajax response is returned and displayed to the user.
Here's what I have, where can I add a .js file or function to bind/run on click to show the loader? I know I can remove the loader in the runCMD.js file.
Controller:
def runCMD
#cmdType = params['commit'].downcase #commit is name of submit button clicked
//do some stuff, removed for brevity...
#output = //buncha stuff that happens, but returns output of the commands ran
#outputVersions = //buncha other stuff, but sets this var
respond_to do |format|
format.js { }
end
#render 'testServer'
end
View:
<%= form_tag('/runCMD', :method => 'post', :remote => true) do %>
<%= select("versions", "version", #outputVersions) %>
<%= submit_tag "Activate", class: "run-cmd-button" %>
<%= submit_tag "Stop", class: "run-cmd-button" %>
<%= submit_tag "Start", class: "run-cmd-button" %>
<%= hidden_field_tag 'component', #component %>
<% end %>
<br />
<div id="ajax_output" contenteditable="true" style="background-color:black;font-size:10pt;font-family:Courier New;overflow-y:auto;height:1000px;width:1180px;">
</div>
.js file
$('#ajax_output').html("<%= escape_javascript(render partial: 'cmdOutput', locals: { output: #output } ) %>");
Partial
<% output.each do |line| %>
<% line.gsub! '[33m', '<font color="yellow">' %>
<% line.gsub! '[32m', '<font color="green">' %>
<% line.gsub! '[31m', '<font color="red">' %>
<% line.sub! '[0m', '<font color="white">' %>
<% line.sub! '[0m', '</font>' %>
<% line.gsub! '[0m', '' %>
<%= raw(line) %>
<br />
<% end %>
you can add your ajax loader on jquery submit form event.
$( "form" ).submit(function( ) {
$('#ajax_output').html("loading...")
});
Now on ajax success your ajax_output div html will be replaced with new content.
as per your comment, you can add it in same view where u have the form
<script type="text/javascript">
$( "form" ).submit(function( ) {
$('#ajax_output').html("loading...")
});
</script>
make sure you have jquery.

Rails render partial without entire html layout

Ok so I have a problem with rails and rendering partials. I have a layout called profile and inside of the profile layout I have all my js, stylesheets, etc included.
<html>
<head>
<title>Profile</title>
<%= javascript_include_tag "https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" %>
<%= javascript_include_tag "https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/jquery-ui.min.js" %>
<%= javascript_include_tag "application" %>
<%= stylesheet_link_tag "main" %>
<%= stylesheet_link_tag "reset" %>
<%= csrf_meta_tag %>
</head>
<body>
<%= yield %>
</body>
</html>
Inside of the yield tag(profile/index.html.erb) above is the following
<%= render :partial => 'pages/page', :layout => "layouts/default", :locals => {:page => #page } %>
Now in the pages/page view there are the same default tags such as css and js files. When i remove the css styles then I lose the styling for the pages/page view. Is there a way I can render a partial without recalling the same css and js files or what is a better way to go about doing something like so?
I always create the option to overwrite the stylesheets as follows:
<%= stylesheet_link_tag content_for?(:stylesheets) ? yield(:stylesheets) : "application", :debug => Rails.env.development? %>
Then inside a view
<% content_for :stylesheets %> some stuff or nothing in here <% end %>
That will let you specify in a view rendered in a layout you want no stylesheets and the same principle applies for javascripts.
That having been said if you are rendering a partial inside a layout that has an html tag and head etc. you should probably investigate if there is a better way to do what you are doing.
You need to pick one or the other: layout the original method call, or pass a layout to the partials. Doing both would be illogical.
There is a more thorough discussion here:
http://www.mikemayo.org/2012/rendering-a-collection-of-partials-with-content_for
I rarely see the usage of( or I am wondering if Rails support this usage... )
<!-- confirmed, this usage will cause error in Rails 3.2 -->
<%= render :partial => "some_partial", :layout => "some_layout" ... %>
I prefer to choose the specific layout in the controller:
def some_action
# some code
render :layout => "some_layout"
end
A partial is basically just a "slice of page" (like slice of cake... but in code form). It's designed to populate a small part of the page; typically one which will by dynamically updated depending on page variables.
Seems like you're confusing the purpose of layouts, views & partials in my opinion. If you want to dynamically load CSS / JS, put a "content_for" block in the profile views with a default layout, like this:
Layout
#layouts/default.rb
<html>
<head>
<title>Site Title</title>
<%= javascript_include_tag "https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" %>
<%= javascript_include_tag "https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/jquery-ui.min.js" %>
<%= javascript_include_tag "application" %>
<%= stylesheet_link_tag "main" %>
<%= stylesheet_link_tag "reset" %>
<%= yield :header_includes %>
<%= csrf_meta_tag %>
</head>
<body>
<%= yield %>
</body>
</html>
Views
#views/profiles/index.html.erb
<% content_for :header_includes do %>
<%= stylesheet "profile_custom_css" %>
<% end %>
Partial
Partials could be used to keep your code DRY & give the output of specific header files, like this:
Partial
#views/elements/_custom_header.rb
<% content_for :header_includes do %>
<% headers.each do |type, value| %>
<% if type == "java" %>
<%= javascript_include_tag value %>
<% else %>
<%= stylesheet_link_tag value %>
<% end %>
<% end %>
<% end %>
View
#views/profiles/index.html.erb
<%= render :partial => 'elements/custom_header', locals: { :headers => [["java", "profile_custom"], ["stylsheeet", "profile_custom"]] } %>
#Resume standard view code here
Layout
#layouts/default.rb
<html>
<head>
<title>Site Title</title>
<%= javascript_include_tag "https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" %>
<%= javascript_include_tag "https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/jquery-ui.min.js" %>
<%= javascript_include_tag "application" %>
<%= stylesheet_link_tag "main" %>
<%= stylesheet_link_tag "reset" %>
<%= yield :header_includes %>
<%= csrf_meta_tag %>
</head>
<body>
<%= yield %>
</body>
</html>
I've not tested passing the partial locals as a hash, so the syntax may be incorrect, but this is what we'd do to load up the required code. The added benefit is that content_for only yields content that has been defined (I.E you just have to include yield :custom_headers and it will only show if the content block is present)

Rendering content inside a partial via =yield

I'm creating an application with ruby on rails where I have an items/_item.html.erb. Inside the partial is a yield statement so i can add extra content as needed. In this case, I want to add a specific button to item depending on what view calls partial.
This is what I've tried and it renders the partial, but it does not render the block:
_item.html.erb
<%= yield if block_given? %>
<div>
<%= item.name %>
</div>
someview.html.erb
...
<% render(:partial => 'items/item', :collection => current_user.items do %>
<%= "HELLO" %>
<% end %>
...
I have also tried using content_for and some other stuff with no success. Is there a way to be able to render specific content inside a partial via yield? I'm currently using Rails3
EDIT:
I've found out that it's the :collection hash that makes it impossible insert the block.
Both of this pieces of code work:
<%= render :layout => 'items/item' do %>
Hello world
<% end %>
<%= render :layout => 'items/item', :locals => {:item => current_user.items.first} do %>
Hello world
<% end %>
This means that if i do a .each i could accomplish what I want but it would be ugly code. Anyone know a way around this?
content_for should work fine in this case. Here is the code I just double checked locally.
somewhere.html.erb
<% content_for :foobar do %>
fubar
<% end %>
_item.html.erb
<% if content_for? :foobar %>
<%= yield :foobar %>
<% end %>

How to merge multiple partial templates into one file?

I'm using Ruby on Rails 3 to create my web app.
I don't want to create a template file for each tiny partial template so I tried to merge them into one file using content_for method but it doesn't works.
My ERB template files are as follows.
layout/_fragments.html.erb: contains contents of some partial templates
<% content_for :twitter_checkbox do -%>
<% can_post_twitter = current_user && current_user.twitter_oauth %>
<% label_text = can_post_twitter ? "Post to Twitter" : "Set up your Twitter account" %>
<%= label_tag :twitter, label_text %>
<%= check_box_tag :twitter, 0, false, :disabled => !can_post_twitter %>
<%- end %>
<% content_for :other_content_of_partial_template do -%> # content of another partial template
...
layouts/application.html.erb
<!DOCTYPE html>
<html>
...
<body>
<%= yield %>
</body>
</html>
<%= render 'layouts/fragments', :formats => :erb %>
layouts/_form.html.erb
<%= form_for(#entry) do |f| %>
...
<%= content_for :twitter_checkbox %> # it shows nothing
<% end %>
What is wrong with this way?
Are there any other better ways to write multiple partial templates into one file?
I suppose you have run the _form partial before your main layout had the chance to run the _fragments partial, so when you display the fragments, they are not yet created.
The action is rendered before the layout, not after. Calling the _fragments from your action instead of from layout should make it clear whether this is the problem. At least, I believe so ;-)
You're missing the = sign in the second snippet which would tell Rails to display the returned text.
<%= form_for(#entry) do |f| %>
...
<%= content_for :twitter_checkbox %> # Note <%= - it should now show stuff
<% end %>

Rails - how to insert/render a file inside a View

in index.html.erb, I would like to know how to insert index.js.erb, something like:
<script type="text/javascript">
$(function() {
<%= render =>"home/index.js.erb" %>
});
</script>
Any ideas on how to just insert the index.js.erb file ?
thanks
<%= File.read "#{RAILS_ROOT}/app/views/home/index.js.erb" %>
Set your file as a partial and append preprend or do what you wana do with it.
For a partial file named _index.js.erb located in the same folder of where the file with this code is called will be prepend in the DOMID exemple.
jQuery('#exemple').prepend("<%= escape_javascript(render(:partial => 'index')) %>");
Maybe you can do a html file with it...
<% javascript_tag do %>
<%= render :partial => 'index' %>
or direct code
<% end %>

Resources