hey guys.
i wanted to write this for a long time but did not really find the time. so here i go. my tutorial on how to build a dynamic filter within webflow. this means that the filter is fully adjustable by the editor and adapts to changes in the cms.
it may be a little advanced. so you may want to give it a try once you’re more familiar with webflow and ideally have some experience with javascript. also as i am not the javascript ninja, there might be a better solution to this. feel free to improve mine.
hopefully no error sneaked into my copy and pasting.
have fun!
jaro.
_
the outcome
to see the outcome of this tutorial, please have a look at the mentors page of my project leadsportsaccelerator.com. scroll to the “say hello” section and activate the filter icon on the left.
_
the starting point
imagine your portfolio site displaying a projects collection in list view. each item has one or more categories (packaging, web, corporate, event, … you name it) assigned to it. the list is pretty long as you are a great designer and completed many projects. you want your potential clients to quickly find what they’re looking for. but not everyone is interested in that last app you designed. maybe someone only wants to look at the logos you created. so giving them the option to filter the list dynamically is what you’re looking for.
_
the basics
you have a projects collection. and you have a categories collection. you add a reference field to the projects collection and link it to the categories collection. now, when adding a project item, you can also add a category to it. all of the contents (projects and categories) can be changed by the client in the cms editor at any time.
_
the fake solution
this is the old and common way i was using before and i’ve been seeing it on many other sites built in webflow. i will explain it shortly for you to understand all the differences.
using the webflow tabs component you create a tab for every category item. you manually change each tab link title to the category title. you insert a collection list inside each tab and set its filter to display only the given category (screen#001). if required you can also create a tab showing all projects by adding the title “all” to the first tab and not setting any filter on its collection list.
_
the problem
if you have a few more categories you will soon run into webflow’s limit of 20 collections per page. if your client wants to change the name of a category he or she will have to do this twice (in the category collection and in the tab component). also, no category items can be added or deleted from the filter by the client as they are defined in the tabs component which is (by now) not fully customisable in the editor (title change only).
_
the new solution
at first, i would like to say that my solution is only using two collection lists at all no matter how many categories you add. one collection list is being used for the filter navigation. the other one is being used for the list itself. so it’s actually more of a real filter. also categories can be added or deleted by the client at any time. the filter dynamically adapts to all the changes.
-
the navigation
at first we are adding the filter navigation (screen#002). this is pretty easy. just add a collection list to your page (ideally before the projects list) and link it to your categories collection. style it any way you want. the only thing to look for is the collection item class. name itfilter-item
in order for it to be triggered by our custom code later. -
the inside
as you cannot display content from a multi reference field within a collection list (only on the collection template page) you can only use the standard reference fields (for now). this is why the number of categories for each project item is limited by the number of available references per collection. 5 on a regular cms hosting plan and 10 on business (i think thats actually the only downside of this method). in this example we are using the regular plan, so 5 categories. add the fields inside the collection settings (screen#003) and fill your collections with content. -
the custom code
what we will be doing is the following. if the user clicks on a filter item, we want to hide every collection item from the projects collection list except the ones being given that exact same category.
–
in order for this to work, we need to be able to identify each projects collection item by it’s categories. this is why every item in our list needs to contain the titles of its categories. so we add five paragraphs and link them to the reference fields. then we give each paragraph the class namecategory-trigger
(screen#004). now we can talk to them with our custom code. also add the idfilter-list
to the projects collection list. that way we can also talk to that list and all the items within.
–
now let the magic happen: custom code. later we want to add 5 classes to every item with the matching names of its categories. because our category names might contain special characters, which are not allowed for class names, we need to create slugs out of them (lowercase version without special characters) before. this is the first part of our code (code#001).
–
next we add the classes to each item (code#002). side fact: if an item has less then 5 categories applied to it, it will of course be given only the appropriate classes.
–
now that every item has its extra category classes, we need to check if they match with the clicked link from our filter navigation. if they do, we will set them todisplay', 'block'
and if they don’t we will set them to'display', 'none'
. i also added a delay of 500ms to the code in order to be able to fire a simple fade interaction before the content changes (code#003). the fade transition can be easily done in webflow.
–
to highlight the active navigation item, we add the classfilter-active
to it and remove it when it becomes inactive again. you can style this class in webflow. in my example i set thefilter-item
class opacity to 40%, added a transition option (screen#005) and set thefilter-active
class opacity to 100%. that way it quickly fades over.
–
missing now is the “all” category. so we add it in your categories collection. because we want it to be always the first item in our filter navigation collection, we add an order number field in the collection settings (screen#006). set the order number of your “all” category to 1 and use higher numbers for the other categories. then set the sort order of your collection list to “order number: smallest to largest” (screen#007). in our custom code we define that every items will be shown when the first navigation link is being clicked (code#004).
–
there’s only one more thing. because all the categories are active in the beginning, we need to manually add thefilter-active
class to our “all” category (code#005). that way it will be highlighted when you load the page.
_
<script>
// Dynamic Filter
$(document).ready(function() {
// Code#001: Set Slug Variables
var slug = function(str) {
var $slug = '';
var trimmed = $.trim(str);
$slug = trimmed.replace(/[^a-z0-9-]/gi, '-').
replace(/-+/g, '-').
replace(/^-|-$/g, '');
return $slug.toLowerCase();
}
// Code#002: Add Classes to Collection List Items
$('#filter-list .w-dyn-item').each(function () {
// The five Category Text Blocks
var category1 = slug($(this).find('.category-inlay:nth-child(1)').text());
var category2 = slug($(this).find('.category-inlay:nth-child(2)').text());
var category3 = slug($(this).find('.category-inlay:nth-child(3)').text());
var category4 = slug($(this).find('.category-inlay:nth-child(4)').text());
var category5 = slug($(this).find('.category-inlay:nth-child(5)').text());
$(this).addClass(category1);
$(this).addClass(category2);
$(this).addClass(category3);
$(this).addClass(category4);
$(this).addClass(category5);
});
// Code#003: Show & Hide Items when Filter Navigation is clicked
$('.filter-item').click(function(){
var navigationCategory = slug($(this).text());
$('#filter-list .w-dyn-item').delay(500).css('display', 'none');
$('.' + navigationCategory).delay(500).css('display', 'block');
$('.filter-item').removeClass('filter-active');
$(this).addClass('filter-active');
});
// Code#004: Show All
$('.filter-item:first-child').click(function(){
$('#filter-list .w-dyn-item').delay(500).css('display', 'block');
});
// Code#005: Set Active for Category "All"
$('.filter-item:first-child').addClass('filter-active');
});
</script>
add the snippet to your footer code.
_
the limitations
as i said before, sadly no multi-reference-fields can be used which is not as user-friendly for the client as it could be. and also there’s a maximum of 5 (or 10 on business hosting) categories for each item.
_
bonus
in my example i wanted to show all the categories but if you don’t want these to be visible in the list, you can also hide them by setting them to display: none
. it’s only important for them to be their, not to be visible. this does not affect the behaviour of the filter.
_
screenshots
screen#001
screen#002
screen#003
screen#004
screen#005
screen#006
screen#007