Including D3 in an ERB loop - javascript

I have a partial called _index.html.erb
<% metric_objects.each do |metric_object| %>
<% if metric_object.histogram.has_key? 0 %>
<%= javascript_include_tag 'iterative_metric_graph.js', metric_object %>
<% else %>
<!--Another type of graph-->
<% end %>
<% end %>
It is supposed to generate a D3 bar graph for each metric_object. When I open the page, I get the error "D3 is not defined" in the console.
iterative_metric_graph.js is a file in my app/assets/javascripts/active_admin folder.
It consists of the javascript code from this page: http://bl.ocks.org/mbostock/3943967 Nothing more than what is inside the script tags right now.
The issue is that D3 is not being included in iterative_metric_graph.js. I could resolve the error by putting the javascript graph code (from the link above) straight into _index.html.erb, and adding <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>, but I would much prefer to render a partial. How can I include D3 (from the web or from a file) in my javascript file?

To include D3 you can just download it and stick it in you app/assets/javascripts directory. Then add the following to your application.js file:
//= require d3.v3.min
Alternatively you could try to put it in vendor/assets/... but there's a little more work involved in getting that to play nice with the asset pipeline. (more info here: Rails asset pipeline: Standard way for including all /vendor/assets/javascripts/?)

Related

Wicked PDF and Javascript loading

I have tried a number of methods to load jQuery and Google Maps API in to my Wicked PDF generator. I am trying to load an image of an address in the PDF. I seem to have an issue with the javascript tag not working.
pdf.erb file:
<html>
<head>
<%= stylesheet_link_tag "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" %>
<%= javascript_include_tag "application" %>
<script src="https://maps.googleapis.com/maps/api/js?key=######"></script>
<%= csrf_meta_tags %>
</head>
<body>
controller file:
respond_to do |format|
format.html
format.pdf do
render :pdf => "location",
:template => "pdf_generation/location_show.pdf.erb",
:javascript_delay => 5000,
:show_as_html => params.key?('debug')
end
end
show.html.erb file:
<div class='row'>
<div class='col-lg-12'>
<div class='ibox float-e-margins'>
<div class='ibox-title'>
<%= link_to 'Edit', edit_location_path(#location), class: 'btn btn-default' %>
</div>
<div class='ibox-content'>
<iframe src="<%= location_path(#location) %>.pdf" style="width:100%; height:700px;" frameborder="0"></iframe>
</div>
</div>
</div>
</div>
I have tried debugging with no success. I may not understand the debugging method for this.
Now I have also tried loading jQuery min file from the CDN and also tried wicked pdf javascript include tag. When I try either of these approaches I get the following error:
Failed to execute: ["/usr/local/rvm/gems/ruby-2.2.1/bin/wkhtmltopdf", "-q", "--javascript-delay", "5000", "file:////tmp/wicked_pdf20171005-21437-hwy6l4.html", "/tmp/wicked_pdf_generated_file20171005-21437-gop4gw.pdf"] Error: PDF could not be generated! Command Error: Fontconfig warning: ignoring C.UTF-8: not a valid language tag Error: Failed loading page file:////tmp/wicked_pdf20171005-21437-hwy6l4.html (sometimes it will work just to ignore this error with --load-error-handling ignore) Exit with code 1, due to unknown error.
I could really use some guidance. I have not been able to get any javascript files to load. CSS files have been a little difficult to, for instance if I try to load a local scss file it typically just won't load, it seems to just ignore it.
(ie stylesheet link tag 'application' )
EDIT
I found the offending code. the FontConfig warning had nothing to do with the loading of any resource. It related to this code that I had been using to pass ruby variables to javascript:
var location = jQuery.parseJSON( '{"main": "<%= #location.main %>", "lat": <%= #location.lat %>, "lng": <%= #location.lng %> }');
I have modified the google map to show in the PDF now, however what I did isn't DRY, and it makes me think there is another way to pass the ruby variable to my javascript code. Any thoughts or pointers?

Using Rails, how do I execute a javascript file on a specific page in the application?

I am attempting to load a javascript file onto my rails application, but only for a specific page in my application, not the homepage. How would I get my javascript file to load for a specific page is using rails.
The javascript I have now, located in programs.js in assets/javascript, looks like this:
document.addEventListener('DOMContentLoaded', (event) => {
let program = document.getElementsByClassName('program-name')
console.log(program)
})
Again, the code itself works fine. The problem is that it executes for the homepage, and not for any particular page that I want it to. How would I go about getting the code to execute for a specific page within my rails application?
Why wouldn't you add the javascript tag to the View you want it to run on?
If you wanted a bit better rendering speed, you could add a end-of-page yield to your layout and then specify your javascript in the View like this:
layout/application.html.erb
<!DOCTYPE html>
...
<%= yield(:scripts) %>
</body>
</html>
view/.../index.html.erb
<!-- regular view code here -->
...
<% content_for :scripts %>
<%= javascript_tag do %>
document.addEventListener('DOMContentLoaded', (event) => {
let program = document.getElementsByClassName('program-name')
console.log(program)
});
<% end %>
<% end %>
An other way is to do the following:
app/views/layouts/application.html.erb
<body class="<%= controller_name %> <%= action_name %>">
<!-- This will add your page's controller and action as classes, for example, "blog show" -->
Then, in your script file, you can do the following:
if($('body').is('.yourcontroller.youraction'){
// Do something
}

The right way to include page-specific JavaScript in Rails

I want to include this, for example:
jQuery(document).ready(function($) {
$('#my-modal').modal(options)
});
In one specific place in a rails app. In my case the file is called views/modals/mymodal.html.erb. There and only there.
I can't figure out how to do that without getting it on all pages as would happen if I put it in assets.
These are some useful tricks
#1 with file js
Create file your.js for your javascript
call file your.js on specific your layout
remove //= require_tree . on application.js
add your.js to asset percompile on config/application.rb : config.assets.precompile += %w( your.js )
#2 put into specific file non layout (not recommended)
put your js script with javascript tag on mymodal.html.erb
#3 use if..else..
put your js script into layout/yourlayout.html.erb and use if.. else.. logic.
example :
<% if current_page?(yourspecific_path) %>
<script language="text/javascript">
your javascript here ..
</script>
<% end %>
Read more here about current_page?
Or use request.fullpath to get current full path
example :
<% if request.fullpath == yourspecific_path %>
<script language="text/javascript">
your javascript here ..
</script>
<% end %>
Read more here about request.fullpath
Also you can combine #1 and #3 if you want script put into file .js
cheers
Given the JS file you want to include is named my_modal.js:
Place your JS files placed in assets/javascripts in some directory inside of
assets/javascripts, for example application.
Change line //= require_tree . to //= require_tree application in your application.js (it prevents loading my_modal.js on every page).
Place your my_modal.js in assets/javasctripts
Add my_modal.js to config.assets.precompile array (config assets.precompile += ['my_modal.js']) in your application.rb.
Put javascript_include_tag 'my_modal' in the view you want this file included
You can go to Rails guides for reference.
One of the solution is to insert our javascript in to its own file: Reference Link
For example :
// app/assets/javascripts/alert.js
alert("My example alert box.");
And including this file only in the view we want it to execute:
<%# app/views/page/contact.html.erb %>
<%= javascript_include_tag "alert" %>
<h1>Contact</h1>
<p>This is the contact page</p>
And don’t forget to include your new file in the list of files to be compiled:
# config/environments/production.rb
config.assets.precompile += %w( alert.js )
Late to the party, but for anyone viewing this today I think I've come up with something better.
Punchbox Gem for Rails
With this, you can write code like:
class Post {
controller() {
// Runs on every action
}
index() {
// Runs on just the index action
}
}
Punchbox.on('Posts', Post);
(You can also create an object instead of a class. See the docs)
I've written about this much more in depth here: https://kierancodes.com/blog/page-specific-javascript-in-rails-4
jquery-readyselector is a plugin that "Extends $().ready() to provide a convenient syntax for page-specific script"
Install jquery-readyselector
Create some CSS classes
<body class="<%= controller_name %> <%= action_name %>">
Scope your javascript to your page
$("#my-modal").ready(function() {
$('#my-modal').modal(options)
});
More info in this answer How to load page specific rails 4 js files?

Gon doesn't work with .js files in Sinatra

In my head within layout.erb I included <%= include_gon %>
In main.rb I have written
require 'gon-sinatra'
Sinatra::register Gon::Sinatra
gon.test = "Test"
puts gon.test
The console outputs Test as expected.
However when I create a .js file and write something like console.log(gon.test) and I look in Firebug or Chrome Console, it says Reference Error: gon is not defined. Why is this happening? What should I do to fix this?
It turns out I have written <script><%= include_gon %></script> which makes it fail. <%= include_gon %> shouldn't be written inside <script> tags.

In Ruby on Rails, how to make HTML as partials in one file and Javascript in another file to be included last?

A lot of time, in a partial, the HTML (or ERB or HAML) as well as the Javascript is in one file, so when the main file includes these partials, the HTML will be intermixed with Javascript code.
However, it is said that for fast page content display, all Javascropt code should be placed at the end of the HTML file. In this case, is there a proper or standard way to make this happen? Perhaps using 1 partial as HTML, and 1 partial as Javascript, and include 2 different partials (the HTML as the correct place, and the Javascript near the end of the file?)
(This is related to If Javascript code block is not at end of HTML file, but is using jQuery's $(document).ready(function() {...}), will it slow down the page display? )
In your layout file you could put a footer into which you can load your Javascript (typically stuff like analytics that don't need to be loaded early). Then define a content_for in your views which includes your Javascript partial. The result is that that Javascript will be placed at the end of the page.
In the layout:
<div id="footer">
<%= yield :footer %>
</div>
In your views/paritals:
<% content_for :footer %>
<script type="text/javascript">
// Some Javascript
</script>
<% end %>
or
<% content_for :footer %>
<%= render :partial => "path_to_some_javascript" %>
<% end %>

Categories

Resources