Объединение элементов для фильтрации с изотопом - PullRequest
3 голосов
/ 25 октября 2011

В настоящее время я использую Isotope для фильтрации списка публикаций, но хотел бы иметь возможность комбинировать стандартный, документированный метод фильтра ссылок с элементом select, поскольку мой второй список фильтров довольно длинный.

Бит, с которым я борюсь, связан с двумя различными типами элементов и объединением выбранных значений в один массив параметров . Я могу заставить фильтры работать независимо друг от друга (код ниже), но они должны работать вместе. Как объединить два разных действия (щелкнуть или изменить) и два атрибута (класс = или значение =) в один массив параметров для передачи в фильтр изотопов?

    var $container = $('#library');
// select ccskills publications by default
$container.isotope({ filter: '.ccskills' });

var $optionSets = $('#library-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;
    $container.isotope( options );
    return false;
});

    // using the 'chozen' plugin to style my select element
$(".chzn-select").chosen().change(
    function() {
        var industry = $("option:selected", this).val();
        $container.isotope({filter: industry});
    }
);

1 Ответ

15 голосов
/ 10 декабря 2013

Вам нужен многомерный массив с размером массива для каждого типа фильтра. Я делал это раньше, и есть живой пример здесь !

Смотрите здесь ! для JS.

В моем js-файле вас заинтересует конечная функция getComboFilters (filters)

function getComboFilter( filters ) {
    var i = 0;
    var comboFilters = [];
    var message = [];
    for ( var prop in filters ) {
        message.push( filters[ prop ].join(' ') );
        var filterGroup = filters[ prop ];
        // skip to next filter group if it doesn't have any values
        if ( !filterGroup.length ) {
            continue;
        }
        if ( i === 0 ) {
            // copy to new array
            comboFilters = filterGroup.slice(0);
        }
        else {
            var filterSelectors = [];
            // copy to fresh array
            var groupCombo = comboFilters.slice(0); // [ A, B ]
            // merge filter Groups
            for (var k=0, len3 = filterGroup.length; k < len3; k++) {
                for (var j=0, len2 = groupCombo.length; j < len2; j++) {
                    filterSelectors.push( groupCombo[j] + filterGroup[k] ); // [ 1, 2 ]
                }
            }
            // apply filter selectors to combo filters for next group
            comboFilters = filterSelectors;
        }
        i++;
    }
    comboFilters.sort();
    var comboFilter = comboFilters.join(', ');
    return comboFilter;
}

Эта функция обрабатывает все операции извлечения, объединения и сортировки различных наборов массивов фильтров, но чтобы использовать их, вам нужно добавить их в свою процедуру фильтрации ... ну, я говорю, что эта процедура действительно, потому что вы, кажется, вызываете метод фильтрации 2 отдельных раза:

$container.isotope({ filter: '.ccskills' });

и позже:

 $container.isotope({filter: .industry});

Если вы собираетесь фильтровать типы вместе, все ваши типы фильтров должны будут знать друг о друге, то есть они должны быть внутри одного и того же javascript-приложения, и метод фильтра должен вызываться только один раз в в какое время он проверяется на соответствие всем условиям типа фильтра.

используя функцию getComboFilter (filters), вы вызываете метод комбинированного фильтра следующим образом:

var $container = $('#library');
var filters = {};
var comboFilter = getComboFilter( filters );
$container.isotope({ filter: comboFilter });

Наконец, полная интеграция в ваш файл будет выглядеть примерно так:

var $container = $('#library');
var filters = {};
var comboFilter = getComboFilter( filters );
$container.isotope({ filter: comboFilter });

// This next part targets all the possible filter items
// i.e. '.option-set a' just like your example

$('.option-set a').click(function(){
        // exit directly if filter already disabled
        if ($(this).hasClass('disabled') ){
            return false;
        }
        var $this = $(this);
        var $optionSet = $(this).parents('.option-set');
        var group = $optionSet.attr('data-filter-group');
        // store filter value in object
        var filterGroup = filters[ group ];
        if ( !filterGroup ) {
            filterGroup = filters[ group ] = [];
        }
        var comboFilter = getComboFilter( filters );
        $container.isotope({ filter: comboFilter });
});
function getComboFilter( filters ) {
    var i = 0;
    var comboFilters = [];
    var message = [];
    for ( var prop in filters ) {
        message.push( filters[ prop ].join(' ') );
        var filterGroup = filters[ prop ];
        // skip to next filter group if it doesn't have any values
        if ( !filterGroup.length ) {
            continue;
        }
        if ( i === 0 ) {
            // copy to new array
            comboFilters = filterGroup.slice(0);
        }
        else {
            var filterSelectors = [];
            // copy to fresh array
            var groupCombo = comboFilters.slice(0); // [ A, B ]
            // merge filter Groups
            for (var k=0, len3 = filterGroup.length; k < len3; k++) {
                for (var j=0, len2 = groupCombo.length; j < len2; j++) {
                    filterSelectors.push( groupCombo[j] + filterGroup[k] ); // [ 1, 2 ]
                }
            }
            // apply filter selectors to combo filters for next group
            comboFilters = filterSelectors;
        }
        i++;
    }
    comboFilters.sort();
    var comboFilter = comboFilters.join(', ');
    return comboFilter;
}

Надеюсь, это кому-нибудь поможет! Демо-версия довольно гладкая.

...