Dynamically create rows and columns in bootstrap / rails - ruby-on-rails

Using Rails with bootstrap I'm trying to layout a page which will have an unknown number of blocks of content on it. On small screens there should be 1 column, on medium screens 2 columns, and on larger screens 3 columns.
Such as...
However I can't work out how to slice up the content so it works reliably. Currently I have this in my view :
<div class="container">
<% #posts.each_slice(3) do |posts| %>
<div class="row">
<% posts.each do |post| %>
<div class="col-sm-6 col-lg-4">
<img src="<%= post.image %>" class="img-responsive">
<h2><%= post.title %></h2>
<h6><%= post.created_at.strftime('%b %d, %Y') %></h6>
<p> <%= raw(post.body).truncate(358) %></p>
</div>
<% end %>
</div>
<% end %>
</div>
But this produces...
I've tried changing the each_slice(3) and class="col-sm-6 col-lg-4" however regardless of the combinations I choose one of the medium or large views breaks.
How do I reliably achieve the desired effect above regardless of the number of items on the page?

When the content of the columns is the same height, the grid wraps evenly:
http://www.codeply.com/go/8w2INqz3e1
When the content of the columns is different heights, the grid wraps unevenly, causing gaps..
http://www.codeply.com/go/1LBtvtDnzA
To fix this, you need to use responsive resets as described in this answer..
Bootstrap row with columns of different height
For example, a CSS clearfix approach in your case would work like this..
#media (min-width: 1200px) {
.row > .col-lg-4:nth-child(3n+1) {
clear: left;
}
}
#media (max-width: 992px) {
.row > .col-sm-6:nth-child(2n+1) {
clear: left;
}
}
http://www.codeply.com/go/LDqxBlyULr

Related

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.

Second container does not load jquery masonry in my rails app

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

Tips on coding this layout with Twitter Bootstrap

I am trying to make this layout with Twitter Bootstrap (only the boxes) :
Basically, it is a youtube embedded video and two equal size boxes to its right.
I have this right now (haml) :
.row
.span8
/ embedded code
.span4
/ I need to put two boxes here... how?
You can stack the .span* blocks inside a .row-fluid container which you can then nest inside another span* block to create the effect you're looking for. Try this for example:
HTML
<div class="container-fluid">
<div class="row-fluid">
<div class="span9">
<div class="big box">
box
</div>
</div>
<div class="span3">
<div class="row-fluid">
<div class="span3">
<div class="box">
box
</div>
</div>
<div class="span3">
<div class="box">
box
</div>
</div>
</div>
</div>
</div>
</div>
Notice how i nested the two side blocks one on top of each other contained within a .row-fluid container inside a another .span* block t stack them up.
Now with a little CSS you we can stretch the stacked .span* blocks to the width of the parent block to create a column:
CSS
.row-fluid [class*="span"] .row-fluid [class*="span"] {
margin-left: 0;
width: 100%;
}
Demo: http://jsfiddle.net/k27S5/show/
Don't know much of HAML but after taking a look at the documentation the setup should look something like this:
HAML
.container-fluid
.row-fluid
.span9
content
.span3
.row-fluid
.span3
content
.span3
content
If you're using the fixed width layout:
.row
.span8
.span4
.row
.span4
.row
.span4
If you're using fluid layout:
.row-fluid
.span8
.span4
.row-fluid
.span12
.row-fluid
.span12
This assumes you're not concerned about matching the heights of the two columns, which wouldn't be handled by Bootstrap anyway.
Like most grid based systems, the one used in twitter bootstrap will help you lay things out by rows but NOT by columns.
I'm assuming you want the big box on the left to be the same height as the two boxes on the right. If that's the case the easiest way to do it is with tables. Yes, people give tables a bad rap but for certain layouts it's the simplest solution.
<table>
<tr>
<td>big box on left</td>
<td>
<div>small top box on right</div>
<div>small bottom box on right</div>
</td>
</tr>
</table>
Then style accordingly

rails - select all checkboxes inside a div before submitting form

I have a new batch form where user can select books from a div using the checkbox and click on a button to put them in another div which represents the selected books.
It works a bit like a listbox where user can move items between the different boxes except that here am using checkbox and div.
I have done the moving of books from one div to another using jquery.
See code below:
<% form_for #batch do |f| %>
<label style="width: 150px">Batch Name:</label><%= f.text_field :BAT_BATCH_NAME %>
<div id="all_books">
<% #books.each do |book| %>
<div id="book<%= book.BK_OID %>" bookid="<%= book.BK_OID %>" class="innertxt">
<ul>
<li>Book ID: <%= book.BK_OID %></li>
<li>Name: <%= book.BK_NAME %></li>
<li>
<input type="checkbox" name="batch[book_ids][]" id="select<%= book.BK_OID %>" value=<%= book.BK_OID %> class="selectit" />
</li>
</ul>
</div>
<% end %>
<div style="width:100px; text-align:center; margin-left:20px; padding-top: 100px; width:75px; float:left;">
Right »<br /><br />
« Left
</div>
<div id="selected_books"> </div>
<br/><br/>
<%= f.submit 'Update Batch Details' %>
<% end %>
Currently, only the selected books are saved, whether they are found in the 'all_books' div or 'selected_books' div.
However, I want all entries in the 'selected_books' div to be submitted when saving the batch, whether their checkboxes have been checked or not. and ignore all selected entries in the 'all_books' div.
In short, when saving the batch, i want to save only those books found in the 'selected_books' div and ignore the rest whether their checkboxes have been checked or not.
I hope i was clear enough.
I would be really grateful if someone could point me the right direction on how to do that.
Many many thanks for any suggestion provided.
$("#formid").submit(function(){ $("#selected_books").find("input:checkbox").attr({checked: "checked"}); });
That should do the trick.

Is it possible to give each record a differant css class?

Is there any way to give each record in a table its own css class? Im displaying records as partials but would like to be able to give each partial its own individual css attributes. Maybe a way of assigning css rules by a div's name and id of the record combined?
EDIT
Sorry for the poorly written question I'll try and explain in more detail.
I have a table of venue records being displayed on the index page in partials and want each one to have an icon placed on a map off to the left side of the screen (map_container). The map is just a hand drawn image as the background of a fixed width and height div.
Venue index.html.erb:
<div class="map_container">
</div>
<div class="filter_options_container">
<form class="filter_form", method="get">
<fieldset class="filter_form_fieldset">
<legend class="filter_form_fieldset_legend">Choose an area:</legend>
<% Area.all.each do |a| %>
<span class="filter_form_checkbox_label">
<%= check_box_tag("areas[]", a.id, false, :class => "styled")%>
<%= a.name %><br>
</span>
<% end %>
<input type="submit" value="Filter" />
</fieldset>
</form>
</div>
<div class="venue_partials_container">
<%= render :partial => 'venue', :collection => #venues %>
<div class="clearall"></div>
<%= will_paginate #venues %>
<div class="venue_partial_button">
<%= link_to 'add a new venue', new_venue_path %>
</div>
</div>
<div class="clearall"></div>
I was thinking a way of doing this could be to make another table of icon records where one venue belongs to one icon and one icon belong to one venue. Then yielding the map div area to partials of the icon records. The differant css classes could then be something like:
.icon(with_venue_id_1) {
position: absolute;
top: 10px;
left: 10px;
}
.icon(with_venue_id_2) {
position: absolute;
top: 15px;
left: 20px;
}
etc etc....
Which I know is so horrifically bad it may bring a bit of sick in your mouth but my zero experience of programming ever has led me to this. I imagine theres so many better ways of doing it but this could work as a learning aid for me at least.
I would eventually like these icons and their positioning to be added from the running app itself but for now I'm happy just to get something working.
Thanks for any help, its much appreciated.
Something like this?
<% #record.each do |r| %>
<tr class="<%= r.id %>">
<!-- Or some other value from the record? -->
...
Not sure I understood the question completley.

Resources