1

I've created a custom post type (projects) with different custom taxonomies (projects' categories).

I would like to create a categories' filter but with AJAX, so without reloading the page every time.

This is what I followed:

How to filter post data with AJAX on page?

and this is the guide:

https://www.bobz.co/ajax-filter-posts-tag/

Here my code

Function.php

function ajax_filter_posts_scripts() {
  // Enqueue script
  wp_register_script('afp_script', get_template_directory_uri() . '/assets/js/ajax-filter-posts.js', false, null, false);
  wp_enqueue_script('afp_script');

  wp_localize_script( 'afp_script', 'afp_vars', array(
        'afp_nonce' => wp_create_nonce( 'afp_nonce' ), // Create nonce which we later will use to verify AJAX request
        'afp_ajax_url' => admin_url( 'admin-ajax.php' ),
      )
  );
}
add_action('wp_enqueue_scripts', 'ajax_filter_posts_scripts', 100);





function ajax_filter_get_posts( $taxonomyproject ) {

  // Verify nonce
  if( !isset( $_POST['afp_nonce'] ) ||
      !wp_verify_nonce( $_POST['afp_nonce'], 'afp_nonce' ))
    die('Permission denied');

     $taxonomyproject = $_POST['project'];
     $result = json_encode(my_get_posts($taxonomyproject, true));
     echo $result;

     die();

}

function my_get_posts($taxonomyproject = '', $ajax = false){

// WP Query
$args = array(
    'post_type' => 'projects',
    'posts_per_page' => -1,
    'tax_query' => array(
        array(
            'taxonomy' => 'project',
        )
    )
);

  // If taxonomy is not set, remove key from array and get all posts
  if( !$taxonomyproject ) {
    unset( $args['tax_query'] );
  }

  $query = new WP_Query( $args );
  $html = '';
  $items = array();

  if ( $query->have_posts() ) :
       while ( $query->have_posts() ) :
       $query->the_post();

       $res = '<div class="col-lg-4">'.
                  '<a href="'.get_permalink().'">'.
                      '<article class="panel panel-default" id="post-'.get_the_id().'">'.
                          '<div class="panel-body">'.
                              get_the_post_thumbnail().
                              '<div class="panel-cover">'.
                                  '<h3>'.get_the_title().'</h3>'.
                                      get_the_content().
                              '</div>'.
                          '</div>'.
                      '</article>'.
                  '</a>' .
              '</div>';


       $ajax ? $items[] = $res : $html .= $res;


   endwhile;

   $result['response'] = $ajax ? $items : $html;
   $result['status'] = 'success';

   else:
       $result['response'] = '<h2>No posts found</h2>';
       $result['status']   = '404';
   endif;
wp_reset_postdata();
return $result;
}

javascript file

$(document).ready(function(){

    // work filters

    $('.projects-filter').click( function(event) {

        // Prevent default action - opening tag page
        if (event.preventDefault) {
            event.preventDefault();
        } else {
            event.returnValue = false;
        }

        // Get tag slug from title attirbute
        var stuff = $(this).attr('title');

        data = {
            action: 'filter_posts', // function to execute
            afp_nonce: afp_vars.afp_nonce, // wp_nonce
            post_type: "projects", // selected tag
            };

        $.ajax({
            type: "post",
            dataType: "json",
            url: afp_vars.afp_ajax_url,
            data: data,
            success: function(data, textStatus, XMLHttpRequest) {
                console.log(data);
                // Restore div visibility
                $('.projects-results').fadeOut()
                    .queue(function(n) {
                            $(this).html(data.response);
                            n();
                }).fadeIn();
            },
            error: function( XMLHttpRequest, textStatus, errorThrown ) {
                /*console.log( MLHttpRequest );
                console.log( textStatus );
                console.log( errorThrown );*/
                $('.projects-results').fadeOut()
                    .queue(function(n) {
                            $(this).html("No items found. ");
                            n();
                }).fadeIn();
            }
        });
    });

});

Project file

<div class="container filters-projects-wrap">
    <div>
        <span class="small-text">FILTER BY SECTOR</span>
    </div>
    <div>
        <ul class="filters-projects-ul">
            <li><a href="<?php echo esc_url( home_url( '/projects/' ) ); ?>">ALL</a></li>
        <?php $categories = get_categories('taxonomy=projects_categories_register&post_type=projects'); ?>
                <?php foreach ($categories as $category) : ?>
                        <li><a class="projects-filter" href="<?php echo get_term_link($category->cat_ID); ?>"><?php echo $category->name; ?></a></li>
        <?php endforeach; ?>
        </ul>
    </div>
</div>



<div class="projects-results">
        <?php $res = my_get_posts();
                echo $res['response'];
        ?>
</div>

At the moment I'm able to get all the projects when I land for the first time on the projects' archive page. When I click on the categories (filters) I get the fade effect but I get "No items found.". It seems the that the parameters that I passed in JS are wrong.

Probably something here:

data = {
    action: 'filter_posts', // function to execute
    afp_nonce: afp_vars.afp_nonce, // wp_nonce
    post_type: "projects", // selected tag
    };

but I'm not getting how to get the right posts of the right category

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.