简体   繁体   中英

Jquery advanced filtering of elements

I have a large list of elements with data attributes.

<ul>
   <li data-brandid="1" data-finishid="5" data-typeid="10" data-constructionid="14">
   <li data-brandid="4" data-finishid="1" data-typeid="3" data-constructionid="7">
   <li data-brandid="18" data-finishid="2" data-typeid="1" data-constructionid="4">
   <li data-brandid="7" data-finishid="4" data-typeid="4" data-constructionid="5">
   <li data-brandid="4" data-finishid="8" data-typeid="1" data-constructionid="2">
   <li data-brandid="2" data-finishid="12" data-typeid="2" data-constructionid="16">
</ul>

At the top of the page, I have a form with checkboxes for each option for each attribute. They can select multiple options for each data attribute. So, for example, if they selected brandsid's 2 and 5, finishid's 1 and 4, typeid's 4 and 2 and constructionid's 1 and 14 the pseudocode(SQL style) would look something like this:

AND (brandid = 2 OR brandid = 5)
AND (finishid = 1 OR finishid = 4)
AND (typeid = 4 OR typeid= 2)
AND (constructionid = 1 OR 14)

But I'm not sure how to turn this into a jquery selector.

Thanks.

You can use patterns in jQuery like this -

$('li[data-brandid^=1][data-finishid^=5]')

Which looks for those attributes consisting of 1 and 5 correspondingly.

Here is a code snippet you could use -

 var choose = function(brandId, finishId, typeid, constructionid){ // Search through brandid and finishid var sel = $('li[data-brandid^=' + brandId + '][data-finishid^='+ finishId +'][data-typeid^='+ typeid +'][data-constructionid^='+ constructionid +']') $('div').append(sel); }; $('#go').on('click', function(){ var brandIds = []; var constructionIds = []; var typeIds = []; var finishIds = []; if($('#brandid').val().indexOf(',') != -1) brandIds = $('#brandid').val().split(','); if($('#finishid').val().indexOf(',') != -1) finishIds = $('#finishid').val().split(','); if($('#typeid').val().indexOf(',') != -1) typeIds = $('#typeid').val().split(','); if($('#constructionid').val().indexOf(',') != -1) constructionIds = $('#constructionid').val().split(','); $.each(brandIds, function(brInd, brand){ $.each(finishIds, function(finId, finish){ $.each(typeIds, function(typeId, type){ $.each(constructionIds, function(conId, construction){ choose(brand, finish, type, construction); }); }); }); }); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> Brand ID <input type="text" id="brandid" /> Finish ID <input type="text" id="finishid" /> Type ID <input type="text" id="typeid" /> Construction ID <input type="text" id="constructionid"> <button id="go">Go!</button> <br/><br/> Available (Brand - Finish - Type - Construction) <ul> <li data-brandid="1" data-finishid="5" data-typeid="10" data-constructionid="14">1 - 5 - 10 - 14</li> <li data-brandid="4" data-finishid="1" data-typeid="3" data-constructionid="7">4 - 1 - 3 - 7</li> <li data-brandid="18" data-finishid="2" data-typeid="1" data-constructionid="4">18 - 2 - 1 - 4</li> <li data-brandid="7" data-finishid="4" data-typeid="4" data-constructionid="5">7 - 4 - 4 - 5</li> <li data-brandid="4" data-finishid="8" data-typeid="1" data-constructionid="2">4 - 8 - 1 - 2</li> <li data-brandid="2" data-finishid="12" data-typeid="2" data-constructionid="16">2 - 12 - 2 - 16</li> </ul> Selected (Brand - Finish - Type - Construction) <div id="selected"></div> 

EDIT: For multiple values, using a $.each

I just wrote a filter like this and its actually quite easy if you know how to start.

We assume that every active filter has a class="active" . We furthermore assume that every checkbox has a data-attribute which holds the name of the filter (eg data-filter="brandid" and a data-attribute which holds the value which should be selected (eg data-value="1" ).

This assumed we can start building the function

$items = $('li');

// Whenever a user changes a checkbox we want to filter our data
$('input[type="checkbox"]').change(function(){

    // We toggle the active-class to dis/enable our filter
    $(this).toggleClass('active');

    // We need an object holding our filters
    var filter = {};
    var $filtered = $items;

    // We select all active filter here and push them to the array
    $('input[type="checkbox"].active').each(function(){

        // When a filter with this type didnt exists in our object we create a new one
        if(filters[$(this).data('filter')] === undefined) filters[$(this).data('filter')] = {};

        // Then we push the filter to our array
        filters[$(this).data('filter')].push($(this).data('value'));

    });

    // We loop through every filter, select all elements which match the
    // filter and apply it to the $filtered selection
    // The items left is the desired collection
    for(var i in filters){

        // For every filter in our object
        // (which can hold multiple filters of one type)
        // we build a selector.
        // We join the selectors using `,` to get an `or`-selection
        selector = filters[i].map(function(value){
            return '[data-'+i+'="'+value+'"]';
        }).join(',');

        // Apply the filter
        $filtered = $filtered.filter(selector);
    }

    // $filtered now holds all elemets left
    // do with this elements what you want

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM