Search code examples
phpwordpressadvanced-custom-fields

How to run Wordpress Query by ACF field using Select on front-end


Basically what I'm trying to do is create filters on front end, so that users can filter all posts by specific ACF field.

There's a cattery website and the owner will need to add new litters, when new generations of kittens arrive. I've created option page for this new field group and created a repeater field with text, so that I can add new rows with names of the litters, I want to filter by later.

I've included basic loop for repeater field:

<select name="litter" id="litter">
  <?php
  
  if( have_rows('cat-litters', 'option') ):
    
    while ( have_rows('cat-litters', 'option') ) : the_row(); ?>

      <option value="<?php the_sub_field('new-litter', 'option'); ?>"><?php the_sub_field('new-litter', 'option'); ?></option>

    <?php endwhile;
  else :
      
  endif;
  ?>
</select>

And it is working for now: enter image description here

I will be adding a field to cats' posts named cat-litter, so that I can find specific posts with a litter "02" for example.

But now I'm stuck with using this select from front-end to run a query to display fitting posts. I'm working in index.php of twentytwentyone child-theme btw.

It doesn't matter if it will need to reload page or not (however if the ajax way won't be complicated I would very much appreciate that) but I have to point out that it needs to work with pagination and I already have it set up with pre_get_posts to display 9 posts per page (3x3 grid).


Solution

  • Taken and modified from the Dynamic $_GET parameters section of this page per the ACF documentation: https://www.advancedcustomfields.com/resources/query-posts-custom-fields/

    function my_pre_get_posts( $query ) {
    
        // do not modify queries in the admin
        if( is_admin() ) {
            return $query;
        }
    
        // only modify queries for 'cat' post type
        if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'cat' ) {
            
            // allow the url to alter the query
            if( isset($_GET['cat-litter']) ) {
                $query->set('meta_key', 'cat-litter');
                $query->set('meta_value', $_GET['cat-litter']);
            } 
        }
        
        // return
        return $query;
    }
    
    add_action('pre_get_posts', 'my_pre_get_posts');
    

    Then on the front end for reloading the page with the 'cat-litter' from the dropdown could be done with jQuery:

    <script>
        $('select#litter').on('change', function() {
          window.location.href = "www.website.com/cats?cat-litter=" + $(this).val();
        });
    </script>