In this post I’m describing the process for AJAX post filtering All credits go to Misha Rudrastyh. My contribution is to make add two features. The first is making it work with Sage 9 namespacing. The second is to make the filtering working without pressing a submit button. The example below is for the Sage 9 them, but can easily be modified to work with any theme.
The Post Filter
This goes into app/helpers.php
.
/** * Post Filter */ if (!function_exists(__NAMESPACE__ . '\\filter_posts')) : function filter_posts() { ?> <div class="post-filter"> <form action="<?php echo site_url() ?>/wp-admin/admin-ajax.php" method="POST" id="filter"> <p>FILTER POSTS BY</p> <?php wp_dropdown_categories( array( 'orderby' => 'name', 'show_count' => false, 'show_option_all' => 'All Categories', 'hide_if_empty' => true, 'name' => 'categoryfilter', )) ?> <input type="hidden" name="action" value="myfilter"> </form> </div> <?php } endif;
The Filtering Function
This goes into app/helpers.php
.
/** * Post filter function */ function post_filter_function() { $args = array( 'orderby' => 'date', // we will sort posts by date 'order' => $_POST['date'] // ASC or DESC ); // for taxonomies / categories if (isset($_POST['categoryfilter'])) $args['tax_query'] = array( array( 'taxonomy' => 'category', 'field' => 'id', 'terms' => $_POST['categoryfilter'] ) ); $query = new \WP_Query($args); if ($query->have_posts()) : echo '<div class="row">'; while ($query->have_posts()): $query->the_post(); ?> <article <?= post_class(); ?>> <div class="row no-gutters"> <?php $post_image = get_the_post_thumbnail($post_id, 'thumbnail', array('class' => 'post-image')); if (!empty($post_image)) echo '<div class="entry entry-image">' . $post_image . '</div>' ?> <div class="entry entry-content"> <header> <time class="updated" datetime="<?= get_post_time('c', true); ?>"><?= get_the_date() ?> </time> <h2 class="entry-title"><a href="<?= get_permalink(); ?>"><?= get_the_title() ?></a></h2> <p class="byline author vcard"> <?= __('By:', 'sage'); ?> <a href="<?= get_author_posts_url(get_the_author_meta('ID')); ?>" rel="author" class="fn"> <?= get_the_author(); ?> </a> </p> </header> <div class="entry-summary"> <?= the_excerpt(); ?> </div> </div> </div> </article> <?php endwhile; echo '</div>'; wp_reset_postdata(); else : echo 'No posts found'; endif; die(); } add_action('wp_ajax_myfilter', __NAMESPACE__ . '\\post_filter_function'); add_action('wp_ajax_nopriv_myfilter', __NAMESPACE__ . '\\post_filter_function');
The Template & Loop
This example is for sage 9 and inside resources/views/index.blade.php
.
{!! App\filter_posts() !!} <div id="blog-posts" class="list"> <div class="row"> @while (have_posts()) @php(the_post()) @include ('partials.content-'.(get_post_type() === 'post' ?: get_post_type())) @endwhile </div> </div>
The JavaScript
/** * AJAX filter functionality */ $('#categoryfilter').change(function () { var filter = $('#filter'); $.ajax({ url: filter.attr('action'), data: filter.serialize(), // form data type: filter.attr('method'), // POST beforeSend: function () { // check if all categories is selected if (filter.serialize().indexOf('categoryfilter=0') !== -1) { location.reload(); } }, success: function (data) { $('#blog-posts').html(data); // insert data }, }); return false; });
Thanks for the tutorial. One issue I’m having is the admin-ajax.php is returning with a console error of ” the server responded with a status of 400 (Bad Request)”
Any idea how to fix it?
That error could mean many things. It’s impossible to tell without looking at your code. If you aren’t using Sage 9, I recommend looking at the original article I mention at the top of the post.
Hi Mike, thanks for the reply. Im using Sage 9 and the same code for the Ajax function. I’ve also tried wp_localize_script to use the admin-ajax.php on ajax url.
The other 2 PHP functions are very similar except im using a CPT Taxonomies
Yeah, without seeing the code I cannot help much. This would require some troubleshooting.
Sorry Mike, thought I’d ask just incase you knew of anything top of your head, also didn’t want to just paste all the code down in the comments.
I have pasted the functions on the below link
https://codeshare.io/2j7dwM
The markup for the posts are different but been scratching my head on how to fix this. Its a website I’ve inherited and first time using Sage
One thing I noticed is that your ajax actions needs to match the hidden input on the filter. So change `wp_ajax_post_filter_function` to `wp_ajax_myfilter` and `wp_ajax_nopriv_post_filter_function`
If that doesn’t solve it, I’m not sure what else could be the issue without active troubleshooting (ie. getting into the code).
Ah OK, I tried that previously and just again now but still getting the 400 bad request for admin-ajax. No worries, thanks for your time.
Thanks for the tutorial, I was looking for Sage specific tutorials, and I found your blog and I fell in love <3
I am even using your custom Numeric Page Navigation {!! App\page_navi() !!}.
Do you know how I can include the pagination in the blog with this AJAX post-filtering?
right now I can see the pagination only in the "all category" page, but as soon as I change the category, the pagination is not showing anymore.
In the wp-admin I set "Blog pages show at most" to a very small number for a testing purpose, but I can't see the pagination, only in the "all category" page.
could you please point me in the right direction?
thanks a lot
Looks like you may need personalized help. Feel free to reach out through the contact form on my site and we’ll go from there.