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.
Related
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?
I want to show jquery ui placeholder both horizontally(top and bottom) and vertically (left or right) as like my sample image. But currently my code shows only top or bottom placeholder. When I place an element, placeholder appears bottom or top position but when i drop element it placed incorrectly.
Here is my sample code
helper: function (event, ui) {
this.copyHelper = ui.clone().insertAfter(ui);
return ui.clone();
},
placeholder: {
element: function(currentItem) {
return $('<div style="height: 5px; padding: 0; background-color: #F78828;" ></div>');
},
update: function(container, p) {$(container.element[0]).addClass("place_here_div");
return;
}
},
Here row column just an example. It may be any kind of element.(div, paragraph, span etc.)
I don't know if my answer will be useful for you, as it's idea with native HTML5 drag'n'drop. You need to introduce an additional element "row":
<div class="root">
<div class="row">
<div class="col-3">component 1</div>
<div class="col-3">component 2</div>
<div class="col-3">component 3</div>
<div class="col-3">component 4</div>
</div>
<div class="row"><div>
<div class="row"><div>
</div>
And then subscribe on dragover event. In the event, you will have property target and then you can define where you are. Then find the closest drop container (row or root) to target. If in the row - place vertically, otherwise place horizontally.
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.
I am calling an isotope layout for multiple containers on the same page. The catch it I would like each container ID to the be the same. Using http://isotope.metafizzy.co v.2.1.0
Isotope will work for the first block, but doesn't trigger for the second block. My feeling is once isotope layout hits the first ID of the first container it stops and doesn't look for the same container again. I've tried using .each() - doesn't seem to want to work however.
<div id="isotope-cat-list">
<div class="grid-sizer"></div>
<div class="box">
<h1>TITLE</h1>
</div>
<div class="box">
<h1>TITLE</h1>
</div>
</div>
I then need to call another isotope block layout again:
<div id="isotope-cat-list">
<div class="grid-sizer"></div>
<div class="box">
<h1>TITLE</h1>
</div>
<div class="box">
<h1>TITLE</h1>
</div>
</div>
Full HTML would look like this:
<div id="isotope-cat-list">
<div class="grid-sizer"></div>
<div class="box">
<h1>TITLE</h1>
</div>
<div class="box">
<h1>TITLE</h1>
</div>
</div>
<div id="isotope-cat-list">
<div class="grid-sizer"></div>
<div class="box">
<h1>TITLE</h1>
</div>
<div class="box">
<h1>TITLE</h1>
</div>
</div>
Obviously there are more elements in those .box elements but for simplicity sake I whittled it down. The reason for multiple calls is they will be for different categories and have other elements in between then and I'd rather not have to call a bunch of container ID's.
When I try to trigger the #isotope-cat-list in my .js library it will run for the first block - but won't trigger for the second block. I've tried doing some jQuery .each() but that didn't work.
Here's the JS:
var mainEl = $('#isotope-cat-list');
mainEl.isotope({
animationEngine: 'best-available', //CSS3 if browser supports it, jQuery otherwise
itemSelector: '.box',
animationOptions: {
duration: transitionDuration
},
containerStyle: {
position: 'relative',
overflow: 'visible'
},
masonry: {
columnWidth: columnWidth,
gutter: 1
}
});
I've tried doing .each():
var mainEl = [$('#isotope-cat-list')];
$.each(mainEl, function (j) {
this.isotope({
animationEngine: 'best-available', //CSS3 if browser supports it, jQuery otherwise
itemSelector: '.box',
animationOptions: {
duration: transitionDuration
},
containerStyle: {
position: 'relative',
overflow: 'visible'
},
masonry: {
columnWidth: columnWidth,
gutter: 1
}
});
});
But it still doesn't trigger for the second HTML block. Any help here would be much appreciated! Thanks!
As I stated, ID's are unique. You can use a class multiple times like so ( some of your functions are missing so I had to modify your code for that reason). You are calling isotope using v1.56 options, not v2.
Updated code
jsfiddle
var mainEl = $('.isotope-cat-list');
mainEl.isotope({
itemSelector: '.box',
transitionDuration: '0.3s',
masonry: {
columnWidth: '.grid-sizer',
gutter: 10
}
});
You are using isotope V2 and it only uses css3 for animations, therefore you should not apply animationEngine or animationOption. Also you are using "grid-sizer" and that should be what you apply in your columnWidth. E.g. columnWidth: '.grid-sizer'. Also the containerStyle is position: relative as a default, therefore it is useless to say it in the options. Also the gutter is pointless in your case as you can simply use margins in css for your items.
For your question you'd do:
var mainEl = $('.isotope-cat-list');
mainEl.isotope({
itemSelector: '.box',
masonry: {
columnWidth: '.grid-sizer'
}
});
var mainEl2 = $('.isotope-cat-list-2');
mainEl2.isotope({
itemSelector: '.box',
masonry: {
columnWidth: '.grid-sizer'
}
});
I am using jquery ui sortable with connected lists. I have 2 problems with one most important requirement.
Items goes behind the other list while dragging li.ui-splitselect-item
Dragging item to right(when mouse is too right) creates Horizontal scroll
IMPORTANT: Lists ul.ui-splitselect-list should have overflow-y:auto; So Header of lists stay fixed
and only list items are scrolled
NOTE:
I previous asked this question on STACKOVERFLOW but didnt notice my important requirement was missing from solution so i opened question again with clarity.
JSFIDDLE: http://jsfiddle.net/bababalcksheep/z67Td/
HTML Mockup:
<div class="ui-splitselect ui-helper-clearfix ui-widget ui-widget-content" style="height:200px;" >
<div class="ui-widget-content ui-splitselect-selected">
<div class="ui-widget-header ui-helper-clearfix">
List1
</div>
<ul id="sortable1" class="ui-splitselect-list" style="height: 332px;">
<li class="ui-splitselect-item ui-state-default">
<a class='ui-splitselect-handle-drag'><span class='ui-icon ui-icon-carat-2-n-s'></span></a>
<span class="ui-splitselect-handle-select">TEST-List1</span>
<a class="ui-splitselect-handle-move" href="#"><span class="ui-icon ui-icon-plus"></span></a>
</li>
</ul>
</div>
<div class="ui-widget-content ui-splitselect-available" >
<div class="ui-widget-header ui-helper-clearfix">
List2
</div>
<ul id="sortable2" class="ui-splitselect-list" style="height: 332px;">
</ul>
</div>
</div>
CSS:
.ui-splitselect{font-size:.8em;width:100%!important;text-align:center;margin:0 auto;padding:0}
.ui-splitselect ul{-moz-user-select:none}
.ui-splitselect .ui-widget-header{border:none;font-size:11px}
.ui-splitselect-selected{height:100%!important;float:left;border:none;width:50%;margin:0;padding:0}
.ui-splitselect-available{height:100%!important;width:49.4%;float:left;border-top:none;border-bottom:none;border-right:none;margin:0;padding:0}
.ui-splitselect-list{height:92%!important;position:relative;list-style:none;overflow:auto;margin:0;padding:0}
.ui-splitselect-item{cursor:default;line-height:20px;height:20px;font-size:11px;list-style:none;display:list-item;white-space:nowrap;overflow:hidden;margin:1px;padding:0}
.ui-splitselect-item.ui-sortable-helper{z-index:99999}
.ui-splitselect-handle-select{float:left}
.ui-splitselect-handle-drag{float:left;height:20px;border-top:0;border-bottom:0;cursor:pointer;margin:0 10px 0 5px;padding:2px 5px}
.ui-splitselect-handle-move{text-decoration:none;cursor:pointer;float:right;height:20px;border-top:0;border-bottom:0;margin:0 5px 0 10px;padding:2px 5px}
JS:
$("#sortable1, #sortable2").sortable({
connectWith: ".ui-splitselect-list",
containment: ".ui-splitselect",
scroll: false,
placeholder: "ui-state-highlight ui-splitselect-item"
}).disableSelection();
Try adding appendTo: document.body and helper: clone options for sortable, like this:
$("#sortable1, #sortable2").sortable({
appendTo: document.body,
helper: "clone",
connectWith: ".ui-splitselect-list",
containment: ".ui-splitselect",
scroll: false,
placeholder: "ui-state-highlight ui-splitselect-item"
}).disableSelection();
Js fiddle: http://jsfiddle.net/XpP25/2/
Trick is in creating sorting helper that clones your original element, and then appending it to body element to resolve zIndex issues. All helpers are automatically removed after stop event of draggable and sortable, so it shouldn't mess your code :)
Hope it helps.
I was having a similar issue with nested sortable items. I have multiple sortable containers, that make up a grid, then widgets inside of those sortable containers. Inside of each widget there is a nested sortable container which takes up the width and height. Inside of the nested sortables I can have multiple nested-widgets, spanning the width of the nested sortable.
Here is how one of those sortables would look:
<div class="sortable">
<div class="widget">
<div class="nested-sortable">
<div class="nested-widget"></div>
</div>
</div>
</div>
Now, once I started dragging my nested sortable item, it would go behind every outer widget except for the one containing it. I tried changing the z-index of the items on sort start and no luck. I needed something like jQuery UI's Draggable stack option, which "stacks" the currently dragged item over all other items of the same class.
Here is jQuery UI's draggable stack function on github at line 800.
So, my friend and I modified that code a bit, and called it on the "outer" widget.
$.fn.stack = function () {
// where $(this) == '.widget'
var o = $(this).closest('.sortable').siblings('.sortable').find('.widget');
// create an array of all the widgets
var group = $(o).sort(function(a,b) {
// compare the each set of widgets
return (parseInt($(a).css("z-index"),10) || 1) - (parseInt($(b).css("z-index"),10) || 1);
});
if (!group.length) { return; }
var min = parseInt($(group[0]).css('z-index')) || 1; // first widget's z-index
$(group).each(function(i) {
// increase each widget's z-index by min + $(this) widget's index value
$(this).css('z-index', min + i);
});
// make currently dragged widget's z-index min + length of group
$(this[0]).css('z-index', min + group.length);
}
Then call in sortable start:
$('.nested-sortable').sortable({
start: function(event, ui) {
$(this).closest('.widget').stack();
}
});
Here is my codepen for reference: Nested Grid System