Reputation: 8717
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
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
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