jQuery quicksand sorting

942 Views Asked by At

On a long panel of 120 images (130x130px) with iosslider to give give it touch swiping sliding. i'm using jQuery quicksand to sort a collection of blocks that are in columns of 4. So i need to clone them, extract the item blocks, sort them and add them back into columns (panel) again.

<div id="tiles_viewport">
  <div id="mouseSwipeScroll">
    <div class="panel">
        <div class="item" data-id="1" data-state="1"><img src="xxx" /></div>
        <div class="item" data-id="2" data-state="1"><img src="xxx" /></div>
        <div class="item" data-id="3" data-state="1"><img src="xxx" /></div>
        <div class="item" data-id="4" data-state="0"><img src="xxx" /></div>
    </div>
    <div class="panel">
        <div class="item" data-id="5" data-state="1"><img src="xxx" /></div>
        <div class="item" data-id="6" data-state="1"><img src="xxx" /></div>
        <div class="item" data-id="7" data-state="1"><img src="xxx" /></div>
        <div class="item" data-id="8" data-state="0"><img src="xxx" /></div>
    </div>
    <div class="panel">...

CSS...

#tiles_viewport {
  position: relative;
  top: 0;
  left: 0;
  width: 100%;
  height: 535px;
  margin: 5px 0;
  padding: 0;
  overflow: hidden;
  z-index: 10;
}

#mouseSwipeScroll {
  -webkit-user-select: none;
  -moz-user-select: none;
  position: relative;
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
}

#mouseSwipeScroll .panel {
  float: left;
  margin: 0;
  padding: 0;
  width: 130px;
  height: 535px;
  overflow: hidden;
}

#mouseSwipeScroll .panel .item {
  position: relative;
  margin: 0;
  padding: 0 5px 5px 5px;
  width: 120px;
  height: 130px;
}

Javascript:

$(function() { 
  sortTiles = function() {
        var panels = $('.panel');
        var items = $(panels).children('.item');
        var sortedItems = $(items).clone();

        // sort //
        sortedItems.sort(function(a, b) {
            return parseInt($(b).data('state')) - parseInt($(a).data('state'));
        });

        // wrap into panels again //
        $.each(sortedItems, function(i, el) {
            if(i % 4 == 0) {
                sortedItems.slice(i , i+4).wrapAll('<div class="panel">');
            }
        });

        // animate //
        $(panels).quicksand(sortedItems, {
            duration: 800,
            easing: 'easeInOutQuad'
        });
      }
});

$(document).ready(function() {

      $('#tiles_viewport').iosSlider({
        snapToChildren: true,
        desktopClickDrag: true,
        startAtSlide: 4
      });
});

The sort isn't working, and also wrapAll doesn't add the enclosing panel div. been looking at this for quite some time, so would be great for some advice.

many thanks,

rob.

2

There are 2 best solutions below

0
On

The flaw in your code is sort() only sorts the jQuery object but it doesn't change the DOM. Following simply adds one line to empty the existing content and changes the wrapAll concept to creating a new div and immediately inserting it into the DOM

var panels = $('.panel');
var items = $(panels).children('.item');
var sortedItems = $(items).clone(); // sort //

$('#content').empty();

sortedItems.sort(function(a, b) {
    return parseInt($(b).data('state')) - parseInt($(a).data('state'));
});

$.each(sortedItems, function(i, el) {
    if (i % 4 == 0) {
        $('<div class="panel">').append(  sortedItems.slice(i, i + 4)).appendTo('#content')
    }
});

DEMO: http://jsfiddle.net/yMtwp/

3
On

I think your problem is mainly related to sand-sorting the items across several panels, which causes the sand-sorting plugin to misbehave. If you can do without the panels, I'd recommend you put them into 1 panel only and everything will work fine.

If not, I propose the solution below, where you have a container for all your panels, do the sand-sort over this super-panel, and then reconstruct the panels after the sand-sorting is finished. I am putting a working example below:

<html>
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="http://gsgd.co.uk/sandbox/jquery/easing/jquery.easing.1.3.js"></script>
<script type="text/javascript" src="https://github.com/razorjack/quicksand/raw/master/jquery.quicksand.js"></script>
<script type="text/javascript">
    function sortTiles() {
        var superpanel = $('.superpanel');
        var items = superpanel.find('.item');
        var sortedItems = items.clone();

        // sort //
        sortedItems.sort(function(a, b) {
            return parseInt($(b).data('state')) - parseInt($(a).data('state'));
        });

        // animate //
        superpanel.quicksand(sortedItems, {
            duration: 800
        }, function() {
           // wrap into panels again //
           var items = $('.superpanel .item');
           for(i=0; i<items.length; i+=4) {
                items.slice(i , i+4).wrapAll('<div class="panel">');
           }
        });

    }   
    $(function() {
        sortTiles();
    });
    </script>     
</head>
<html>
<body>
    <div class="superpanel">
        <div class="panel">
            <div class="item" data-id="4" data-state="4">Content 4</div>
            <div class="item" data-id="1" data-state="1">Content 1</div>
            <div class="item" data-id="3" data-state="3">Content 3</div>
            <div class="item" data-id="2" data-state="2">Content 2</div>
        </div>
        <div class="panel">
            <div class="item" data-id="8" data-state="8">Content 8</div>
            <div class="item" data-id="5" data-state="5">Content 5</div>
            <div class="item" data-id="7" data-state="7">Content 7</div>
            <div class="item" data-id="6" data-state="6">Content 6</div>
        </div>
    </div>
</body>
</html>

EDIT

Here is another proposal to make the columns and in the same time have them in one panel, instead of regrouping which would make the animation ugly.

<html>
<head>
<style>
    .item {
        display: inline-block;
        width: 40%;
    }
</style>

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="http://gsgd.co.uk/sandbox/jquery/easing/jquery.easing.1.3.js"></script>
<script type="text/javascript" src="https://github.com/razorjack/quicksand/raw/master/jquery.quicksand.js"></script>
<script type="text/javascript">
    function sortTiles() {
        var superpanel = $('.superpanel');
        var items = superpanel.find('.item');
        var sortedItems = items.clone();

        // sort //
        sortedItems.sort(function(a, b) {
            return parseInt($(b).data('state')) - parseInt($(a).data('state'));
        });

        // animate //
        superpanel.quicksand(sortedItems, {
            duration: 800
        });

    }   
    $(function() {
        window.setTimeout(sortTiles, 1000);
    });
    </script>     
</head>
<html>
<body>
    <div class="superpanel">
            <div class="item" data-id="4" data-state="4">Content 4</div>
            <div class="item" data-id="1" data-state="1">Content 1</div>
            <div class="item" data-id="3" data-state="3">Content 3</div>
            <div class="item" data-id="2" data-state="2">Content 2</div>
            <div class="item" data-id="8" data-state="8">Content 8</div>
            <div class="item" data-id="5" data-state="5">Content 5</div>
            <div class="item" data-id="7" data-state="7">Content 7</div>
            <div class="item" data-id="6" data-state="6">Content 6</div>
    </div>
</body>
</html>