1

I have javascripts in the Asset Pipeline that interact with specific DOM elements on a specific view. For example:

# app/assets/javascripts/book.js
...
var svg = d3.select("#book").append("svg")
...

My view /pages/book looks like:

<% content_for :head do %>
  <%= javascript_include_tag 'd3' %>
<% end %> 
<h1>Book</h1>
<div id="book"></div>
<% content_for :body do %>
  <%= javascript_include_tag 'book' %>
<% end %>

My assets.rb has:

Rails.application.config.assets.precompile += %w( d3.js )
Rails.application.config.assets.precompile += %w( book.js )

When I go to localhost:3000/pages/book it works perfectly, the SVG binds to the #book

When I start at root localhost:3000 and follow a link <%= link_to "See Book", pages_book_path %>, the DOM elements exist, the HTML renders, but the SVG does not bind to #book.

Looking in the terminal, when I go directly to localhost:3000/pages/book the Asset Pipeline is loaded and the javascript executes correctly. And when I start at root, the same thing happens, but since #book does not exist on the root view, nothing happens...and when I follow the link, the asset pipeline does not reload...

How can I get the asset pipeline to reload when the link is followed?

jdesilvio
  • 1,794
  • 4
  • 22
  • 38

1 Answers1

0

You need to make sure that your javascript asset code is wrapped in a jquery page ready and page:load like this:

$(document).on('ready page:load', function () {
  var svg = d3.select("#book").append("svg")
});

I believe turbo-links are to blame here, and that code that appends to #book is being run before there is a #book, like you were saying. To get it to run when you visit that page, I'd say the above should work for you.

Update:

If you are trying to embed svg, there are gems and custom approaches out there. I found these four sources with 2 minutes of searching online, so there is likely even better stuff you can run across that will likely get you what you need. I'd start here though:

Community
  • 1
  • 1
Jake Smith
  • 2,332
  • 1
  • 30
  • 68
  • This still doesn't work when following the link, but when I load the page directly, 2 `SVG`s append to `#book` instead of 1. – jdesilvio Oct 01 '15 at 18:26
  • okay. I was assuming there was more logic aroundt his appending, but if there isn't, then what you are seeing makes sense. Why are you relying on client side to render something after the page loads? Why not render this server side? – Jake Smith Oct 01 '15 at 21:02
  • How would I accomplish this in a basic rails app? – jdesilvio Oct 02 '15 at 13:24
  • It depends on what you are trying to do. Are you trying to use a particular font icon or something? In Rails 4, you can incorporate fonts into the asset pipeline just like javascript and stylesheets and images. Can you give me a little more detail as to what you are trying to accomplish? – Jake Smith Oct 02 '15 at 19:13