I’m trying to allow users to select criteria from multiple custom taxonomies in order to filter a custom post type on the front end via a from with multiple selects.
My problem is that the code only works if each of the selects has criteria selected. Trying to find a way where users can also just select one of the options and it will only filter the CPT by that option.
* All code is abstracted. Taxonomy names are actually: incident_category, incident_classification, incident_type, et al.
Markup:
<form action="<?php echo site_url() ?>/wp-admin/admin-ajax.php" method="POST" id="filter"> <?php if( $terms = get_terms( array( 'taxonomy' => 'tax1', ) ) ) : echo '<select name="tax1filter"><option value="">Select tax1...</option>'; foreach ( $terms as $term ) : echo '<option value="' . $term->term_id . '">' . $term->name . '</option>'; endforeach; echo '</select>'; endif; if( $terms = get_terms( array( 'taxonomy' => 'tax2', ) ) ) : echo '<select name="tax2filter"><option value="">Select tax2...</option>'; foreach ( $terms as $term ) : echo '<option value="' . $term->term_id . '">' . $term->name . '</option>'; endforeach; echo '</select>'; endif; if( $terms = get_terms( array( 'taxonomy' => 'tax3', ) ) ) : echo '<select name="tax3filter"><option value="">Select tax3...</option>'; foreach ( $terms as $term ) : echo '<option value="' . $term->term_id . '">' . $term->name . '</option>'; endforeach; echo '</select>'; endif; ?> <button>Apply filter</button> <input type="hidden" name="action" value="myfilter"> </form> <div id="loop"></div>
JS:
jQuery(function($){ $('#filter').submit(function(){ var filter = $('#filter'); $.ajax({ url:filter.attr('action'), data:filter.serialize(), // form data type:filter.attr('method'), // POST beforeSend:function(xhr){ filter.find('button').text('Processing...'); // changing the button label }, success:function(data){ filter.find('button').text('Apply filter'); // changing the button label back $('#loop').html(data); // insert data } }); return false; }); });
Function:
add_action('wp_ajax_myfilter', 'misha_filter_function'); // wp_ajax_{ACTION HERE} add_action('wp_ajax_nopriv_myfilter', 'misha_filter_function'); function misha_filter_function(){ $args = array( 'post_type' => 'cpt', 'orderby' => 'date', 'order' => 'DESC', ); $relation = 'OR'; if(isset($_POST['tax1filter']) && isset( $_POST['tax2filter'] ) && isset( $_POST['tax3filter'] )) { $relation = 'AND'; } if( isset( $_POST['tax1filter'] ) || isset( $_POST['tax2filter'] || isset( $_POST['tax3filter']) ) $args['tax_query'] = array( 'relation' => $relation, array( 'taxonomy' => 'tax1', 'field' => 'id', 'terms' => $_POST['tax1filter'] ), array( 'taxonomy' => 'tax2', 'field' => 'id', 'terms' => $_POST['tax2filter'], ), array( 'taxonomy' => 'tax3', 'field' => 'id', 'terms' => $_POST['tax3filter'], ), ); $query = new WP_Query( $args ); if( $query->have_posts() ) : while( $query->have_posts() ): $query->the_post(); echo '<h5>' . $query->post->post_title . '</h5>'; endwhile; wp_reset_postdata(); else : echo 'No posts found'; endif; die(); };
Any help with this would be as always greatly appreciated!
Advertisement
Answer
This seems to get what you need:
function misha_filter_function(){ $taxonomies = get_taxonomies();; $args = array( 'post_type' => 'cpt', 'orderby' => 'date', 'order' => 'DESC', ); $relation = 'AND'; $params = array(); $args['tax_query']['relation'] = $relation; foreach ( $taxonomies as $tax ) { if( isset( $_POST[ $tax . 'filter' ] ) && !empty( $_POST[ $tax . '_filter' ] ) { $args['tax_query'][] = array( 'taxonomy' => $tax, 'field' => 'id', 'terms' => $_POST[ $tax . 'filter' ], ); } } $query = new WP_Query( $args ); if( $query->have_posts() ) : while( $query->have_posts() ): $query->the_post(); echo '<h5>' . $query->post->post_title . '</h5>'; endwhile; wp_reset_postdata(); else : echo 'No posts found'; endif; die(); };