|
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 |