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.