If you have a quick look at the fiddle you’ll see the working solution in action. Everything works ok, until I change the click event onto another element and looks like this.
What I need is to change the click event onto the more link as shown in the second fiddle. Only this causes the hidden div to display inside column__4 instead of outside.
I’m just not sure what I need to change so everything works as it does in the first example with the new click event.
js
$(document).on('click', '.column__4', function(e){
//this is what i need
//$(document).on('click', '.more', function(e){
$chosen = $(this);
var n = $chosen.closest('div.column__4').find('span').attr("data-ref");
console.log(n);
$('#content').css('display','inline-block').text(n);
var top = $(this).offset().top;
var $blocks = $(this).nextAll('.column__4');
if ($blocks.length == 0) {
placeAfter($(this));
return false;
}
$blocks.each(function(i, j) {
if($(this).offset().top != top) {
placeAfter($(this).prev('.column__4'));
return false;
} else if ((i + 1) == $blocks.length) {
placeAfter($(this));
return false;
}
});
e.preventDefault();
});
Then uncomment and comment the click events to see my problem.
If your not opposed to altering the html slightly I can offer a solution that meets your requirements. It uses your script from the last updated fiddle.
From what I see with your three divs on a row at 32% width, is that there will be no more than three divs per row. You can nest those three divs in a parent div and then target with .closest(".row")
<div class="row">
<div class="column__4 col show">1
<span class="more" data-ref="1">more</span>
</div>
<div class="column__4 col show">2
<span class="more" data-ref="2">more</span>
</div>
<div class="column__4 col show">3
<span class="more" data-ref="3">more</span>
</div>
</div>
I used flexbox for the layout instead of floats but it will work with floats too.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Load div below row of containers - new click event</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
.row {
display: flex;
flex-flow: row nowrap;
justify-content: center;
margin: 0 0 10px;
}
.column__4 {
display: flex;
flex: 0 1 33%;
min-height: 200px;
margin: 0 5px;
padding: 10px;
box-sizing: border-box;
background: purple;
color: white;
}
.more {
margin-top: auto;
margin-left: auto;
padding: 5px;
cursor: pointer;
}
#content {
display: none;
margin: 0 5px 10px;
padding: 5px;
text-align: center;
background: #333;
font-weight: 600;
color: #fff;
}
</style>
</head>
<body>
<div class="row">
<div class="column__4 col show">1
<span class="more" data-ref="1">more</span>
</div>
<div class="column__4 col show">2
<span class="more" data-ref="2">more</span>
</div>
<div class="column__4 col show">3
<span class="more" data-ref="3">more</span>
</div>
</div>
<div class="row">
<div class="column__4 col show">4
<span class="more" data-ref="4">more</span>
</div>
<div class="column__4 col show">5
<span class="more" data-ref="5">more</span>
</div>
<div class="column__4 col show">6
<span class="more" data-ref="6">more</span>
</div>
</div>
<div class="row">
<div class="column__4 col show">7
<span class="more" data-ref="7">more</span>
</div>
<div class="column__4 col show">8
<span class="more" data-ref="8">more</span>
</div>
</div>
<div id="content">
content is king
</div>
<script>
function placeAfter($block) {
$block.after($('#content'));
}
var $chosen = null;
$(document).on('click', '.more', function(e){
//$(document).on('click', '.more', function(e){
$chosen = $(this);
var n = $chosen.closest('div.column__4').find('span').attr("data-ref");
console.log(n);
$('#content').css('display','block').text(n); //changed to display:block
var top = $(this).offset().top;
var $blocks = $(this).nextAll('.row'); //changed to .row
if ($blocks.length == 0) {
placeAfter($(this).closest(".row")); //changed to .row
return false;
}
$blocks.each(function(i, j) {
if($(this).offset().top != top) {
placeAfter($(this).prev('.row')); //changed to .row
return false;
} else if ((i + 1) == $blocks.length) {
placeAfter($(this));
return false;
}
});
e.preventDefault();
});
$(window).on('resize', function() {
if ($chosen != null) {
$('#content').css('display','none');
$('body').append($('#content'));
$chosen.trigger('click');
}
});
</script>
</body>
</html>
I know its not relevant now that things have changed but my demo in the other thread used flexbox also and I’ve just updated it to use only the one tab.
It has responsive columns although a lot of the logic should probably be moved to js
Thanks @Ray.H , been working endless on this, stressing out
What you suggest is a good approach if I know for certain the amount of containers. Unfortunately, this is a responsive setup and the rows will be a mixture of 1-10+ depending on the screen size and containers available.
And thanks @PaulOB l, nice improvement of the last codepen. Something I can look at moving forward for stuff related.
Ok, as mentioned. I’ve been working full steam ahead for the past 3 days and after chatting with a colleague come up with a solution
Similar approach as the last, with less code.
var $chosen = null;
var $allBlocks = [];
$(function(){
$allBlocks = $('#results .column__4');
})
$(window).on('resize', function() {
if ($chosen != null) {
$('#content').css('display','none');
$('body').append($('#content'));
$chosen.trigger('click');
}
});
$('.read_more').on('click', function() {
$chosen = $(this);
var position = $chosen.parent('.column__4').position();
$('#content').css('display','inline-block');
$allBlocks.filter(function(idx, ele){
return $(ele).position().top == position.top;
})
.last()
.after($('#content'));
});
It works mostly on the principle that .append and .after, if supplied a single target, and an existing DOM object, moves the element to the target position, rather than duplicate it. (Somewhat unintuitive to the name .append, I know)