Last active
October 10, 2025 11:41
-
-
Save robertpainsi/2fa433d90ae0136573f155af705f4ee7 to your computer and use it in GitHub Desktop.
Example for loading and storing the checked filters in the browser's hash using filtering.js version 2.0.0
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!-- filtering.js library https://github.com/robertpainsi/filtering.js --> | |
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>Filtering.js Hash</title> | |
| <style> | |
| .filtering-group { | |
| margin: 12px; | |
| } | |
| .filtering-filter.checked { | |
| background-color: lightblue; | |
| } | |
| .filtering-filter.disabled { | |
| color: lightgrey; | |
| } | |
| /* Items */ | |
| .filtering-item.filtered { | |
| display: none; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div id="root"> | |
| <div style="display: flex; flex-direction: row;"> | |
| <div class="filtering-group" data-group-name="color"> | |
| <div class="filtering-filter" data-filter-name="red">Red</div> | |
| <div class="filtering-filter" data-filter-name="blue">Blue</div> | |
| </div> | |
| <div class="filtering-group" data-group-name="size"> | |
| <div class="filtering-filter" data-filter-name="small">Small</div> | |
| <div class="filtering-filter" data-filter-name="large">Large</div> | |
| </div> | |
| </div> | |
| <ul> | |
| <li id="item-1" class="filtering-item" data-filter-color="red" data-filter-size="small">Small red item</li> | |
| <li id="item-2" class="filtering-item" data-filter-color="blue" data-filter-size="large">Large blue item</li> | |
| </ul> | |
| </div> | |
| <script src="index.ui.js"></script> | |
| <script> | |
| const { FilteringFlow, FilterData } = filteringjs; | |
| const filteringFlow = new FilteringFlow( document.querySelector( '#root' ) ); | |
| const loadFiltersFromHash = registerFilteringHashPlugin( filteringFlow ); | |
| // Since we want to enable all filters specified in the browser's hash on page load, we call the loadFiltersFromHash, | |
| // which will internally call filteringFlow.filter(...). Call this function after all plugins have been registered. | |
| loadFiltersFromHash(); | |
| // The registerFilteringHashPlugin is just a helper function to registers all listeners. You actually don't have to | |
| // create it, you could also inline the code. However, I strongly encourage you to create it somehow similar to | |
| // encapsulate the plugin and make it reusable in other projects too. The checked filters in the hash for this code | |
| // example look like #color=red&color=blue... | |
| function registerFilteringHashPlugin( filteringFlow ) { | |
| // After a filter is checked or unchecked, store the checked filters in the hash | |
| filteringFlow.addEventListener( 'filter', ( event ) => storeFiltersToHash( event.data.filterData ) ); | |
| // To support the browser's history (back and forward), a hash change needs to trigger the filtering with checked | |
| // filters parsed from the hash. | |
| window.addEventListener( 'hashchange', loadFiltersFromHash ); | |
| function loadFiltersFromHash() { | |
| const hash = decodeURIComponent( window.location.hash.substring( 1 ) ); | |
| // The FilterData is used to specify which filters should be checked and used for filtering | |
| const filteringData = new FilterData(); | |
| if ( hash ) { | |
| const filteringAsQueryParams = new URLSearchParams( hash ); | |
| for ( const [groupName, filterName] of filteringAsQueryParams ) { | |
| // Set the checked filters parsed from the hash | |
| filteringData.checkFilter( groupName, filterName ); | |
| } | |
| } | |
| // Trigger filtering with the parsed filters | |
| filteringFlow.filter( filteringData ); | |
| } | |
| // This function just stores the checked filters in the hash. | |
| function storeFiltersToHash( filterData ) { | |
| const filteringAsQueryParams = new URLSearchParams(); | |
| for ( const [groupName, checkedFilters] of filterData.checkedFilters ) { | |
| for ( const checkedFilter of checkedFilters ) { | |
| filteringAsQueryParams.append( groupName, checkedFilter ); | |
| } | |
| } | |
| const newHash = filteringAsQueryParams.toString(); | |
| if ( newHash !== window.location.hash.substring( window.location.hash.indexOf( '#' ) + 1 ) ) { | |
| window.location.hash = newHash; | |
| } | |
| } | |
| return loadFiltersFromHash; | |
| } | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment