Johan Johan - 3 months ago 79
CoffeeScript Question

Unexpected behavior with masonry effect on rails 4

I got inspiered by Makenzie Child video and github repo to create a masonry effect on my rails app.

I have a little problem, when I visit the page, the behavior is not the expected one, all the boxes are below each others, and if I reload they take the good behavior... I would like that the good behavior could display when we arrive on the page.

I don't know any javascript please dont be mad at me :)

this is the

$ ->
$('#progresses').imagesLoaded ->
itemSelector: '.box'
isFitWidth: true


//= require jquery
//= require bootstrap-sprockets
//= require jquery_ujs
//= require masonry/jquery.masonry
//= require turbolinks
//= require_tree .


|Work In Progress [
= @progresses.count
| ]
- @progresses.each do |progress|
= link_to (image_tag progress.main_image.url), progress
h4.text-gold = progress.title.upcase
h5 =
small = truncate(progress.content, length: 150)

Thanks for your help,



The fact that it works when you reload the page makes me suspect this is a turbolinks problem.

Turbolinks makes following links in your web application faster. Instead of letting the browser recompile the JavaScript and CSS between each page change, it keeps the current page instance alive and replaces only the body and the title in the head.

So you'll visit the page using a link within your application, the javascript doesn't reload. But when you do a refresh on the page, everything is fetched again including the javascript causing the script to execute.

Solution 1

This also means things like $(document).ready(function(){ won't work because this only fires on initial load. Try something like this out:

ready = ->

  $('#progresses').imagesLoaded ->
    itemSelector: '.box'
    isFitWidth: true

$(document).on('page:load', ready)

I'm assuming you're using rails 4, this won't work in rails 5. I've used the following question for information and there are ways described to do this in rails 5: Rails 4: how to use $(document).ready() with turbo-links

Turbolinks will trigger the page:load event when a new page is loaded.

Solution 2

Another solution might be using jquery-turbolinks gem.

It's easy to use. Add gem 'jquery-turbolinks' to your gemfile. Then add //= require jquery.turbolinks to your application.js. This has to go between //= require jquery and //= require jquery_ujs. So in your case:

//= require jquery
//= require jquery.turbolinks
//= require bootstrap-sprockets
//= require jquery_ujs
//= require masonry/jquery.masonry
//= require turbolinks
//= require_tree .

If any of this doesn't work, you might want to disable turbolinks for a moment to see if turbolinks is actually the problem. You can do this by replacing the <body> tag in your application.html.erb with the following: <body data-no-turbolink="true"> Just note that disabling turbolinks for your whole application isn't something you'll want. There are clean solutions to disable it for a specific page.


If the following solution works for you, you can try this instead of the code I gave in solution 1:

$(document).on('turbolinks:load', function() {

  ...your javascript goes here...


In my opinion this is a lot cleaner and I've read that it should work from rails 4.2 and above. Notice the difference: turbolinks:load instead of page:load.