so i’m playing around with jquery isotope and trying to combine two options into one button
I have one set of links which filters the results, the other set of links changes the layout mode. I would like filter links to change the layout as well as filtering.
heres the spine documentation which is the layout mode i’m changing to from default.
i think the problem lies with the data-option-key, as one is set to filter and the other to layoutMode, is it possible to have two different data-option-key’s with different kinds of data-option-values within?
here’s the html followed by the script:
<section id="options">
<ul id="filters" class="option-set clearfix" data-option-key="filter">
<li><a href="#filter" data-option-value="*:not(.before)" class="selected">everything</a></li>
<li><a href="#filter" data-option-value=".modern">modern</a></li>
<li><a href="#filter" data-option-value=".traditional">traditional</a></li>
<li><a href="#filter" data-option-value=".commercial">commercial</a></li>
<li><a href="#filter" data-option-value=".automotive">automotive</a></li>
<li><a href="#filter" data-option-value=".bespoke">bespoke</a></li>
<li><a href="#filter" data-option-value=".before, .after">before <span style="font-size:10px;">&</span> after</a></li>
</ul>
<ul id="layouts" class="option-set clearfix" data-option-key="layoutMode">
<li><a href="#filter" data-option-value="masonry" class="selected">normal</a></li>
<li><a href="#filter" data-option-value="spineAlign">spine</a></li>
</ul>
</section> <!-- # O P T I O N S -->
<div id="result"></div>
<div id="container" class="clickable clearfix">
<div class="element portrait before">
<a href="img/gallery/large/beforeandafter/image1_before.jpg" rel="shadowbox[traditional]"><img src="img/gallery/thumbs/beforeandafter/image1_before.jpg" alt="chair" /></a>
</div>
<div class="element portrait after bespoke">
<a href="img/gallery/large/beforeandafter/image1_after.jpg" rel="shadowbox[traditional]"><img src="img/gallery/thumbs/beforeandafter/image1_after.jpg" alt="chair" /></a>
</div>
<div class="element portrait modern">
<a href="img/gallery/large/modern/image1.jpg" rel="shadowbox[traditional]"><img src="img/gallery/thumbs/modern/image1.jpg" alt="chair" /></a>
</div>
<div class="element landscape modern">
<a href="img/gallery/large/modern/image2.jpg" rel="shadowbox[traditional]"><img src="img/gallery/thumbs/modern/image2.jpg" alt="chair" /></a>
</div>
</div> <!-- # C O N T A I N E R -->
<script>
$(function(){
var $container = $('#container');
$container.isotope({
itemSelector : '.element',
filter: '*:not(.before)'
});
// custom layout mode spineAlign
$.Isotope.prototype._spineAlignReset = function() {
this.spineAlign = {
colA: 0,
colB: 1
};
};
$.Isotope.prototype._spineAlignLayout = function( $elems ) {
var instance = this,
props = this.spineAlign,
gutterWidth = Math.round( this.options.spineAlign && this.options.spineAlign.gutterWidth ) || 0,
centerX = Math.round(this.element.width() / 2);
$elems.each(function(){
var $this = $(this),
isColA = props.colB > props.colA,
x = isColA ?
centerX - ( $this.outerWidth(true) + gutterWidth / 2 ) : // left side
centerX + gutterWidth / 2, // right side
y = isColA ? props.colA : props.colB;
instance._pushPosition( $this, x, y );
props[( isColA ? 'colA' : 'colB' )] += $this.outerHeight(true);
});
};
$.Isotope.prototype._spineAlignGetContainerSize = function() {
var size = {};
size.height = this.spineAlign[( this.spineAlign.colB > this.spineAlign.colA ? 'colB' : 'colA' )];
return size;
};
$.Isotope.prototype._spineAlignResizeChanged = function() {
return true;
};
$(function(){
var $container = $('#container');
$container.isotope({
itemSelector : '.element',
layoutMode: 'spineAlign',
spineAlign: {
gutterWidth: 20
}
});
var $optionSets = $('#options .option-set'),
$optionLinks = $optionSets.find('a');
$optionLinks.click(function(){
var $this = $(this);
// don't proceed if already selected
if ( $this.hasClass('selected') ) {
return false;
}
var $optionSet = $this.parents('.option-set');
$optionSet.find('.selected').removeClass('selected');
$this.addClass('selected');
// make option object dynamically, i.e. { filter: '.my-filter-class' }
var options = {},
key = $optionSet.attr('data-option-key'),
value = $this.attr('data-option-value');
// parse 'false' as false boolean
value = value === 'false' ? false : value;
options[ key ] = value;
if ( key === 'layoutMode' && typeof changeLayoutMode === 'function' ) {
// changes in layout modes need extra logic
changeLayoutMode( $this, options )
}
else {
// otherwise, apply new options
$container.isotope( options );
}
return false;
});
});
// filter buttons for shadowbox
$('#filters a').click(function(){
var selector = $(this).attr('data-option-value');
$container.isotope({ filter: selector });
// don't proceed if no Shadowbox yet
if ( !Shadowbox ) {
return false;
}
Shadowbox.clearCache();
$container.data('isotope').$filteredAtoms.each(function(){
Shadowbox.addCache( $(this).find('a[rel^="shadowbox"]')[0] );
});
return false;
});
});
</script>
appreciate any nudges in the right direction
thanks
edit:
i’ve also been trying another approach, of using jquery to resize the container when the links are clicked. but this has its own problems. i can get it to resize, but when the filter changes it won’t keep the images inside the container, instead they are left outside the newly formed small container until you click again and then they reposition themselves inside to fit. so close!
the code i was trying for this:
// change the width of the container depending on the filter
if ( $this.hasClass('thin') ) {
$container
.css({'width': '636px','margin-left': '132px'})
.isotope('reLayout');
}
if ( $this.hasClass('thick') ) {
$container
.css({'width': '960px','margin-left': '0'})
.isotope('reLayout');
}
got it working after a looooong time.
for anyone who is interested I used JSON to allow two different values in each link, so my options ended up looking like this:
i then called both values one after the other in the script like:
i’m still new with jquery so it might not be the best way, but it worked, WAHOO!