0
|
1 |
--- |
|
2 |
title: Combo filters, sorting, AND hash history |
|
3 |
layout: default |
|
4 |
category: tests |
|
5 |
schema: |
|
6 |
- name: color |
|
7 |
filters: [ red, blue, yellow ] |
|
8 |
- name: size |
|
9 |
filters: [ small, wide, tall, big ] |
|
10 |
- name: shape |
|
11 |
filters : [ round, square ] |
|
12 |
--- |
|
13 |
|
|
14 |
<section id="copy"> |
|
15 |
<p>Filters can be combined. In addition to filtering for just <code>.red</code> or <code>.tall</code>, you can pass in a filter selector of both: <code>.red.tall</code>.</p> |
|
16 |
</section> |
|
17 |
|
|
18 |
<section id="options" class="clearfix combo-filters"> |
|
19 |
<div class="clearfix"> |
|
20 |
<h3>Filters</h3> |
|
21 |
|
|
22 |
{% for group in page.schema %} |
|
23 |
<div class="option-combo {{ group.name }}"> |
|
24 |
<h4>{{ group.name }}</h4> |
|
25 |
<ul class="filter option-set clearfix " data-filter-group="{{ group.name }}"> |
|
26 |
<li><a href="#filter-{{ group.name }}-any" data-filter-value="" class="selected">any</a> |
|
27 |
{% for filter in group.filters %} |
|
28 |
<li><a href="#filter-{{ group.name }}-{{ filter }}" data-filter-value=".{{ filter }}">{{ filter }}</a> |
|
29 |
{% endfor %} |
|
30 |
</ul> |
|
31 |
</div> |
|
32 |
{% endfor %} |
|
33 |
</div> |
|
34 |
|
|
35 |
<h3>Sort</h3> |
|
36 |
|
|
37 |
<ul id="sort-by" class="option-set clearfix" data-option-key="sortBy"> |
|
38 |
<li><a href="#sortBy=original-order" data-option-value="original-order" class="selected" data>original-order</a></li> |
|
39 |
<li><a href="#sortBy=color" data-option-value="color">color</a></li> |
|
40 |
<li><a href="#sortBy=size" data-option-value="size">size</a></li> |
|
41 |
<li><a href="#sortBy=shape" data-option-value="shape">shape</a></li> |
|
42 |
</ul> |
|
43 |
|
|
44 |
|
|
45 |
</section> <!-- #options --> |
|
46 |
|
|
47 |
<div id="container" class="clearfix"> |
|
48 |
{% for size in page.schema[1].filters %} |
|
49 |
{% for shape in page.schema[2].filters %} |
|
50 |
{% for color in page.schema[0].filters %} |
|
51 |
<div class="color-shape {{ size }} {{ shape }} {{ color }}" data-size="{{ size }}" data-color="{{ color }}" data-shape="{{ shape }}"></div> |
|
52 |
{% endfor %} |
|
53 |
{% endfor %} |
|
54 |
{% endfor %} |
|
55 |
|
|
56 |
|
|
57 |
{% for color in page.schema[0].filters %} |
|
58 |
{% for shape in page.schema[2].filters %} |
|
59 |
{% for size in page.schema[1].filters %} |
|
60 |
<div class="color-shape {{ size }} {{ shape }} {{ color }}" data-size="{{ size }}" data-color="{{ color }}" data-shape="{{ shape }}"></div> |
|
61 |
{% endfor %} |
|
62 |
{% endfor %} |
|
63 |
{% endfor %} |
|
64 |
|
|
65 |
</div> <!-- #container --> |
|
66 |
|
|
67 |
<script src="../js/jquery-1.7.1.min.js"></script> |
|
68 |
<script src="../js/jquery.ba-bbq.min.js"></script> |
|
69 |
<script src="../jquery.isotope.min.js"></script> |
|
70 |
<script> |
|
71 |
$(function(){ |
|
72 |
|
|
73 |
var $container = $('#container'); |
|
74 |
var initialOptions = { |
|
75 |
itemSelector : '.color-shape', |
|
76 |
masonry: { |
|
77 |
columnWidth: 80 |
|
78 |
}, |
|
79 |
getSortData: { |
|
80 |
color: function( $elem ) { |
|
81 |
return $elem.attr('data-color'); |
|
82 |
}, |
|
83 |
shape: function( $elem ) { |
|
84 |
return $elem.attr('data-shape'); |
|
85 |
}, |
|
86 |
size: function( $elem ) { |
|
87 |
return $elem.attr('data-size'); |
|
88 |
} |
|
89 |
} |
|
90 |
}; |
|
91 |
// build a hash for all our options |
|
92 |
var options = { |
|
93 |
// special hash for combination filters |
|
94 |
comboFilters: {} |
|
95 |
}; |
|
96 |
|
|
97 |
|
|
98 |
// filter buttons |
|
99 |
$('.filter').on( 'click', 'a', function( event ) { |
|
100 |
event.preventDefault(); |
|
101 |
var $this = $(this); |
|
102 |
// don't proceed if already selected |
|
103 |
if ( $this.hasClass('selected') ) { |
|
104 |
return false; |
|
105 |
} |
|
106 |
|
|
107 |
// console.log('hello world'); |
|
108 |
var $optionSet = $this.parents('.option-set'); |
|
109 |
var group = $optionSet.attr('data-filter-group'); |
|
110 |
options.comboFilters[ group ] = $this.attr('data-filter-value'); |
|
111 |
$.bbq.pushState( options ); |
|
112 |
}); |
|
113 |
|
|
114 |
var $sortBy = $('#sort-by').on( 'click', 'a', function( event ) { |
|
115 |
event.preventDefault(); |
|
116 |
var $this = $(this); |
|
117 |
// don't proceed if already selected |
|
118 |
if ( $this.hasClass('selected') ) { |
|
119 |
return false; |
|
120 |
} |
|
121 |
options.sortBy = $this.attr('data-option-value'); |
|
122 |
// console.log( options ); |
|
123 |
$.bbq.pushState( options ); |
|
124 |
}); |
|
125 |
|
|
126 |
function selectLink( $link ) { |
|
127 |
$link.parents('.option-set').find('.selected').removeClass('selected'); |
|
128 |
$link.addClass('selected') |
|
129 |
} |
|
130 |
|
|
131 |
var location = window.location; |
|
132 |
var $comboFilterOptionSets = $('.combo-filters .option-set'); |
|
133 |
|
|
134 |
|
|
135 |
function getComboFilterSelector( comboFilters ) { |
|
136 |
// build filter |
|
137 |
var isoFilters = []; |
|
138 |
var filterValue, $link, $optionSet; |
|
139 |
for ( var prop in comboFilters ) { |
|
140 |
filterValue = comboFilters[ prop ]; |
|
141 |
isoFilters.push( filterValue ); |
|
142 |
// change selected combo filter link |
|
143 |
$optionSet = $comboFilterOptionSets.filter('[data-filter-group="' + prop + '"]'); |
|
144 |
$link = $optionSet.find('a[data-filter-value="' + filterValue + '"]'); |
|
145 |
selectLink( $link ); |
|
146 |
} |
|
147 |
var selector = isoFilters.join(''); |
|
148 |
return selector; |
|
149 |
} |
|
150 |
|
|
151 |
$( window ).on( 'hashchange', function() { |
|
152 |
// get options from hash |
|
153 |
if ( location.hash ) { |
|
154 |
$.extend( options, $.deparam.fragment( location.hash, true ) ); |
|
155 |
} |
|
156 |
// build options from hash and initial options |
|
157 |
var isoOptions = $.extend( {}, initialOptions, options ); |
|
158 |
|
|
159 |
if ( options.comboFilters ) { |
|
160 |
isoOptions.filter = getComboFilterSelector( options.comboFilters ); |
|
161 |
} |
|
162 |
|
|
163 |
// change selected link for sortBy |
|
164 |
if ( options.sortBy ) { |
|
165 |
var $link = $sortBy.find('a[data-option-value="' + options.sortBy + '"]'); |
|
166 |
selectLink( $link ); |
|
167 |
} |
|
168 |
|
|
169 |
$container.isotope( isoOptions ); |
|
170 |
}) |
|
171 |
// trigger hashchange to capture initial hash options |
|
172 |
.trigger( 'hashchange' ); |
|
173 |
|
|
174 |
}); |
|
175 |
|
|
176 |
</script> |
|
177 |
|