Mr. B.
Mr. B.

Reputation: 8717

jQuery: How to filter contents with jQuery?

I've a list with items I would like to filter by switch on/off (select, radio, checkbox) and sort by fields (name, date, ...).

The code below is okay for basic filtering but it's not a good way. I would like to know how to do it in a professional way. Any good jQuery plugins out there? I don't want a widget, just the filtering/sorting engine behind it.

# this code is pseudocode and not running! # 
<script>
// ready
$(function() {
    // get items
    var items = jQuery.parseJSON("items_json.php");

    // items filtered
    var items_filtered = new Array();

    // conditions/relations for filtering
    var filter1_relations = jQuery.parseJSON("filter1_relations.php");
    var filter2_relations = jQuery.parseJSON("filter2_relations.php");

    // build unfiltered list
    build_list(items);

    // build filtered list
    $(".filter").on("change", function() {
        items_filtered = run_filter1(items, filter1_relations);
        items_filtered = run_filter2(items_filtered, filter2_relations);
        build_list(items_filtered);
    });
});

// filters the 'items' by checking if a 'relation' exists
function run_filter1(items, relations) {
    items_filterd = new Array();
    $.each(items, function(key, item) {
        for (var i = 0; i < relations.length; i++) {
            if (...) {
                items_filtered.push(item);
            }
        }
    });
    return items_filtered;
}

// build list and add to #content
function build_list(items) {
    html = '<ul>';
    for (var i = 0; i < items.length; i++) {
        html += '<li>'+ items[i].name +'</li>';
    }
    html += '</ul>';

    $("#content").html(html);
}
</script>
Filter 1.1: <input type="checkbox" name="filter1_condition1" value="1" class="filter"/><br/>
Filter 1.2: <input type="checkbox" name="filter1_condition1" value="1" class="filter"/><br/>
Filter 2.1: <input type="checkbox" name="filter1_condition1" value="1" class="filter"/><br/>
Filter 2.1: <input type="checkbox" name="filter1_condition1" value="1" class="filter"/><br/>
<div id="content"></div>

I found this code by searching stackoverflow but it's not that extensive.

Thanks in advance!

Upvotes: 0

Views: 744

Answers (2)

mikakun
mikakun

Reputation: 2265

instead of looping every time on change, once you have the data (providing you cannot structure your data before sending by server via sql or php or both), create right away the arrays for each filter

//loop data
//loop filter conditions
//if match
if (!filter_results[filter])   filter_results[filter]=new Array () 
filter_results[filter].push(data)

edit : can use index instead of push (it's faster)

var i = -1;

then in the loop

filter_results[filter][++i]=data

(or an array of index if there are many of them, creating new one when creating the new Array))

so yes just like index then on change you just create your html from the good array

 var html='<ul><li>'+ filter_results[filterselected].join('</li><li>')+'</li></ul>'

one way or another, you'll have to loop through, with this way you'll just loop through it once for all (i had to deal with stg similar not long ago -receiving 100/200kb of pregzip data at each call- & after much thinking/experimenting/evaluating memory usage i went for that way)

Upvotes: 1

robertklep
robertklep

Reputation: 203419

I just implemented a rather complex form (with lots of "if this option is selected, those items should become visible") using KnockOut, which is really very useful for this sort of thing.

You'd need to setup your conditions in a KnockOut view model, but then you can bind against those conditions and, for example, show items only if a certain condition is met:

<input type="checkbox" data-bind="visible: filter1_condition1" value="1" class="filter"/>

Upvotes: 1

Related Questions