Advanced filtering.
For using any advanced filtering option, all filter triggering elements (buttons, search field, checkboxes, radio buttons, etc) have to be inside the FORM.
You also will have to use some extra jQuery code snippet, which I recommend to put in the separate .js file
Creating content for filtering
Main settings, which is necessary for make your content filtered is:
- container with filtered content should have an ID (we are using #container)
-all items, which will be filtered SHOULD have class .mix
For filter your content in several dimensions (size, color, etc...) all you need is add a combo classes to the elements.
For example, one element can have classes "category-1", "blue", "big", "square".
Creating filtering menu
MixItUp will "read" the value of the inputs with type "checkbox" and will react when checkbox will be checked.
First of all, you have to add a FORM to the page and give it an ID (I used #filterform)
Unfortunately, we can't use "value" property for the checkbox directly in Webflow, so you will have to create them by using embed code.
Important note: Embed code should be INSIDE THE FORM.
Add the code for checkboxes structure into the embed code widget:
Every Checkbox will have VALUE property equal the class for filter.
Along with that you have to give a class for the embed code widget itself so every group of filters will be wrapped in a div with specific class. You will need it for further connection with the plugin code.
Add a RESET button
For fast and easy clean all the filters we can use "Reset" buttons.
All you will need for that is a link-block or standard Webflow button with ID "reset".
Important note: button or link should be INSIDE THE FORM.
Create .js file for advanced filtering settings.
I recommend creating separate .js file for using advanced filtering settings, because Webflow limit custom code size to 5000 characters.
var checkboxFilter = {
// Declare any variables we will need as properties of the object
$filters: null,
$reset: null,
groups: [],
outputArray: [],
outputString: '',
// The "init" method will run on document ready and cache
// any jQuery objects we will need.
init: function(){
var self = this;
// As a best practice, in each method we will
// asign "this" to the variable "self" so that
// it remains scope-agnostic. We will use it
// to refer to the parent "checkboxFilter"
// object so that we can share methods and
// properties between all parts of the object.
self.$filters = $('#filterform');
self.$reset = $('#reset');
self.$container = $('#container');
self.$filters.find('.cd-filter-block').each(function(){
self.groups.push({
$inputs: $(this).find('input'),
active: [],
tracker: false
});
});
self.bindHandlers();
},
// The "bindHandlers" method will listen for whenever a form value changes.
bindHandlers: function(){
var self = this;
self.$filters.on('change', function(){
self.parseFilters();
});
self.$reset.on('click', function(e){
e.preventDefault();
self.$filters[0].reset();
self.parseFilters();
});
},
// The parseFilters method checks which filters are active in each group:
parseFilters: function(){
var self = this;
// loop through each filter group and add active filters to arrays
for(var i = 0, group; group = self.groups[i]; i++){
group.active = []; // reset arrays
group.$inputs.each(function(){
$(this).is(':checked') && group.active.push(this.value);
});
group.active.length && (group.tracker = 0);
}
self.concatenate();
},
// The "concatenate" method will crawl through each group, concatenating filters as desired:
concatenate: function(){
var self = this,
cache = '',
crawled = false,
checkTrackers = function(){
var done = 0;
for(var i = 0, group; group = self.groups[i]; i++){
(group.tracker === false) && done++;
}
return (done < self.groups.length);
},
crawl = function(){
for(var i = 0, group; group = self.groups[i]; i++){
group.active[group.tracker] && (cache += group.active[group.tracker]);
if(i === self.groups.length - 1){
self.outputArray.push(cache);
cache = '';
updateTrackers();
}
}
},
updateTrackers = function(){
for(var i = self.groups.length - 1; i > -1; i--){
var group = self.groups[i];
if(group.active[group.tracker + 1]){
group.tracker++;
break;
} else if(i > 0){
group.tracker && (group.tracker = 0);
} else {
crawled = true;
}
}
};
self.outputArray = []; // reset output array
do{
crawl();
}
while(!crawled && checkTrackers());
self.outputString = self.outputArray.join();
// If the output string is empty, show all rather than none:
!self.outputString.length && (self.outputString = 'all');
//console.log(self.outputString);
// ^ we can check the console here to take a look at the filter string that is produced
// Send the output string to MixItUp via the 'filter' method:
if(self.$container.mixItUp('isLoaded')){
self.$container.mixItUp('filter', self.outputString);
}
}
};
Don't forget to change parameters in the code if you will use different classes or IDs
Create a .js file with the code above and host it in any cloud service (Dropbox, Google Drive, etc), so you could use the public link to it and connect that file to your site.
Connecting plugin
For connect this plugin you will have to add custom code to the site settings (pic1) or page settings (pic2) before </body> tag.
As I mentioned in the general setup (mixitup-main), first you will need a link to main .js file of plugin.
In my case I used public link
<script src="http://cdn.jsdelivr.net/jquery.mixitup/latest/jquery.mixitup.min.js" type="text/javascript">
Nex line, we are connecting advanced filtering .js file:
<script src="link to your hosted file here" type="text/javascript">
After these lines of code you have to add a code, which will call jQuery plugins.
MixitUp Search function
There is also exist code snippet, which will let you to have a search function for your filtering content
(credits http://codepen.io/edprats/pen/pzAdg).
1) Add an input field with type="search" inside the form (use embed code)
2) Add an extra piece of code to the snippet in the footer area
//search filtering
//credits http://codepen.io/edprats/pen/pzAdg
var inputText;
var $matching = $();
var delay = (function(){
var timer = 0;
return function(callback, ms){
clearTimeout (timer);
timer = setTimeout(callback, ms);
};
})();
$(".cd-filter-content input[type='search']").keyup(function(){
// Delay function invoked to make sure user stopped typing
delay(function(){
inputText = $(".cd-filter-content input[type='search']").val().toLowerCase();
// Check to see if input field is empty
if ((inputText.length) > 0) {
$('.mix').each(function() {
var $this = $(this);
// add item to be filtered out if input text matches items inside the title
if($this.attr('class').toLowerCase().match(inputText)) {
$matching = $matching.add(this);
} else {
// removes any previously matched item
$matching = $matching.not(this);
}
});
$('.itembox').mixItUp('filter', $matching);
} else {
// resets the filter to show all item if input is empty
$('.itembox').mixItUp('filter', 'all');
}
}, 200 );
});
Last important detail.
Before we get to the finish, there is one small but crucial CSS rule you must add to the project:
filtering elements should have setting display:none
So, do not forget to apply display:none to class .mix before publish the site
When MixItUp plugin will load, it will add the display value as an inline-style (the default is “inline-block”).
Publish you site and enjoy plugin!
Good luck!