Adding grid items to isotope without breaking the UI - javascript

I have my HTML as below
<div class="blog-box">
<div class="blog-item" >...</div>
<div class="blog-item" >...</div>
<div class="blog-item" >...</div>
</div>
and javascript with jquery and isotope js as
var $container=$('.blog-box');
try{
$container.imagesLoaded( function(){
$container.show();
$container.isotope({
filter:'*',
layoutMode:'masonry',
animationOptions:{
duration:750,
easing:'linear'
}
});
});
} catch(err) {
}
When I try to add more blog item elements dynamically using javascript, the width of the blog-box item becomes zero. I have tried rerunning the js above every time I add items to the blog-box but it's not working out. How do I be able to add more blog-items without interfering with the layout?

Related

slideDown does not work for the first time

I'm adding animation to show a hidden div when a checkbox is changed,
The first time it's clicked the div appears with no animation but it works both ways after the first time.
How can I make it work also on the first time?
Here is my div (also using bootstrap)
var postOptionsSourcesWrapper = $("#post-options-sources-wrapper");
var postOptionsExclusiveCheckbox = $("#post-exclusive-cb");
postOptionsExclusiveCheckbox.change(function() {
if ($(this).is(":checked")) {
postOptionsSourcesWrapper.slideUp(300, "easeOutCirc", function() {
postOptionsSourcesWrapper.addClass("hidden");
});
} else {
postOptionsSourcesWrapper.removeClass("hidden");
postOptionsSourcesWrapper.slideDown(300, "easeOutCirc");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="post-options-sources-wrapper" class="margin-b-5 hidden">
<label class="text-md thick-600">Original post references</label>
<div class="box-marker box-marker-white">
<div class="thick-600 color-gray text-sm text-uppercase">
Add one or multiple sources.
</div>
</div>
</div>
UPDATE: this issue is solved by adding display:none; to the div
When adding the bootstrap class .hidden to hide for some reason it's not adding the display:none; that is part of the .hidden class in bootstrap... not sure why, but adding the style display:none; or calling postOptionsSourcesWrapper.hide() solves this issue.
This code will achieve what you want to achieve.
You just have to replace your script with this one.
var postOptionsSourcesWrapper = $("#post-options-sources-wrapper");
var postOptionsExclusiveCheckbox = $("#post-exclusive-cb");
postOptionsSourcesWrapper.hide();
postOptionsExclusiveCheckbox.change(function() {
postOptionsSourcesWrapper.slideToggle(300,postOptionsSourcesWrapper.is(":checked"));
});

Masonry/Isotope.js not working correctly

I'm developing an wordpress theme and I'm using Isotope or Masonry for the masonry layout. Also I'm using Visual Composer to insert custom elements that i mapped to Visual Composer. I have a container which has no styles and all these items have a div with a class "overlay" that's absolutely positioned and has 100% width and height. It's purpose is to position the white box ( class "content" ) inside of it. Isotope has been giving me a hard time in a previous wordpress theme.. I have no idea why. Here's the image.
Here's the markup for an item:
<div class="masonry-item">
<img/>
<div class="overlay">
<div class="content">
<!-- Just some text here
</div>
</div>
</div>
ANY suggestions are more than welcome, because I can't seem to get it to work in ANY way. Most of the layout methods just end up overlapping all of the items in the most top left corner of the container. Yes, I've tried using ImagesLoaded.js, and it hasn't made a difference.
Masonry JS:
$(".masonry-grid").isotope({
itemSelector: '.masonry-item'
});
.masonry-item CSS:
.masonry-item {
position: relative;
margin-bottom: 30px;
}
It would seem that if they ALL have equal width like 50% it will work flawlessly. Like Deepak Thomas noted in the comments. But as soon as i put a random style for each element, like 30, 40, 50, 60, 70% width it starts to break. In some cases it would put elements next to each other, most of the time leaving a gap between them if they are not in the first row, and the other times it would just stack them one on top of another even though the two items can clearly be put side to side and still have room to spare.
EDIT: Tried removing the image. No difference.
Thanks in advance!
try this :
var $post_masonry = $('.masonry-grid');
$(document).ready(function () {
if ($post_masonry.length) {
$post_masonry.isotope({
itemSelector: '.masonry-item',
layoutMode: 'masonry',
percentPosition: true,
masonry: {
columnWidth: '.masonry-item'
}
});
}
});
Recommended to use imagesloaded.pkgd.min.js to apply isotope when images already loaded.
var $post_masonry = $('.masonry-grid');
$(document).ready(function () {
if ($post_masonry.length) {
var $masonry = $post_masonry.imagesLoaded(function() {
$masonry.isotope({
itemSelector: '.masonry-item',
layoutMode: 'masonry',
percentPosition: true,
masonry: {
columnWidth: '.masonry-item'
}
});
});
}
});
if ($post_masonry.length) --> is optional. Usually applied with dynamic ajax.
From the code you shared, it seems masonry does not provide default sizes to its items.
For every masonry-item, give an additional class
E.g:
.half { width: 50% }
.full { width: 100% }
.pad { padding: 15px }
And use this on the items as you find them apt.
E.g:
<div class="masonry-item half">
<div class="pad">
<img src="xyz" />
<div class="overlay">
<div class="content">I'm the overlay content</div>
</div>
</div>
</div>
That should solve it.
The problem is that the first masonry item is being taken as the columnWidth option for isotope. So just make sure that the first time is the smallest one of your columns.

Make an endless jQuery short and easy

I have an accordion on my WordPress website.
Usually it works fine, adding and removing classes when clicking the different tabs, but there is an issue with one of the accordions on the website: When clicking on one of the tabs - it doesn't close the rest of the opened tabs. So I added this code in and it works fine:
jQuery(document).ready(function($) {
$("#top11").click(function() {
$("#collapse202").removeClass("in");
$("#collapse203").removeClass("in");
});
$("#top12").click(function() {
$("#collapse201").removeClass("in");
$("#collapse203").removeClass("in");
});
$("#top13").click(function() {
$("#collapse201").removeClass("in");
$("#collapse202").removeClass("in");
});
});
I am sure that there is a way to make it shorter, could some one please explain how to do it more compact?
One way is to add data-id to each collapsed element. For example:
<div id="collapse201" data-id="top11"></div>
<div id="collapse202" data-id="top12"></div>
<div id="collapse203" data-id="top13"></div>
And of course you should use a class in your tabs just in case there are lots of tabs in your accordion:
<div id="top11" class="clickingTab"></div>
<div id="top12" class="clickingTab"></div>
<div id="top12" class="clickingTab"></div>
The JS code could look like this then:
jQuery(document).ready(function($) {
$(".clickingTab").click(function() {
var clickedId = $(this).attr("id");
$("element:not([data-id="+clickedId+"])").removeClass("in");
});
});
There of course could be more efficient ways to solve your problem. But for this particular question this could be the particular solution.
If your HTML look like that, you can use the next() function to target the next sibling element:
$("#top11, #top12, #top13").click(function() {
$("#top11, #top12, #top13").next().removeClass("in");
$(this).next().addClass("in");
});
.in {
color:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="top11">top11</div>
<div id="collapse201" class="in">collapse201</div>
<div id="top12">top12</div>
<div id="collapse202" class="in">collapse202</div>
<div id="top13">top13</div>
<div id="collapse203" class="in">collapse203</div>

Grid system does not work when it is inside a hidden div

I am using the Salvattore plugin to create a grid based layout for my website.
Here is how the plugin should set up in HTML:
<div class="grid columns2" data-columns>
<img src="">
<img src="">
</div>
It basically finds .grid and then .columns3 which determines how many columns the plugin should create inside .grid.
The outcome would look like:
<div class="grid" data-columns="2">
<div class="column count-2">
<img src="">
</div>
<div class="column count-2">
<img src="">
</div>
</div>
All works fine, until the .grid is a child of a parent which has display: hidden - i.e:
<div style="display:none" id="popup">
<div class="grid" data-columns="2">
<div class="column count-2">
<img src="">
</div>
<div class="column count-2">
<img src="">
</div>
</div>
</div>
Why I gave it display: none? well, I am trying to use this .grid inside div's which are hidden by default and only show when requested, for example, inside a popup window or UI accordion and tabs.
I have created a live test here: http://loai.directory/beta if you look, you will see two containers with the .grid one that works fine and the other one below where it says The hidden div is below me which is the one in question.
Here is what I thought of doing "but don't have the skills to try it or even know where to start" - I was wondering, would the problem be solved if using JavaScript to trigger the plugin again each time the .grid state changes?
Your problem with Salvatore's plugin is in grid-system.js (ln. 538)
self.registerGrid = function registerGrid (grid) {
if (global.getComputedStyle(grid).display === "none") {
return; // so basically any class or inline style with display set to none :s
}
/*...*/
};
To workaround this issue, you can bind an unique event to it's "toggle/display" trigger. It would be ideal that all triggers and hidden layers, match an unique id or some commonly mapped reference.
trigger popup
<div id="popup" class="grid hide" data-columns></div>
Then the js would be something like:
function delayedGrid() {
var grids = $('.grid.hide[data-columns]'); // assuming they all have the hide class
// var grids = $('.grid:hidden'); // could work as well
$.each(grids, function(){
// pickup the mapped references from your grid (id and ref)
var grid = $(this),
id = grid.prop('id'), // get the id reference
ref = $('[data-ref="' + id + '"]'); // get the referenced element by data-ref="popup" for ex.
// one time only event
ref.one('click', function() {
// gives browser reflow a better chance
setTimeout(function() {
// call the grid initializer again
salvattore.init();
}, 200);
});
});
}
Then all you need to do is render delayedGrid on DOM ready, or onload, or on resize, or whenever you need to recalculate your hidden grids.
// DOM ready
$(fuction(){
delayedGrid();
});
// window load
$(window).load(function(){
delayedGrid();
});
// window resize
$(window).on('resize', function(){
// google for throttle function perhaps
delayedGrid();
});

masonry on bootstrap elements got bumped down to new row

The nature of the elements are that each one will be varied in height (due to image and the title) and its height is unknown before applying masonry. Though the width of each element is fixed with .col-lg-3.
On the rendered page where each row has 4 elements, the 5 element is visually on a row on its own and the 6, 7, 8 got pushed down to 3rd row.
html code
<div class="section-details">
<div class="container">
<div class="">
<div class="masonry" id="elements" data-reference="0">
<!-- elements will be pulled over dynamically -->
</div>
</div>
</div>
</div>
and the content of each new element is wrapped in something like the following
<div class="col-lg-3 element">
</div>
css
.element {
padding: 10px 10px 0px;
}
javascript code
// layout the elements
var layout = function(elements, $container, selector) {
$container.imagesLoaded(function () {
$container.masonry({
itemSelector: selector,
columnWidth: selector,
isAnimated: true,
animationOptions: {
duration: 750,
easing: 'linear',
queue: false
}
}).append(elements).masonry('appended', elements, true);
});
};
and it's got called in the following way
layout(elements, $('#elements'), '.element');
So anything could go wrong here?
Debugged into the masonry source code and figured out the cause, it's how the elements got prepared that matters - each of the element that got pushed to the elements array should be an HTMLElement. And once I got that fixed, the issue was gone.

Categories

Resources