Second container does not load jquery masonry in my rails app - ruby-on-rails

I am trying to display my posts organized by date created. Jquery Masonry works fine for the first container, but for the second container it fails to properly load. When I view the code in a web browser it shows this for the second container:
<div id="pins" class="transitions-enabled">
<div class="box panel panel-default">
</div>
</div>
when it should show this (content display for the first container):
<div id="pins" class="transitions-enabled masonry" style="position: relative; height: 247px; width: 448px;">
<div class="box panel panel-default masonry-brick" style="position: absolute; top: 0px; left: 0px;">
</div>
</div>
app/assets/javascripts/pin.js.coffee:
$ ->
$('#pins').imagesLoaded ->
$('#pins').masonry
itemSelector: '.box'
isFitWidth: true
views/pins/index.html.erb:
<%= render 'pages/home' %>
<div id="pins-container" class="container">
<% #pins_by_day.each do |day, pins| %>
<h5 align="center"> <%= day.strftime('%B %d, %Y') %> </h5>
<div class="well well-sm">
<div id="pins" class="transitions-enabled">
<% for pin in pins %>
<div class="box panel panel-default">
<%= link_to pin %>
<div class="panel-body">
<p>
<%= pin.description %>
</p>
</div>
</div>
<% end %>
</div>
</div>
<% end %>
</div>
I would appreciate it if someone could explain how to properly load jquery masonry for multiple containers on my page. The first section is loading properly, but the second container is just a single column.

HTML doesn't like it when you have more than one id per page. And jQuery will only find the first one. So if you're ever iterating over a partial or a template, make sure that you either don't use ids, or have the id be dynamic.
So instead of id="pins" try:
<div class="masonry-pins transitions-enabled">
And
$ ->
$('.masonry-pins').imagesLoaded ->
$('.masonry-pins').masonry
itemSelector: '.box'
isFitWidth: true
Also, I imagine inside imagesLoaded callback, you have access to the element at this? Instead of calling $('.masonry-pins').masonry you might just want to call $(this).masonry

Related

Iterating with rails and using bootstrap to get cards to display in columns of 3?

I am trying to get iterate through rails to create cards that grid in 3 then new line etc using each. Currently the cards only stack vertically. I would like them to be in columns of 3 and then resize to stack when the screen is made small.
Currently my code looks like this:
https://i.imgur.com/mnbDIl5.png
And when I make my screen smaller it appears to go to a 3x3 like this:
https://i.imgur.com/G2T9leW.png
Could anyone please help/suggest where I am going wrong?
Currently using Bootstrap v5.2.2
Thanks in advance!
<div class="card text-center text-white row row-cols-3 row-cols-md-3" style="background-color:#ffa82e00;">
<% #drinks.each do |drink| %>
<div class="col-md-3">
<div class="card photo" class="card-img-top">
<%= cl_image_tag drink.photo.key, height: 350, width: 350, crop: :fit if drink.photo.attached? %>
<div class="card-body">
<h5 class="card-title"><%= link_to drink.name, drink_path(drink) %></h5>
<p class="card-text">Price: £<%= drink.price %></p>
<button type="button" class="btn btn-primary"><%= link_to "Buy now", new_drink_order_path(drink) %></button>
</div>
</div>
</div>
<% end %>
</div>
The cards only stack 1 by 1 no matter the viewport size, and my novice knowledge of bootstrap is hindering me from getting them to display in columns of 3.
Try this:
<div class="row">
<% #drinks.each do |drink| %>
<div class="col-12 col-lg-4">
<div class="card text-center text-white" style="background-color:#ffa82e00;">
<div class="card photo" class="card-img-top">
<%= cl_image_tag drink.photo.key, height: 350, width: 350, crop: :fit if drink.photo.attached? %>
<div class="card-body">
<h5 class="card-title"><%= link_to drink.name, drink_path(drink) %></h5>
<p class="card-text">Price: £<%= drink.price %></p>
<button type="button" class="btn btn-primary"><%= link_to "Buy now", new_drink_order_path(drink) %></button>
</div>
</div>
</div>
</div>
<% end %>
</div>
You can wrap cards in the grid like that. This will make a grid of 3 cards wide on lg screens and above then reduces down to 1 column below that.
The loop also changed slightly to more correctly duplicate the card itself, and not extra code.
https://getbootstrap.com/docs/5.2/layout/grid/
The docs above explain the columns in a bit more detail. Version 5.2 automatically handles wrapping columns after 12 columns are exceeded, so this should be all you need!

4 graphs for each user, need to show the fourth graph in different layout

In my app each user has 4X graphs to display.
I'm displaying 3X col-md-4 graphs for each user through the each loop below.
This code is in my view.
<div class="row">
<div class="container">
<% #user_overviews.each do |overview| %>
<div class="col-md-4 text-center">
<h4><%= overview.title %></h4>
<%= raw overview.graph%>
</div>
<% end %>
</div>
</div>
the problem is that I need to be able to show a fourth graph below the other three graphs in a col-md-12.
I'm using active admin to upload the graphs, so the four graphs for user 1 have ID 1,2,3,4 and the next four graphs for user 2 have ID 5, 6, 7, 8 and so on.
So in graph 4 and 8 are the once that should be displayed in the col-md-12
I find it hard to get around how I can display graph 4 and 8 in a col-md-12
can someone advise me on how I would do that?
First of all (unless I'm missing something), the row div should be the child of the container div.
Given that the overviews will always be of fixed sized 4, try using the each_with_index method as shown below:
<div class="container">
<div class="row">
<% #user_overviews.each_with_index do |overview, index| %>
<div class="col-md-<%= index == 3 ? '12' : '4' %> text-center">
<h4><%= overview.title %></h4>
<%= raw overview.graph%>
</div>
<% end %>
</div>
</div>
If each user has exactly 4 overviews, probably a simple solution is to iterate over all except the last one and then put another row for the last overview. You will need another row anyway if you want to have col-md-12.
Also, I think the container div has to wrap everything else.
Something like this maybe:
<div class="container">
<div class="row">
<% #user_overviews[0...-1].each do |overview| %>
<div class="col-md-4 text-center">
<h4><%= overview.title %></h4>
<%= raw overview.graph %>
</div>
<% end %>
</div>
<div class="row">
<div class="col-md-12 text-center">
<h4><%= #user_overviews.last.title %></h4>
<%= raw overview.graph %>
</div>
</div>
</div>
Edit: Lazarus' solution is more DRY, so I think it's better.

Bootstrap does not work as it should on my Rails App

I'm trying to create a two column layout. The first side should span 9 columns and the next one 3. Inside the col-md-9 I want to nest two more columns, one that spans 4 and another one that spans 8.
<div class="row">
<% #huddles.each do |huddle| %>
<div class="col-md-9">
<div class="row">
<div class="col-md-4">
<img class="img-responsive" src="http://placehold.it/300x150">
</div>
<div class="col-md-8">
<h4><%= huddle.title %></h4>
<h4 class="huddle-description"><%= huddle.description %></h4>
<%= link_to "Read More...", huddle_path(huddle) %>
</div>
</div>
<% end %>
</div>
<div class="col-md-3">Second Column</div>
</div>
This however, comes out looking like this:
Am I nesting my rows and columns wrong? Or maybe it is my ruby code itself that screws up the layout once new "Huddles" are created?
EDIT: With the fixed code, the second column "col-md-3" comes out next to the last created huddle. Inspecting it, all the huddles make one single row.
<div class="row">
<% #huddles.each do |huddle| %>
<div class="col-md-9">
<div class="row">
<div class="col-md-4">
<img class="img-responsive" src="http://placehold.it/300x150">
</div>
<div class="col-md-8">
<h4><%= huddle.title %></h4>
<h4 class="huddle-description"><%= huddle.description %></h4>
<%= link_to "Read More...", huddle_path(huddle) %>
</div>
</div>
</div>
<% end %>
<div class="col-md-3">Second Column</div>
</div>
And looks like this, where the second column moves all the way down next to the last huddle created:
I think this is what you are going for. I am pretty confident the issue is with the html structure and has nothing to do with ruby.
I also want to clarify. The initial issue you were having was that you were starting a div inside the loop but only closing it outside the loop. So starting n amount of divs but only one closing tag, and that would cause it to look like the image you first posted.
<div class="row">
<div class="col-md-9">
<% #huddles.each do |huddle| %>
<div class="show-region" >
<div class="col-md-4" style="height:150px;">
<img class="img-responsive" src="http://placehold.it/300x150">
</div>
<div class="col-md-8" style="height:150px;">
<h4><%= huddle.title %></h4>
<h4 class="huddle-description"><%= huddle.description %></h4>
<%= link_to "Read More...", subjects_path(huddle) %>
</div>
</div>
<% end %>
</div>
<div class="col-md-3">Second Column</div>
</div>

Multiple ajax forms in same page does not work properly

I have a problem with multiples ajax forms in index view, only first works with remote: true attribute.
This is my index view with a forms
<% #mensagens.each do |mensagem| %>
<%= form_for(mensagem, remote: true,:authenticity_token => true) do |f| %>
<div class="row">
<div class="col-md-9">
<div class="widget">
<!-- BLOCK -->
<div class="row innerAll half border-bottom">
<div class="col-sm-12">
<div class="media-body">
<div class="innerAll half">
<div class='col-md-10'><%= f.number_field :avaliacao %></div>
<div class='col-md-2'><%= mensagem.slug %></div>
</div>
</div>
</div>
</div>
<div class="row innerAll half border-bottom">
<div class="col-sm-12">
<div class="media-body">
<div class="innerAll half">
<%= f.text_area :texto, :class=>"col-md-12 form-control", :placeholder=>"Mensagem" %>
</div>
</div>
</div>
</div>
<div class="row innerAll half border-bottom">
<div class="col-sm-12">
<div class="media-body">
<div class="innerAll half ">
<div class="col-md-2"><%= f.check_box :aprovado %></div>
<div class="col-md-2"><%= f.check_box :status %></div>
<div class="col-md-6 btn"><%= f.text_field :autor,:class=>"form-control", :placeholder=>"Autor" %></div>
<div class="col-md-2"><%= f.submit "Salvar", :class=>"btn btn-success" %></div>
</div>
</div>
</div>
</div>
<div class="row innerAll half border-bottom">
<div class="col-sm-12">
<div class='notyfy_wrapper mensagem_<%= mensagem.id %>'>
<div class="notyfy_message">
<span class="notyfy_text">
<div id="alerta"></div>
</span>
</div>
</div>
</div>
</div>
</div>
<!-- BLOCK -->
</div>
</div>
<% end %>
<% end %>
This is a result: (http://droido.com.br/html.html)
This first form works fine! but second, send a normal request (non-ajax) and redirect to show page!
At droido.com.br/mensagens the second form is nested inside the first. It appears the second This is why it isn't being set up with ajax, as forms are not supposed to be nested, so I expect Rails is not getting to it.
The problem is, based upon your code above, I am not finding any missing close tags. On the page it looks like the <div class='row'> is missing the closing tag. I suggest you knock out a section at a time until you find the problem. Or, delete the entire content and add back until you find it.
Have you used the Chrome dev tools? If not, try it out. Go to the web page, right click, inspect. It will show the tags in a hierarchical manner.

How do I add left and right classes to every other element in a loop in Ruby on Rails?

I am working within a Ruby on Rails app. I have a loop that creates divs like this:
<% #snorks.each do |snork| -%>
<div>
<%= snork %>
</div>
<% end %>
And I need the output to have every other div be floated left or right like this:
<div class="left">
Allstar Seaworthy
</div>
<div class="right">
Casey Kelp
</div>
<div class="left">
Dimmy Finster
</div>
<div class="right">
Daffney Gillfin
</div>
<div class="left">
Tooter Shellby
</div>
<div class="right">
Dr. / Uncle Galeo
</div>
Additionally, I need to add a div with class="clear" every two divs, like this:
<div class="left">
Allstar Seaworthy
</div>
<div class="right">
Casey Kelp
</div>
<div class="clear"></div>
<div class="left">
Dimmy Finster
</div>
<div class="right">
Daffney Gillfin
</div>
<div class="clear"></div>
<div class="left">
Tooter Shellby
</div>
<div class="right">
Dr. / Uncle Galeo
</div>
<div class="clear"></div>
I have researched, and found a few posts saying that the alternate classes can be accomplished easily by using cycle(), and that does work. However, when I use it in two places within the loop it stops working right and just outputs something like this:
<div class="left">
Allstar Seaworthy
</div>
<div class="left">
Casey Kelp
</div>
<div class="left">
Dimmy Finster
</div>
<div class="left">
Daffney Gillfin
</div>
<div class="left">
Tooter Shellby
</div>
<div class="left">
Dr. / Uncle Galeo
</div>
What's the best practices way in Ruby on Rails to alternate classes in a loop, and also add something every other loop?
According to the documentation, if you need nested ones you name them. Otherwise they will both share the name "default" and conflict.
<% #snorks.each do |snork| -%>
<div class="<%= cycle('left', 'right') -%>">
<%= snork %>
</div>
<%= cycle('','<div class="clear"></div>', :name=>"cleardiv") %>
<% end %>
The best thing here seems to be using each with index. That way you could do some simple modulus math to determine if the number is odd or even and output the correct class and add the clears.
#snorks.each_with_index do | snork, index|
If index%2 == 0
class = 'left'
else
class = 'right'
end
Well u get my drift and I'm on my phone.
use cycle helper
http://apidock.com/rails/ActionView/Helpers/TextHelper/cycle
<% #snorks.each do |snork| -%>
<div class="<%= cycle("left", "right") -%>">
<%= snork %>
</div>
<% end %>
Edit: for adding new div; following could help
<% #snorks.each_slice(2) do |snork_batch| -%>
<% snork_batch.each do |snork|%>
<div class="<%= cycle("left", "right",:name=>"className") -%>">
<%= snork %>
</div>
<%end%>
<div class="clear"></div>
<% reset_cycle("className")%>
<% end %>

Resources