I’m trying to code an ajax custom post filter but the result seems like it’s not filtering, and I’m not sure where I did wrong. I’ll provide the revelant code below.
archive-projetos.php
<div class="categories">
<ul>
<li><a href="" class="js-filter-item">Todos</a></li>
<?php
$cat_args = array(
'exclude' => array(1),
'option_all' => 'All',
'taxonomy' => 'Tipos de Construção'
);
$categories = get_categories($cat_args);
foreach($categories as $cat): ?>
<li><a class="js-filter-item" href="<?= get_category_link($cat->term_id);?>"><?= $cat->name;?></a></li>
<?php endforeach;?>
</ul>
</div>
<div class="content-wrapper js-filter row">
<?php
$args = array (
'post_type' => array('projetos'),
'post_status' => array('publish')
);
$query = new WP_Query($args);
if($query->have_posts()):
while ($query->have_posts()) : $query->the_post();?>
<div class="post-thumbnail-container col-sm">
<a href="<?php the_permalink();?>">
<div class="thumbnail-container"><?php the_post_thumbnail();?></div>
<div class="title-overlay"><?php the_title();?></div>
</a>
</div>
<?php endwhile; else: endif; wp_reset_postdata();?>
</div>
filter.js
(function($){
$(document).ready(function(){
$(document).on('click', '.js-filter-item', function(e){
e.preventDefault();
var category =$(this).data('category');
$.ajax({
url: wpajax.ajaxurl,
data: {action: 'filter', category: category},
type: 'post',
success: function(result) {
$('.js-filter').html(result);
},
error: function(result) {
console.warn(result);
}
});
});
});
})(jQuery);
functions.php
function load_scripts() {
wp_enqueue_script('ajax', get_template_directory_uri() . '/js/filter.js', array ('jquery'), NULL, true);
wp_localize_script('ajax','wpajax',
array('ajaxurl' => admin_url('admin-ajax.php'))
);
}
add_action('wp_enqueue_scripts', 'load_scripts');
add_action('wp_ajax_nopriv_filter', 'filter_ajax');
add_action('wp_ajax_filter', 'filter_ajax');
function filter_ajax() {
$category = $_POST['projetos'];
$args = array (
'post_type' => array('projetos'),
'post_status' => array('publish')
);
$query = new WP_Query($args);
if(isset($category)) {
$args['category__in'] = array($category);
}
if($query->have_posts()):
while ($query->have_posts()) : $query->the_post();?>
<div class="post-thumbnail-container col-sm">
<a href="<?php the_permalink();?>">
<div class="thumbnail-container"><?php the_post_thumbnail();?></div>
<div class="title-overlay"><?php the_title();?></div>
</a>
</div>
<?php endwhile; else: endif; wp_reset_postdata();
die();
}
I don’t think it would be necessary to include the custom post and category but there it goes as well:
function projetos()
{
$args = array(
'labels' => array(
'name'=> 'Projetos',
'singular_name'=>'Projeto'
),
'public' => true,
'has_archive' => true,
'menu_icon' => 'dashicons-category',
'supports' => array('title','editor','thumbnail')
);
register_post_type('projetos', $args);
}
add_action('init', 'projetos');
function tipos_construcao()
{
$args = array(
'labels' => array (
'name' => 'Tipos de Construção',
'singular_name'=>'Tipo de Construção'
),
'public'=> true,
'hierarchical'=> true
);
register_taxonomy('Tipos de Construção',array('projetos'), $args);
}
add_action('init', 'tipos_construcao');
Any help would be appreciated! I’ve been trying several solutions and tried to browse other websites but to no solution.
I did console.log(result) in the filter.js to check what was the result, and it just doesn’t filter, the result is all the posts.
Thank you, once again!
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
How to make your AJAX filter works properly:
-
As I said in the comments, add the
data-categoryattribute to the<a>having the CSS classjs-filter-itemin theforeachloop in yourarchive-projetos.phptemplate:// * Wrapped for brevity. foreach ( $categories as $cat ) : ?> <li><a class="js-filter-item" href="<?= get_category_link( $cat->term_id ); ?>" data-category="<?= $cat->term_id; ?>" ><?= $cat->name; ?></a></li> <?php endforeach; ?>And if you wonder why add that attribute, then it’s because in
filter.js, the script is reading the category ID via$(this).data('category')which is equivalent to$( this ).attr( 'data-category' ). -
In the
filter_ajax()function infunctions.php, replace this:$query = new WP_Query($args); if(isset($category)) { $args['category__in'] = array($category); }with this:
if ( ! empty( $category ) ) { $args['tax_query'] = array( array( 'taxonomy' => 'Tipos de Construção', 'terms' => $category, ), ); } $query = new WP_Query( $args );I.e. Switch the position (of the
new WP_Query()call and theifblock) and then use thetax_queryparameter and notcategory__inwhich is for the defaultcategorytaxonomy only. -
Also in that
filter_ajax()function, replace the$category = $_POST['projetos'];with$category = $_POST['category'];because your JS script is sending the category ID in a (POST) input namedcategoryand notprojetos.However, you should always check if an array item is actually set before attempting to use it, so you would want to use
$category = $_POST['category'] ?? '';or the old way (prior to PHP 7):$category = isset( $_POST['category'] ) ? $_POST['category'] : '';.
Additional Notes
Even though the Tipos de Construção does work as the taxonomy name, i.e. the first parameter you pass to register_taxonomy(), you should actually use a slug like tipos_de_construcao because the documentation says:
$taxonomyis the name of the taxonomy. Name should only contain lowercase letters and the underscore character, and not be more than
32 characters long (database structure restriction). Default: None
So you should try to fix the taxonomy name, i.e. use a slug. It will take time, but it will be a better option in the long run. =)
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0