Pergunta

I am using isotope to filter and sort elements by name, date or category, descending or ascending within a main container.

I need to keep the first element in the top left hand corner so that it is unaffected by sorting. I have managed to get this working except for when sorting by ascending / decending. The first element is sorted and after a number of different sorting selections are made, gaps appear on the page. When I look at the code where the gaps are, its the code for the first element being repeated in various different places on the page depending on how many selections of sorting are made.

How do I get the first element to behave? Below is my code.

            //isotope set up
            var $container = $('#container'),
                 filters = {};
                 $container.isotope({
                itemSelector: '.element',
                masonry: {
                    columnWidth: 260
                },
                getSortData: {
                    category: function($elem) {
                        if ($elem.is('.first_static')) {
                            return -1;
                        }
                        return $elem.attr('data-category');
                    },
                    date: function($elem) {
                        if ($elem.is('.first_static')) {
                            return -1;
                        }
                        return $elem.attr('data-expiry');
                    },
                    name: function($elem) {
                        if ($elem.is('.first_static')) {
                            return -1;
                        }
                        return $elem.find('.name').text();
                    },
                    first: function($elem) {
                        // sort by first_static first, then by original order
                        return ($elem.hasClass('first_static') ? -500 : 0) + $elem.index();
                    }
                },
                sortBy: 'first'
            });

                //sort page elements
                $('.sort a').click(function(e) {
                    var $this = $(this);
                    if ($this.hasClass('selected')) {
                        return false;
                    }
                    var $sortSet = $this.parents('.sort-set');
                    $sortSet.find('.selected').removeClass('selected');
                    $this.addClass('selected');
                    var sorts = {},
                            key = $sortSet.attr('data-option-key'),
                            value = $this.attr('data-option-value');

                    value = value === 'false' ? false : value;
                    sorts[ key ] = value;


            $container.isotope(sorts).isotope('reloadItems');

            return false;
        });

Im working on a JSFiddle (http://jsfiddle.net/AbUgj/30/) to demonstrate what Im trying to do. There should always be a blue box in the top left regardless of filter or sort.

HTML

<h3>Sorting</h3><br />
                            <div class="option-combo sort">
                                <ul data-filter-group="sort" class="sort sort-set clearfix" data-option-key="sortBy">
                                    <li><a href="#" data-option-value="name">Name</a></li>
                                    <li><a href="#" data-option-value="category">Category</a></li>
                                    <li><a href="#" data-option-value="date">Expiry Date</a></li>

                                </ul>
                            </div>
                            <div class="option-combo sort">
                                <ul data-filter-group="sort" class="sort sort-set clearfix" data-option-key="sortAscending">
                                    <li><a href="#" data-option-value="true" id="sortByCatAsc">Ascending</a></li>
                                    <li><a href="#" data-option-value="false" id="sortByCatDesc">Descending</a></li>
                                </ul>
                        </div>
Foi útil?

Solução

Create different sorting categories depending of Ascending/Descending mode, like this:

...
name_asc: function($elem) {
    if ($elem.is('.first_static')) return "aaaa";
    return $elem.find('.name').text();
},
name_desc: function($elem) {
    if ($elem.is('.first_static')) return "zzzz";
    return $elem.find('.name').text();
},
...

To sort, you don't need to call reloadItems:

$('#sortByNameAsc').click()(function() {
    $("#container")isotope({sortBy : 'name_asc', sortAscending : true});
});

$('#sortByNameDesc').click()(function() {
    $("#container").isotope({sortBy : 'name_desc', sortAscending : false});
});

Or using a more generic approach:

<div class="option-combo sort">
    <ul class="sort sort-set clearfix sortKey">
        <li><a href="#" data-option-value="name" class="selected">Name</a></li>
        <li><a href="#" data-option-value="category">Category</a></li>
        <li><a href="#" data-option-value="date">Expiry Date</a></li>
    </ul>
</div>
<div class="option-combo sort">
    <ul class="sort sort-set clearfix sortOrder">
        <li><a href="#" data-option-value="asc" class="selected">Ascending</a></li>
        <li><a href="#" data-option-value="desc">Descending</a></li>
    </ul>
</div>

And script:

$('.sort a').click(function(e) {
    var $this = $(this);

    // Turn 'selected' class on/off
    if ($this.hasClass('selected')) return false;
    $this.parents('.sort-set').find('.selected').removeClass('selected');
    $this.addClass('selected');

    var key = $('.sortKey a.selected').attr('data-option-value');
    var order = $('.sortOrder a.selected').attr('data-option-value');

    var valBy = key + '_' + order; // For instance name_asc
    var valAscending = (order == "asc"); // true for 'asc', false otherwise

    $("#container").isotope({sortBy : valBy, sortAscending : valAscending});

    return false;
});
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top