Filter ilightbox portfolio items based on URL query string parameter

Viewed 134

I have a website that uses a portfolio with filters to define which images are displayed. The relavent JavaScript is (I believe) shown below:

    if( $element.hasClass( 'filterable-entries' ) ){
            $( '.cl-filters' ).on( 'click', 'button', function() {
                var filterValue = $(this).attr('data-filter');
                if( filterValue != '*' )
                    $element.isotope({
                        filter: filterValue,
                        sortBy: 'random'
                    }); 
                else
                    $element.isotope({
                            filter: filterValue,
                            sortBy: 'original-order'
                    }); 
                            
                CL_FRONT.restartAnimations( $element );
                $element.isotope('arrange');
    
                $(this).parent().find('button.selected').removeClass('selected');
                $(this).addClass('selected');

            });
    }

The filters are using the 'data-filter' as mentioned above in the generated HTML (which I can't edit):

<div class="inner">
    <button data-filter="*" class="selected">All 2</button>
    <button data-filter=".portfolio_entries-abstract">Abstract</button>
    <button data-filter=".portfolio_entries-animal">Animal</button>
    <button data-filter=".portfolio_entries-famous-reproductions">Famous Reproductions</button>
    <button data-filter=".portfolio_entries-flower-tree">Flower & Tree</button>
    <button data-filter=".portfolio_entries-landscape">Landscape</button>
    <button data-filter=".portfolio_entries-modern-art">Modern Art</button>
    <button data-filter=".portfolio_entries-portrait">Portrait</button>
</div>

I need to make the var filterValue = $(this).attr('data-filter'); somehow take the value from the query string in order to apply the filter, but without stopping the current button filters working. So for example if the URL contains ?filter=abstract (or any specific value) then it would apply the .portfolio_entries-abstract as the filterValue. However as the function appears to be triggered by a button click using $( '.cl-filters' ).on( 'click', 'button', function() { I'm not sure how this is possible.

The filter would also need to still apply the class selected to the appropriate filter button, and make sure it isn't applied to any of the others, as it currently does when using the buttons.

Example scenario: User visits the site with URL mysite.com?filter=abstract and is shown the filtered gallery with the relevant button highlighted by the .selected class. The user then changes the filter using the buttons to view a different category and carries on as normal - there is no need for the original filter to persist in any way.

This is a WordPress/WooCommerce site so is PHP based, but this JavaScript is included in the theme files as .js and not .php so I can't just use $_SERVER['QUERY_STRING'];, not that I would know what to do with that in this context anyway...

1 Answers

I solved it! :)

The logic is:

  • Check if the user is loading the page for the first time this session using sessionStorage, and if not then just use the button filtering as normal rather than the URL filter.

  • Get the query string using URLSearchParams(window.location.search)

  • Get the specific parameter from the query string using .has from URLSearchParams (if it exists, otherwise just use the button filtering as normal)

  • Then use the parameter value as both the filter (by appending the leading . to the value) and for the .selected CSS class (by using $(document).find and the parameter value from the query string.

    if( $element.hasClass( 'filterable-entries' ) ){     
     if (sessionStorage.alreadyRun2 != "true")
         var params = new URLSearchParams(window.location.search);
           if (params){
             if (params.has('filter') == true){  
                 var filter = params.get('filter');                      
                 var filterValue = "." + filter;
                 if( filterValue != '*' ){
                     $element.isotope({
                         filter: filterValue,
                         sortBy: 'random'
                     }); 
                 }
                 else {
                 $element.isotope({
                        filter: filterValue,
                        sortBy: 'original-order'
                 }); 
                 }
    
                 CL_FRONT.restartAnimations( $element );
                 $element.isotope('arrange');
    
                 $(document).find('button.selected').removeClass('selected');
                 $(document).find("[data-filter=" + CSS.escape(filterValue) + "]").addClass('selected');
            }
         } else {
             $( '.cl-filters' ).on( 'click', 'button', function() {
             var filterValue = $(this).attr('data-filter');
                 if( filterValue != '*' ){
                 $element.isotope({
                     filter: filterValue,
                     sortBy: 'random'
                 }); 
                 }
             else {
                 $element.isotope({
                        filter: filterValue,
                        sortBy: 'original-order'
                 });
             }
    
             CL_FRONT.restartAnimations( $element );
             $element.isotope('arrange');
    
             $(this).parent().find('button.selected').removeClass('selected');
             $(this).addClass('selected');
             });
         }
         sessionStorage.alreadyRun2 = "true";
    
         $( '.cl-filters' ).on( 'click', 'button', function() {
             var filterValue = $(this).attr('data-filter');
             if( filterValue != '*' )
                 $element.isotope({
                     filter: filterValue,
                     sortBy: 'random'
                 }); 
             else
                 $element.isotope({
                         filter: filterValue,
                         sortBy: 'original-order'
                 }); 
    
             CL_FRONT.restartAnimations( $element );
             $element.isotope('arrange');
    
             $(this).parent().find('button.selected').removeClass('selected');
             $(this).addClass('selected');
    
         });
     }
    

It needed adding in a few other places in the same file, but the logic is the same.

Related