user123456789
user123456789

Reputation: 566

combining multiple jquery filters (UI slider, checkbox)

I want a page where I will display a bunch of div's, the div's will be displayed is based on selections made on the page.

Here i'm using two types of filters i.e., jQuery ui slider(price range) and checkbox

Both are working fine separately, but i want to combine both

I'm unable to find a trick that which combines both the filters

Fiddle: Working Demo

HTML

<div id="slider-container">
 <p>
  <input type="text" id="amount" style="border: 0; color: #f6931f; font-weight: bold;" />
</p>
</div>

<ul id="filters">
    <li>
        <input type="checkbox" value="categorya" id="filter-categorya" />
        <label for="filter-categorya">Category A</label>
    </li>
    <li>
        <input type="checkbox" value="categoryb" id="filter-categoryb" />
        <label for="filter-categoryb">Category B</label>
    </li>
</ul>

<hr>
    <h3>Results</h3>
<div id="computers">
    <div class="system categorya categoryb" data-price="299">A, B -  299</div>
    <div class="system categorya" data-price="599">A -  599</div>
    <div class="system categoryb" data-price="1099">B -  1099</div>
</div>
<div id="slider-range"></div>

jQuery

 $(function() {
        $('#slider-container').slider({
            range: true,
            min: 299,
            max: 1099,
            values: [ 299, 1099 ],
            slide: function(event, ui) {
                $( "#amount" ).val( "$" + ui.values[ 0 ] + " - $" + ui.values[ 1 ] );
                var mi = ui.values[ 0 ];
                var mx = ui.values[ 1 ];
                filterSystem(mi, mx);
            }
        });
      $( "#amount" ).val( "$" + $( "#slider-container" ).slider( "values", 0 ) +
      " - $" + $( "#slider-container" ).slider( "values", 1 ) );
  });

function filterSystem(minPrice, maxPrice) {
    $("#computers div.system").hide().filter(function() {
        var price = parseInt($(this).data("price"), 10);
        return price >= minPrice && price <= maxPrice;
    }).show();
}

$("#filters :checkbox").click(function() {
    $("#computers div.system").hide();
    $("#filters :checkbox:checked").each(function() {
        $("." + $(this).val()).show();
    });
});

Can anyone help me to combine these two filters.

Thanks in Advance, sorry for my poor english

Upvotes: 2

Views: 2899

Answers (1)

omma2289
omma2289

Reputation: 54639

You could combine both filters in a single function filterSystem() that you call on every state change of both the slider and the checkboxes:

UPDATE

Here's an update that accommodates for multiple checkbox filters:

$(function () {
    var minPrice = 299,
        maxPrice = 1099,
        $filter_lists = $("#filters ul"),
        $filter_checkboxes = $("#filters :checkbox"),
        $items = $("#computers div.system");

    $filter_checkboxes.click(filterSystem); //Call filter function on checkbox change

    $('#slider-container').slider({
        range: true,
        min: minPrice,
        max: maxPrice,
        values: [minPrice, maxPrice],
        slide: function (event, ui) {
            $("#amount").val("$" + ui.values[0] + " - $" + ui.values[1]);
            minPrice = ui.values[0];
            maxPrice = ui.values[1];
            filterSystem(); //Call filter function on slider change
        }
    });
    $("#amount").val("$" + minPrice + " - $" + maxPrice);

    //Slider filter
    function filterSlider(elem) {
        var price = parseInt($(elem).data("price"), 10);
        console.log(price);
        return price >= minPrice && price <= maxPrice;
    }

    //Checkbox filter 
    function filterCheckboxes(elem) {
        var $elem = $(elem),
            passAllFilters = true;
        $filter_lists.each(function () {
            var classes = $(this).find(':checkbox:checked').map(function () {
                return $(this).val();
            }).get();
            var passThisFilter = false;
            $.each(classes, function (index, item) {
                if ($elem.hasClass(item)) {
                    passThisFilter = true;
                    return false; //stop inner loop
                }
            });
            if (!passThisFilter) {
                passAllFilters = false;
                return false; //stop outer loop
            }
        });
        return passAllFilters;
    }

    //Combine checkbox and slider filters
    function filterSystem() {
        $items.hide().filter(function () {
            return filterSlider(this) && filterCheckboxes(this);
        }).show();
    }
});

Here's the updated fiddle

Note that this approach needs to have the checkbox lists wrapped in a container #filters

Upvotes: 3

Related Questions