Custom Dynamic Filter in Webflow

hey guys. :yum:

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.

  1. 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 it filter-item in order for it to be triggered by our custom code later.

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

  3. 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 name category-trigger (screen#004). now we can talk to them with our custom code. also add the id filter-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 to display', '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 class filter-active to it and remove it when it becomes inactive again. you can style this class in webflow. in my example i set the filter-item class opacity to 40%, added a transition option (screen#005) and set the filter-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 the filter-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

001
screen#001


screen#002


screen#003

004
screen#004

005
screen#005


screen#006

007
screen#007

27 Likes

Hi @buntestrahlen

Wow, some work has gone into this - I look forward to trying it out soon!

Many many thanks

Stu

Hey @buntestrahlen , Thanks so much for putting this together!

Look’s awesome, i’m going to give it a test now :slight_smile:

hey guys. i am also looking forward to hearing your feedback.

Very cool! Any chance that there is a way to run it with multiple filters at a time?

Thanks for making this @buntestrahlen, really awesome.

hey @Cameron_Johnson
as i said in the bonus section, right now you can add up to 5 filters (10 on business hosting) for every item in the collection. they are limited by the number of available reference fields. or do you mean something other than that?

:sun_with_face:

Hey @buntestrahlen, I was thinking more of in the fashion of filtering: consulting, design, and legal all at the same time.

i don’t really understand what you mean. clicking on one link but three filters are being set to activate? like grouping?

Yes! Exactly.

Sorry I see how could sound confusing. I don’t see how someone would do this, I was just curious.

i see. thats possible. the custom code would just need some tweaking. :sun_with_face:

Hmm, I’m not sure what the code would be. But definitley an interesting thought!

Hi @buntestrahlen :slight_smile:
Im having some trouble making this work and was wondering if you could help?
Share link
Page link

I this is where i’m going wrong, what classes to what items? :slight_smile:
Sorry for the trouble.

hey kjell. there you go.
:sun_with_face:

every collection item in your second collection list should get a class assigned with the name of it’s filter tag (code#002). the class has no styling. we just use it for the filter. when you click on a link inside your first collection list we can check if the link text matches one of the classes in your second collection list. and then we can only show those. in my case i used five tags. so for every collection item i added up to five classes. in your example you used only one tag. so your code might look like this:

// Code#002: Add Classes to Collection List Items
$('#filter-list .w-dyn-item').each(function () {

    	// One Category Text Block
      	var category1 = slug($(this).find('.category-trigger:nth-child(1)').text());
      	$(this).addClass(category1);
});

and your html after publishing should look like this:

__
you could also add a data-filter attribute to the items instead of classes. but for me this has been the easiest solution.

Hi guys.
I have now successfully made the Custom Dynamic Filter in Webflow with a lot of help from Jaro and some changes to the code.
Instead of going back and forth and telling you what you had to do differently, I’ll just tell you how I made it. I also made a video of the process where we also give it some interactions.

Add the code

<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());
          
          	setTimeout(function() { $('#filter-list .w-dyn-item').css('display', 'none'); }, 500);
    		setTimeout(function() { $('.' + navigationCategory).css('display', 'block'); }, 500);;
          
          	$('.filter-item').removeClass('filter-active');
          	$(this).addClass('filter-active');
    	});
      
      
      	// Code#004: Show All
      	$('.filter-item:first-child').click(function(){
          
          	setTimeout(function() { $('#filter-list .w-dyn-item').css('display', 'block'); }, 500);
    	});
      
      	// Code#005: Set Active for Category "All"
      	$('.filter-item:first-child').addClass('filter-active');
      
    });
    </script>

Add the new code to the page you are working on or on site level. What ever you prefer and if you are using the filter on multiple pages.
Page: Edit page details > Custom code> Before /body tag
Site: Project settings > Custom code > Footer Code

Create the Category CMS Collection.

  • Name: Name of category
  • Add a number field
  • Name it sort order

Create the categories.
Create all categories you want + one category called ALL where you set the sort number to 1.

Create the content CMS Collection

  • Create the reference field (from 1-10 depending on what you want)
  • Create the rest of the content fields.

Create the CMS content

  • Add the references. (you don’t have to use all the fields)
  • Populate the rest of the content.

Create the page content
The filter items

  • Add a collection list and link it to the categories.
  • Add a Text Block and style it as you please.
  • Give the Collection item a Class or Subclass of filter item
  • Set the sort order to:
    • Order, Larges to smallest (this puts the ALL to the front)
    • Name, Alphabetical (this sorts the rest of the categories alphabetical)

Styling the active filter items.

This is to difference the inactive and active filter item. I set the inactive (initial state) to 60% opacity. And the Active State to 100% opacity.

  • Set Filter Item opacity to 60%
  • Add a Text Block to anywhere on the page.
  • Give it the class name of Filter Active
  • Set opacity to 100%
  • Delete the text block

The content

  • Add collection list and link it to the content
  • Give the Collection list the ID: filter-list
  • Add a div that will contain the Categories
  • Add same amount of Text Blocks that you have reference fields and link it to each field
  • Give the text block a Class or subclass of Category Inlay
  • Style it as you please.
  • Add the rest of the content in a separate Div and style it as you please.

Publish the site and test.

8 Likes

Little confused about the last part “The Content.” Any luck on the video?

Yes the video should explain it for you :).

Basically, add the filter names and give them the class of Category inlay

the video doesnt load unfortunately. any help? the filter ALL works on my page, but when i click the other categories, it doesnt filter my list. =(

http://jasonsuh.com/cinematography

Sorry, now the video should work.

I would have to see a sharelink to help you on that :slight_smile:

wow kjell thanks for the amazing video! that really explains it very well!

1 Like

https://preview.webflow.com/preview/jasonsuh?preview=a3c90a58e214656a534a964f9ef5c341

Here’s my share link. I went step by step through your vid, but I guess I’m missing something. The collection list shows for “ALL” but when I click the other filters, it goes blank.

CINEMATOGRAPHY PAGE! sorry for that

Thanks for all your help guys!