Sorting Posts Via Custom Taxonomy Values Using Checkboxes?

I am working on a project that has a dropdown of custom taxonomy values called “Disciplines”, there are only 4 of them in the dropdown. The way it has been designed is that you can select more than one discipline to filter by. The idea is you check the checkbox and it will filter the posts via the value specified in the checkbox value.

My question is: what is the best way to go about this? It doesn’t have to be AJAX, in-fact I would be happy for the user to check their desired values and if they don’t check anything within the space of 2 seconds or so, then the page reloaded and the values they want to sort by only showed the posts matching that criteria.

The problem I am facing here is where do I store these values, and how do I reload the page so it knows about these values? I’m assuming that the solution will most likely use query_var’s, but not sure if there are other ways like using custom rewrite rules and rewrite tags.

This is the current code I am using to display the dropdown:

          <ul class="parent-sort-container">
            <li>
                <?php
                $disciplines = get_terms('discipline', array('hide_empty' => 0));
                ?>
                <a href="#">All Disciplines</a>
                <?php if ($disciplines): ?>
                <ul class="filter-sub-dropdown">
                    <?php foreach($disciplines AS $discipline): ?>
                    <li><a href="javascript:void(0);"><input type="checkbox" name="discipline[]" value="<?php echo $discipline->slug; ?>"><?php echo $discipline->name; ?></a></li>
                    <?php endforeach; ?>
                </ul>
                <?php endif; ?>
            </li>

The generated HTML output looks like this:

<ul class="parent-sort-container">
                    <li>
                                                <a href="#">All Disciplines</a>
                                                <ul class="filter-sub-dropdown">
                                                        <li><a href="javascript:void(0);"><input type="checkbox" name="discipline[]" value="better-living">Better Living</a></li>
                                                        <li><a href="javascript:void(0);"><input type="checkbox" name="discipline[]" value="communication">Communication</a></li>
                                                        <li><a href="javascript:void(0);"><input type="checkbox" name="discipline[]" value="design-thinking">Design Thinking</a></li>
                                                        <li><a href="javascript:void(0);"><input type="checkbox" name="discipline[]" value="fashion">Fashion</a></li>
                                                        <li><a href="javascript:void(0);"><input type="checkbox" name="discipline[]" value="public-places">Public Places</a></li>
                                                    </ul>
                                            </li>
                  </ul>

1 Answer
1

Wrap the whole thing within a form and add a submit button in it:

<form method="POST" action="">
   <ul class="filter-sub-dropdown">
   ...

</form>

Use term IDs as checkbox values instead of slugs (you’ll save a little server resources):

$discipline->slug; > $discipline->term_id

Then, in your functions.php file check if that form has been submitted, and change WP’s query to include only posts having at least one of those terms:

add_action('pre_get_posts', function($query){

  // only do this if we have user input and if this is the main query 
  if(isset($_POST['discipline']) && $query->is_main_query()){

    // sanitize 
    $disciplines = array_map('intval', $_POST['discipline']); 

    // prepare a taxonomy query
    $my_tax_query = array(
      'taxonomy' => 'discipline',
      'field'    => 'id',
      'terms'    => $disciplines,
      'operator' => 'IN',
    );

    // include it in the main query
    $query->set('tax_query', array($my_tax_query)); 
  }

});

Adding AJAX support is very easy. Just hook a function on the form submit event (use preventDefault() to prevent its submission) (or on the input change event if you don’t want the submit button), serialize input values into a variable, do a $.ajax POST request where you pass that variable and get the contents of the DIV with the posts from the response. And replace existing contents with it…

Leave a Comment