I am using the Bootstrap class .clearfix
after every second(or third) <div>
to keep each row starting at the same height on all screen sizes even if two divs on same row have different height.
I use a hidden <div>
at the top as template for information I will get from an ajax call. I have simulated this event in the demo with a button to click and content "insert N" for simplicity. The counter is only there for the demo. In this snippet I also added <br />
to some news to simulate difference in height.
When I insert a <div>
at the top with jquery, I need the .clearfix
classes to move accordingly to keep the current layout, and add a .clearfix
if there are too many <div>
after the last .clearfix
.
The layouts are 1 field on top row, and 2(or 3) fields on all other rows on screen 992px and up, if smaller screen just 1 field per row.
(Just to be clear, when I talk about "row", I do not mean the bootstrap class .row
)
I have managed to get this working with jquery .clone()
/ .prepend()
/ .each()
/ .prev()
/ .next()
/ .insertAfter()
/ .nextUntil()
/ .nextAll()
, but I cant shake the feeling that it is extremely long-winded and hard for next generation coders to maintain. Can anyone offer a cleaner method?
// simulate new content from ajax call
$('#clickit').on('click', function(){
// demo counter
var counter = (parseInt($('#output').text())+1);
$('#output').text(counter); // view
// clone template before filling up with info
var template = $('.modalInputHolder_679');
var templateClone = template.clone();
// remove template-class from old template
// insert new content in new div(old template) and new template
template.removeClass('modalInputHolder_679').text('insert '+counter);
templateClone.text('hidden');
$(".row").prepend(templateClone);
// move clearfix divs up one place
var replaceClass;
var clearfix = $(".row .clearfix");
clearfix.each(function(index){
var that = $(this);
var prev = that.prev();
if(index==0) { // if first .clearfix
replaceClass = that.next().attr('class'); // get new class for old template
prev.attr('class',replaceClass);
}
prev.insertAfter(that); // move up
});
// accomodate for both 1-2 layout and 1-3 layout(wide first, rest split among 2/3 cols)
var clearfixLength = clearfix.length;
if(clearfixLength>1){ // if more than two .clearfix
// find number of divs between clearfixes
var type = clearfix.eq(0).nextUntil('.clearfix').length;
var last = clearfix.eq((clearfixLength-1)); // get last .clearfix
// get number of divs after last
var trailingFields = last.nextAll();
var trailingLength = trailingFields.length;
if(trailingLength>type){ // if difference is more than filled up (2 or 3)
var clearfixClone = clearfix.eq((type-1)).clone(); // create clone of clearfix
trailingFields.eq((type-1)).after(clearfixClone); // input new clearfix
}
}
});
.fullWidthColumn { background-color: #FF0000!important; }
.row>.col-xs-12:nth-of-type(odd) { background-color: #00FF00; }
.row>.col-xs-12:nth-of-type(even) { background-color: #0000FF; }
.modalInputHolder_679 { display:none; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<button class="btn btn-default" id="clickit">Insert news</button> <span> Counter: </span><span id="output">0</span><br />
<div class="container">
<div class="row">
<div class="col-xs-12 fullWidthColumn modalInputHolder_679">hidden</div>
<div class="col-xs-12 fullWidthColumn">first</div>
<div class="clearfix"></div>
<div class="col-xs-12 col-md-6">second<br />...</div>
<div class="col-xs-12 col-md-6">third</div>
<div class="clearfix"></div>
<div class="col-xs-12 col-md-6">fourth</div>
<div class="col-xs-12 col-md-6">fifth<br />...</div>
<div class="clearfix"></div>
<div class="col-xs-12 col-md-6">sixth<br />...</div>
<div class="col-xs-12 col-md-6">seventh</div>
</div>
</div>
Here's jsfiddles of both 2 col layout (code/view) and 3 col layout (code/view), they use the same javascript and css, but slightly different html.