I'm trying to get some client-side filtering going by decorating some "cards" with data-* attributes to filter on. I'm having some successes and some failures :)
I've created a fiddle at:
This is work in an existing project and I've stripped out quite a bit of code to get this down to a bare bones demo.
In a nutshell, I'm looping over each card, extracting the data-* attributes into vars, then looping over the selected filters. I then do a comparison of the data-* attributes and the filter values and set a matched flag if appropriate. That then drives the display state of each card.
Where I seem to be hitting a wall is down around line 56 in the fiddle JS pane. It's the else condition with two lines of comments. Basically, if I include that branch of code the filters work with one filter selection across each filter facet/category. If I comment out the else code the filter works with multiple selections within the same filter facet/category.
What I'm trying to accomplish is to filter down the cards to whatever is checked in the filters. If I select "gold, $2,001-$4,000, CCN" I only want to see any cards that have those corresponding data-* attributes. I don't want to see a "silver $2,001-$400" or a "bronze CCN" card.
I'm wondering if anyone has any ideas on how to get proper filtering applied to my fiddle.
Here's the code from the fiddle as well, though the fiddle is probably easier to work with:
<!--metallic level-->
<fieldset>
<p>metal</p>
<ol>
<li>
<label for="metallic1">
<input type="checkbox" value="platinum" id="metallic1" name="checkbox" data-filter-facet="metallic">
<span>Platinum</span>
</label>
</li>
<li>
<label for="metallic2">
<input type="checkbox" value="gold" id="metallic2" name="checkbox" data-filter-facet="metallic">
<span>Gold</span>
</label>
</li>
<li>
<label for="metallic3">
<input type="checkbox" value="silver" id="metallic3" name="checkbox" data-filter-facet="metallic">
<span>Silver</span>
</label>
</li>
<li>
<label for="metallic4">
<input type="checkbox" value="bronze" id="metallic4" name="checkbox" data-filter-facet="metallic">
<span>Bronze</span>
</label>
</li>
<li>
<label for="metallic5">
<input type="checkbox" value="catastrophic" id="metallic5" name="checkbox" data-filter-facet="metallic">
<span>Catastrophic</span>
</label>
</li>
</ol>
</fieldset>
<!--deductible-->
<fieldset>
<p>deductible</p>
<ol>
<li>
<label for="deductible1">
<input type="checkbox" value="deductible0-2" id="deductible1" name="checkbox" data-filter-facet="deductible">
<span>$0 - $2,000</span>
</label>
</li>
<li>
<label for="deductible2">
<input type="checkbox" value="deductible2-4" id="deductible2" name="checkbox" data-filter-facet="deductible">
<span>$2,001 - $4,000</span>
</label>
</li>
<li>
<label for="deductible3">
<input type="checkbox" value="deductible4+" id="deductible3" name="checkbox" data-filter-facet="deductible">
<span>$4,001+</span>
</label>
</li>
</ol>
</fieldset>
<!--network-->
<fieldset>
<p>network</p>
<ol>
<li>
<label for="network1">
<input type="checkbox" value="beacon" id="network1" name="checkbox" data-filter-facet="network">
<span>Beacon</span>
</label>
</li>
<li>
<label for="network2">
<input type="checkbox" value="ccn" id="network2" name="checkbox" data-filter-facet="network">
<span>CCN</span>
</label>
</li>
<li>
<label for="network3">
<input type="checkbox" value="rosecity" id="network3" name="checkbox" data-filter-facet="network">
<span>Rose City</span>
</label>
</li>
</ol>
</fieldset>
<!--features-->
<fieldset>
<p>features</p>
<ol>
<li>
<label for="features1">
<input type="checkbox" value="alternativecare" id="features1" name="checkbox" data-filter-facet="features">
<span>Alternative care</span>
</label>
</li>
<li>
<label for="features2">
<input type="checkbox" value="healthsavingsaccount" id="features2" name="checkbox" data-filter-facet="features">
<span>Health savings account</span>
</label>
</li>
<li>
<label for="features3">
<input type="checkbox" value="pediatricdental" id="features3" name="checkbox" data-filter-facet="features">
<span>Pediatric dental</span>
</label>
</li>
</ol>
</fieldset>
</div>
<hr>
<p class="bold">
<span class="plan-count" style="color:red;">count</span> plans available
</p>
<!--start plan card-->
<div class="plan-card mobile-card"
data-filter-metal="gold"
data-filter-deductible="deductible0-2"
data-filter-network="rosecity"
data-filter-features="alternativecare">
<div class="row card-padding">
<div class="row">
<div class="twelve columns">
<p>sample decorated plan card with attributes to filter on</p>
<pre>
data-filter-metal="gold"
data-filter-deductible="deductible0-2"
data-filter-network="rosecity"
data-filter-features="alternativecare"
</pre>
</div>
</div>
</div>
</div>
<!--end plan-card-->
<!--start plan card-->
<div class="plan-card mobile-card"
data-filter-metal="silver"
data-filter-deductible="deductible0-2"
data-filter-network="ccn"
data-filter-features="healthsavingsaccount">
<div class="row card-padding">
<div class="row">
<div class="twelve columns">
<p>sample decorated plan card with attributes to filter on</p>
<pre>
data-filter-metal="silver"
data-filter-deductible="deductible0-2"
data-filter-network="ccn"
data-filter-features="healthsavingsaccount"
</pre>
</div>
</div>
</div>
</div>
<!--end plan-card-->
<!--start plan card-->
<div class="plan-card mobile-card"
data-filter-metal="bronze"
data-filter-deductible="deductible4+"
data-filter-network="rosecity"
data-filter-features="pediatricdental">
<div class="row card-padding">
<div class="row">
<div class="twelve columns">
<p>sample decorated plan card with attributes to filter on</p>
<pre>
data-filter-metal="bronze"
data-filter-deductible="deductible4+"
data-filter-network="rosecity"
data-filter-features="pediatricdental"
</pre>
</div>
</div>
</div>
</div>
<!--end plan-card-->
<!--start plan card-->
<div class="plan-card mobile-card"
data-filter-metal="platinum"
data-filter-deductible="deductible0-2"
data-filter-network="beacon"
data-filter-features="alternativecare">
<div class="row card-padding">
<div class="row">
<div class="twelve columns">
<p>sample decorated plan card with attributes to filter on</p>
<pre>
data-filter-metal="platinum"
data-filter-deductible="deductible0-2"
data-filter-network="beacon"
data-filter-features="alternativecare"
</pre>
</div>
</div>
</div>
</div>
<!--end plan-card-->
<!--start plan card-->
<div class="plan-card mobile-card"
data-filter-metal="gold"
data-filter-deductible="deductible2-4"
data-filter-network="ccn"
data-filter-features="healthsavingsaccount">
<div class="row card-padding">
<div class="row">
<div class="twelve columns">
<p>sample decorated plan card with attributes to filter on</p>
<pre>
data-filter-metal="gold"
data-filter-deductible="deductible2-4"
data-filter-network="ccn"
data-filter-features="healthsavingsaccount"
</pre>
</div>
</div>
</div>
</div>
<!--end plan-card-->
<!--start plan card-->
<div class="plan-card mobile-card"
data-filter-metal="silver"
data-filter-deductible="deductible2-4"
data-filter-network="rosecity"
data-filter-features="healthsavingsaccount">
<div class="row card-padding">
<div class="row">
<div class="twelve columns">
<p>sample decorated plan card with attributes to filter on</p>
<pre>
data-filter-metal="silver"
data-filter-deductible="deductible2-4"
data-filter-network="rosecity"
data-filter-features="healthsavingsaccount"
</pre>
</div>
</div>
</div>
</div>
<!--end plan-card-->
<!--start plan card-->
<div class="plan-card mobile-card"
data-filter-metal="silver"
data-filter-deductible="deductible4+"
data-filter-network="beacon"
data-filter-features="healthsavingsaccount">
<div class="row card-padding">
<div class="row">
<div class="twelve columns">
<p>sample decorated plan card with attributes to filter on</p>
<pre>
data-filter-metal="silver"
data-filter-deductible="deductible4+"
data-filter-network="beacon"
data-filter-features="healthsavingsaccount"
</pre>
</div>
</div>
</div>
</div>
<!--end plan-card-->
<!--start plan card-->
<div class="plan-card mobile-card"
data-filter-metal="bronze"
data-filter-deductible="deductible0-2"
data-filter-network="rosecity"
data-filter-features="alternativecare">
<div class="row card-padding">
<div class="row">
<div class="twelve columns">
<p>sample decorated plan card with attributes to filter on</p>
<pre>
data-filter-metal="bronze"
data-filter-deductible="deductible0-2"
data-filter-network="rosecity"
data-filter-features="alternativecare"
</pre>
</div>
</div>
</div>
</div>
<!--end plan-card-->
<!--start plan card-->
<div class="plan-card mobile-card"
data-filter-metal="platinum"
data-filter-deductible="deductible0-2"
data-filter-network="ccn"
data-filter-features="alternativecare">
<div class="row card-padding">
<div class="row">
<div class="twelve columns">
<p>sample decorated plan card with attributes to filter on</p>
<pre>
data-filter-metal="platinum"
data-filter-deductible="deductible0-2"
data-filter-network="ccn"
data-filter-features="alternativecare"
</pre>
</div>
</div>
</div>
</div>
<!--end plan-card-->
<!--start plan card-->
<div class="plan-card mobile-card"
data-filter-metal="platinum"
data-filter-deductible="deductible2-4"
data-filter-network="beacon"
data-filter-features="alternativecare">
<div class="row card-padding">
<div class="row">
<div class="twelve columns">
<p>sample decorated plan card with attributes to filter on</p>
<pre>
data-filter-metal="platinum"
data-filter-deductible="deductible2-4"
data-filter-network="beacon"
data-filter-features="alternativecare"
</pre>
</div>
</div>
</div>
</div>
<!--end plan-card-->
<!--start plan card-->
<div class="plan-card mobile-card"
data-filter-metal="gold"
data-filter-deductible="deductible2-4"
data-filter-network="ccn"
data-filter-features="pediatricdental">
<div class="row card-padding">
<div class="row">
<div class="twelve columns">
<p>sample decorated plan card with attributes to filter on</p>
<pre>
data-filter-metal="gold"
data-filter-deductible="deductible2-4"
data-filter-network="ccn"
data-filter-features="pediatricdental"
</pre>
</div>
</div>
</div>
</div>
<!--end plan-card-->
<!--start plan card-->
<div class="plan-card mobile-card"
data-filter-metal="silver"
data-filter-deductible="deductible4+"
data-filter-network="ccn"
data-filter-features="pediatricdental">
<div class="row card-padding">
<div class="row">
<div class="twelve columns">
<p>sample decorated plan card with attributes to filter on</p>
<pre>
data-filter-metal="silver"
data-filter-deductible="deductible4+"
data-filter-network="ccn"
data-filter-features="pediatricdental"
</pre>
</div>
</div>
</div>
</div>
<!--end plan-card-->
<!--start plan card-->
<div class="plan-card mobile-card"
data-filter-metal="silver"
data-filter-deductible="deductible0-2"
data-filter-network="beacon"
data-filter-features="healthsavingsaccount">
<div class="row card-padding">
<div class="row">
<div class="twelve columns">
<p>sample decorated plan card with attributes to filter on</p>
<pre>
data-filter-metal="silver"
data-filter-deductible="deductible0-2"
data-filter-network="beacon"
data-filter-features="healthsavingsaccount"
</pre>
</div>
</div>
</div>
</div>
<!--end plan-card-->
<!--start plan card-->
<div class="plan-card mobile-card"
data-filter-metal="bronze"
data-filter-deductible="deductible4+"
data-filter-network="beacon"
data-filter-features="healthsavingsaccount">
<div class="row card-padding">
<div class="row">
<div class="twelve columns">
<p>sample decorated plan card with attributes to filter on</p>
<pre>
data-filter-metal="bronze"
data-filter-deductible="deductible4+"
data-filter-network="beacon"
data-filter-features="healthsavingsaccount"
</pre>
</div>
</div>
</div>
</div>
<!--end plan-card-->
<style>
.plan-card {
background: #f0edeb;
margin: 1.5em 0 0;
padding: 0;
}
.no-display {
display: none;
}
fieldset {
float: left;
width: auto;
padding: 0;
margin: 0 10px 0 0;
border: none;
}
ol {
list-style: none;
margin:0;
padding: 0;
}
</style>
<script>
var PLANCARDFILTER = {};
PLANCARDFILTER.plan_card = $('.plan-card');
PLANCARDFILTER.count = 0;
PLANCARDFILTER.plan_match_count = 0;
//active filters checked, used to display appropriate plan cards
PLANCARDFILTER.filters = [];
PLANCARDFILTER.FilterChange = function() {
var value = $(this).val(),
facet = $(this).data('filterFacet');
//keep track of what filters are checked
if (this.checked) {
PLANCARDFILTER.count = PLANCARDFILTER.count + 1;
PLANCARDFILTER.filters.push(value);
} else {
PLANCARDFILTER.count = PLANCARDFILTER.count - 1;
PLANCARDFILTER.filters.splice(PLANCARDFILTER.filters.indexOf(value), 1);
}
PLANCARDFILTER.FilterPlanCards();
};
PLANCARDFILTER.FilterPlanCards = function() {
PLANCARDFILTER.plan_match_count = 0;
//if nothing checked, show all plans
if (PLANCARDFILTER.count === 0) {
PLANCARDFILTER.plan_card.removeClass('no-display');
return;
}
//intially hide all plan cards
PLANCARDFILTER.plan_card.addClass('no-display');
//show plan cards based on what filters are checked
PLANCARDFILTER.plan_card.each(function(index, elem) {
var filter_metal = $(elem).data('filterMetal'),
filter_deductible = $(elem).data('filterDeductible'),
filter_network = $(elem).data('filterNetwork'),
filter_features = $(elem).data('filterFeatures'),
matched = false;
for (var i=0, len=PLANCARDFILTER.filters.length; i<len; i++) {
if (filter_metal.indexOf(PLANCARDFILTER.filters[i]) > - 1) {
matched = true;
} else if (filter_deductible.indexOf(PLANCARDFILTER.filters[i]) > - 1) {
matched = true;
} else if (filter_network.indexOf(PLANCARDFILTER.filters[i]) > - 1) {
matched = true;
} else if (filter_features.indexOf(PLANCARDFILTER.filters[i]) > - 1) {
matched = true;
} else {
//with this included, filter works with *one* selection max across each filter facet
//when commented out, filter works with multiple selections within same filter facet
matched = false;
break;
}
}
if (matched) {
$(elem).removeClass('no-display');
PLANCARDFILTER.plan_match_count = PLANCARDFILTER.plan_match_count + 1;
} else {
$(elem).addClass('no-display');
}
//stubbed in functionality for this
$('.plan-count').text(PLANCARDFILTER.plan_match_count);
});
};
PLANCARDFILTER.Initialize = function() {
$('.plans-filter').on('change', 'input:checkbox', PLANCARDFILTER.FilterChange);
};
PLANCARDFILTER.Initialize();
</script>
Aucun commentaire:
Enregistrer un commentaire