I've cobbled a custom filter together for some custom product taxonomies for a wine shop. I got it to where user can select a single item from a single filter and the page will refresh / point to the archive page of the selected taxonomy. This is fine for now but not the ideal functionality. Ideally, I'd love it to allow for multiple filter selections before showing results, and grey-out options within other filters based on the first filter selection. E.g. if Italy is selected as Origin, then only Regions that apply to wines categorized as Italy would be selectable. Is this possible? I know there are plugins I could use but I want to keep the site as lean as possible and am trying to avoid using a plugin for this, plus working on my php skills I guess. Any suggestions for how to accomplish this and/or make the current code more efficient?
Here's what I have so far:
// Add custom taxonomies filter dropdowns before the product loop
add_action('woocommerce_before_shop_loop', 'custom_taxonomy_filters', 0);
function custom_taxonomy_filters()
{
//Customize taxonomy slugs
$taxonomy_slugs = array('origin-taxo', 'varietal_taxo', 'region_taxo', 'appellation_taxo'); ?>
<div class="siab-filter-msg">Scroll, filter, or call us for a rec. Cheers!</div>
<div class="siab-custom-filters">
<?php
foreach ($taxonomy_slugs as $taxonomy_slug) {
$taxonomy = get_taxonomy($taxonomy_slug);
if ($taxonomy) {
$terms = get_terms(array(
'taxonomy' => $taxonomy_slug,
'hide_empty' => false,
));
if ($terms) {
?>
<div class="taxonomy-filter">
<h5><?php echo esc_html($taxonomy->labels->name);
?></h5>
<select name="<?php echo esc_attr($taxonomy_slug);
?>" class="filter-dropdown custom-taxonomy-filter" data-taxonomy="<?php echo esc_attr($taxonomy_slug); ?> ">
<option value=""><?php echo esc_html__('All', 'laon-wine-house');
?></option>
<?php foreach ($terms as $term) :
?>
<option value="<?php echo esc_attr($term->slug);
?>"><?php echo esc_html($term->name);
?></option>
<?php endforeach;
?>
</select>
</div>
<?php
}
}
} ?>
</div><!-- end .siab-custom-filters container -->
<?php
}
// Apply custom taxonomies filter to product query
add_action('pre_get_posts', 'apply_custom_taxonomy_filters');
function apply_custom_taxonomy_filters($query)
{
if (!is_main_query() || !$query->is_post_type_archive('product')) {
return;
}
// Customize taxonomy slugs
$taxonomy_slugs = array('origin', 'varietal', 'region', 'appellation');
$tax_query = array('relation' => 'OR');
foreach ($taxonomy_slugs as $taxonomy_slug) {
$filter_value = isset($_GET[$taxonomy_slug]) ? sanitize_text_field($_GET[$taxonomy_slug]) : '';
if (!empty($filter_value)) {
$args['tax_query'][] = array(
'taxonomy' => $taxonomy_slug,
'field' => 'slug',
'terms' => $filter_value,
'operator' => 'IN',
);
}
}
if (count($tax_query) > 1) {
$query->set('tax_query', $tax_query);
}
}
// Add JavaScript for handling form submission and page redirection
add_action('wp_footer', 'custom_taxonomy_filter_js');
function custom_taxonomy_filter_js()
{
?>
<script>
jQuery(function($) {
$('select.custom-taxonomy-filter').change(function() {
var taxonomySlug = $(this).data('taxonomy');
var taxonomyName = taxonomySlug.split('-')[0]; // Extract the actual taxonomy name
var value = $(this).val();
if (value !== '') {
// Construct the URL with the selected taxonomy and value
var url = '<?php echo esc_url(home_url('/')); ?>' + taxonomyName + '/' + value;
window.location.href = url;
}
});
});
</script>
<?php
}