Ajax Custom Post Filter is not filtering

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:

  1. As I said in the comments, add the data-category attribute to the <a> having the CSS class js-filter-item in the foreach loop in your archive-projetos.php template:
    // * 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' ).

  2. In the filter_ajax() function in functions.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 the if block) and then use the tax_query parameter and not category__in which is for the default category taxonomy only.

  3. 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 named category and not projetos.

    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:

$taxonomy is 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

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x