How to Filter Portfolio with multiple attributes with ajax in WordPress?

To filter portfolio with multiple attributes using AJAX in WordPress, you can create a custom plugin or add the code to your theme’s functions.php file. Below is an example of how you can achieve this in a WordPress environment:

Assuming you have a custom post type named “portfolio” and custom taxonomies named “category” and “type” to store the attributes, here’s the code:

Step 1: Create a custom plugin or add the following code to your theme’s functions.php file

// Enqueue scripts and styles for AJAX functionality
function enqueue_portfolio_filter_scripts() {
    wp_enqueue_script('portfolio-filter', get_template_directory_uri() . '/js/portfolio-filter.js', array('jquery'), '1.0', true);
    wp_localize_script('portfolio-filter', 'portfolio_filter_data', array(
        'ajax_url' => admin_url('admin-ajax.php'),
        'nonce'    => wp_create_nonce('portfolio_filter_nonce'),
    ));
}
add_action('wp_enqueue_scripts', 'enqueue_portfolio_filter_scripts');

// AJAX callback to filter portfolio items
function filter_portfolio_items() {
    check_ajax_referer('portfolio_filter_nonce', 'security');

    $category = isset($_POST['category']) ? sanitize_text_field($_POST['category']) : '';
    $type = isset($_POST['type']) ? sanitize_text_field($_POST['type']) : '';

    $args = array(
        'post_type' => 'portfolio',
        'tax_query' => array(
            'relation' => 'AND',
            array(
                'taxonomy' => 'category',
                'field'    => 'slug',
                'terms'    => $category,
            ),
            array(
                'taxonomy' => 'type',
                'field'    => 'slug',
                'terms'    => $type,
            ),
        ),
    );

    $query = new WP_Query($args);

    if ($query->have_posts()) {
        while ($query->have_posts()) {
            $query->the_post();
            // Display portfolio item here
            echo '<div>' . get_the_title() . '</div>';
        }
        wp_reset_postdata();
    } else {
        echo 'No portfolio items found.';
    }

    wp_die();
}
add_action('wp_ajax_portfolio_filter', 'filter_portfolio_items');
add_action('wp_ajax_nopriv_portfolio_filter', 'filter_portfolio_items'); // For non-logged-in users

Step 2: Create a JavaScript file in your theme’s js folder (create one if it doesn’t exist) named “portfolio-filter.js”

jQuery(document).ready(function($) {
    // Function to handle the AJAX request and update the portfolio items
    function updatePortfolioItems() {
        const category = $('#categorySelect').val();
        const type = $('#typeSelect').val();

        $.ajax({
            url: portfolio_filter_data.ajax_url,
            method: 'POST',
            data: {
                action: 'portfolio_filter',
                security: portfolio_filter_data.nonce,
                category: category,
                type: type,
            },
            beforeSend: function() {
                // Show a loading spinner or any other loading indicator
                $('#portfolio').html('<div>Loading...</div>');
            },
            success: function(response) {
                // Update the portfolio with the filtered items
                $('#portfolio').html(response);
            },
            error: function() {
                // Handle error if needed
                $('#portfolio').html('<div>Error fetching portfolio items.</div>');
            },
        });
    }

    // Event listener for filter changes
    $('#categorySelect, #typeSelect').on('change', function() {
        updatePortfolioItems();
    });

    // Reset button event listener
    $('#resetButton').on('click', function() {
        $('#categorySelect').val('');
        $('#typeSelect').val('');
        updatePortfolioItems('', ''); // Clear filters and show all items
    });


    // Initial update on page load
    updatePortfolioItems();
});

Step 3: Add the filter dropdowns and portfolio container to your desired template file, for example, in single-portfolio.php or archive-portfolio.php

<label for="categorySelect">Select Category:</label>
<select id="categorySelect">
    <option value="">All Categories</option>
    <?php
    $categories = get_terms('category'); // Replace 'category' with your custom taxonomy slug
    foreach ($categories as $category) {
        echo '<option value="' . esc_attr($category->slug) . '">' . esc_html($category->name) . '</option>';
    }
    ?>
</select>

<label for="typeSelect">Select Type:</label>
<select id="typeSelect">
    <option value="">All Types</option>
    <?php
    $types = get_terms('type'); // Replace 'type' with your custom taxonomy slug
    foreach ($types as $type) {
        echo '<option value="' . esc_attr($type->slug) . '">' . esc_html($type->name) . '</option>';
    }
    ?>
</select>

<button id="resetButton">Reset Filters</button>

<div id="portfolio">
    <!-- Portfolio items will be populated here via AJAX -->
</div>

Make sure you replace 'portfolio', 'category', and 'type' with the appropriate post type and taxonomy slugs you are using in your WordPress installation.

Step 4: Conclusion

With this code, when users select a category or type from the dropdowns, the portfolio items will be dynamically filtered and displayed without the page being reloaded.

Leave a Reply

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

Back to Top