WordPress AJAX Taxonomy Filter

User
we have two taxonomy fileters select dropdown add ajax fitler and to bring post wordpress jquery
Assistant
To implement two taxonomy filters as dropdowns and filter posts via AJAX in WordPress using jQuery, follow these steps:

### **1. Register Taxonomy Filters**
Add dropdowns to filter posts based on the taxonomies. This code should be added to your theme’s template file where you want to display the filters (e.g., archive or a custom page template).

<?php
$taxonomy_1 = 'category'; // Replace with your taxonomy name
$taxonomy_2 = 'post_tag'; // Replace with another taxonomy name

$terms_1 = get_terms(['taxonomy' => $taxonomy_1, 'hide_empty' => true]);
$terms_2 = get_terms(['taxonomy' => $taxonomy_2, 'hide_empty' => true]);
?>

<div id="filters">
    <select id="filter-taxonomy-1">
        <option value="">Select Category</option>
        <?php foreach ($terms_1 as $term): ?>
            <option value="<?php echo $term->slug; ?>"><?php echo $term->name; ?></option>
        <?php endforeach; ?>
    </select>

    <select id="filter-taxonomy-2">
        <option value="">Select Tag</option>
        <?php foreach ($terms_2 as $term): ?>
            <option value="<?php echo $term->slug; ?>"><?php echo $term->name; ?></option>
        <?php endforeach; ?>
    </select>
</div>

<div id="posts-container">
    <!-- AJAX posts will be rendered here -->
</div>

### **2. Enqueue Scripts**
Add the necessary JavaScript and pass AJAX URL to it.

function enqueue_taxonomy_filter_scripts() {
    wp_enqueue_script('taxonomy-filter', get_template_directory_uri() . '/js/taxonomy-filter.js', ['jquery'], null, true);
    wp_localize_script('taxonomy-filter', 'ajax_vars', ['ajax_url' => admin_url('admin-ajax.php')]);
}
add_action('wp_enqueue_scripts', 'enqueue_taxonomy_filter_scripts');

### **3. Create JavaScript File**
Create `taxonomy-filter.js` in your theme's `js` folder.

jQuery(document).ready(function ($) {
    $('#filter-taxonomy-1, #filter-taxonomy-2').on('change', function () {
        const taxonomy1 = $('#filter-taxonomy-1').val();
        const taxonomy2 = $('#filter-taxonomy-2').val();

        $.ajax({
            url: ajax_vars.ajax_url,
            type: 'POST',
            data: {
                action: 'filter_posts',
                taxonomy_1: taxonomy1,
                taxonomy_2: taxonomy2,
            },
            beforeSend: function () {
                $('#posts-container').html('<p>Loading...</p>');
            },
            success: function (response) {
                $('#posts-container').html(response);
            },
        });
    });
});

### **4. Handle AJAX Request in PHP**
Add the following code to your theme's `functions.php`.

function filter_posts() {
    $taxonomy_1 = sanitize_text_field($_POST['taxonomy_1']);
    $taxonomy_2 = sanitize_text_field($_POST['taxonomy_2']);

    $args = [
        'post_type' => 'post',
        'posts_per_page' => -1,
        'tax_query' => [
            'relation' => 'AND',
        ],
    ];

    if (!empty($taxonomy_1)) {
        $args['tax_query'][] = [
            'taxonomy' => 'category', // Replace with your taxonomy name
            'field' => 'slug',
            'terms' => $taxonomy_1,
        ];
    }

    if (!empty($taxonomy_2)) {
        $args['tax_query'][] = [
            'taxonomy' => 'post_tag', // Replace with your taxonomy name
            'field' => 'slug',
            'terms' => $taxonomy_2,
        ];
    }

    $query = new WP_Query($args);

    if ($query->have_posts()) {
        while ($query->have_posts()) {
            $query->the_post();
            ?>
            <div class="post-item">
                <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
                <p><?php the_excerpt(); ?></p>
            </div>
            <?php
        }
    } else {
        echo '<p>No posts found</p>';
    }

    wp_die();
}
add_action('wp_ajax_filter_posts', 'filter_posts');
add_action('wp_ajax_nopriv_filter_posts', 'filter_posts');

### **5. Add Styling (Optional)**
Style your dropdowns and posts container with CSS as needed.

### **Summary**
– Dropdowns will trigger an AJAX request on selection change.
– Posts will be filtered dynamically based on the selected taxonomy terms.
– AJAX requests will fetch and render posts without page reload.

Let me know if you need further assistance!

User
add class on select and send taxony names with slugs
Assistant
To add a class to the “ elements and send both the taxonomy names and their selected slugs in the AJAX request, follow these steps:

### **1. Update HTML for Dropdowns**
Add a class to each “ and include data attributes for taxonomy names.

<div id="filters">
    <select class="taxonomy-filter" data-taxonomy="category">
        <option value="">Select Category</option>
        <?php foreach ($terms_1 as $term): ?>
            <option value="<?php echo $term->slug; ?>"><?php echo $term->name; ?></option>
        <?php endforeach; ?>
    </select>

    <select class="taxonomy-filter" data-taxonomy="post_tag">
        <option value="">Select Tag</option>
        <?php foreach ($terms_2 as $term): ?>
            <option value="<?php echo $term->slug; ?>"><?php echo $term->name; ?></option>
        <?php endforeach; ?>
    </select>
</div>

<div id="posts-container">
    <!-- AJAX posts will be rendered here -->
</div>

### **2. Update JavaScript**
Modify the JavaScript to send taxonomy names along with the selected slugs.

jQuery(document).ready(function ($) {
    $('.taxonomy-filter').on('change', function () {
        let filters = {};

        // Loop through all dropdowns to collect data
        $('.taxonomy-filter').each(function () {
            const taxonomy = $(this).data('taxonomy');
            const slug = $(this).val();

            if (slug) {
                filters[taxonomy] = slug;
            }
        });

        $.ajax({
            url: ajax_vars.ajax_url,
            type: 'POST',
            data: {
                action: 'filter_posts',
                filters: filters,
            },
            beforeSend: function () {
                $('#posts-container').html('<p>Loading...</p>');
            },
            success: function (response) {
                $('#posts-container').html(response);
            },
        });
    });
});

### **3. Update PHP Handler**
Process the `filters` array to handle taxonomy names and slugs.

function filter_posts() {
    $filters = isset($_POST['filters']) ? $_POST['filters'] : [];

    $args = [
        'post_type' => 'post',
        'posts_per_page' => -1,
        'tax_query' => ['relation' => 'AND'],
    ];

    foreach ($filters as $taxonomy => $slug) {
        $args['tax_query'][] = [
            'taxonomy' => sanitize_text_field($taxonomy),
            'field' => 'slug',
            'terms' => sanitize_text_field($slug),
        ];
    }

    $query = new WP_Query($args);

    if ($query->have_posts()) {
        while ($query->have_posts()) {
            $query->the_post();
            ?>
            <div class="post-item">
                <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
                <p><?php the_excerpt(); ?></p>
            </div>
            <?php
        }
    } else {
        echo '<p>No posts found</p>';
    }

    wp_die();
}
add_action('wp_ajax_filter_posts', 'filter_posts');
add_action('wp_ajax_nopriv_filter_posts', 'filter_posts');

### **Summary of Changes**
1. **HTML**: Added a class (`taxonomy-filter`) and data attributes (`data-taxonomy`) to the “ elements.
2. **JavaScript**: Collects taxonomy names and slugs dynamically from the dropdowns and sends them as an array.
3. **PHP**: Processes the `filters` array to construct the `tax_query` dynamically.

This setup ensures the dropdowns are classed, and the AJAX request sends both taxonomy names and their selected slugs for filtering. Let me know if you have further questions!

Leave a Comment

Your email address will not be published. Required fields are marked *