I’m struggling with ajax filters mixed with a load more button. I will try to be as clear as possible
I’ve got a custom post type called Companies. I’ve created a page listing all of them , they can be filtered by taxonomies terms (ex: certifications, area, etc …). You pick some filters then click on apply and the corresponding results are displayed using Ajax.
In addition only the first 12 results are displayed, there is a loadmore button which loads more results using Ajax too
companies.php
<?php
/*****
Here's my init query listing all of them
*****/
$all_companies = new WP_Query(array('post_type' => 'companies', 'posts_per_page' => 12, 'paged' => $paged, 'order' => 'ASC', 'orderby' => 'ID'));
<?php if($all_companies->have_posts()): ?>
<div class="companies_results">
<?php while ( $all_companies->have_posts() ) : $all_companies->the_post(); ?>
<?php get_template_part( 'template-parts/bloc_companies' ); ?>
<?php endwhile; ?>
</div>
<?php endif; wp_reset_query(); ?>
<div class="loadmore">
<div>
<span>Show more</span>
</div>
</div>
functions.php
<?php
/**
* AJAX
*
* @return void
*/
/*****
Here's my loadmore script
*/
function misha_my_load_more_scripts() {
wp_enqueue_script('jquery');
global $all_companies;
wp_localize_script( 'cs-ajax', 'misha_loadmore_params', array(
'ajaxurl' => site_url() . '/wp-admin/admin-ajax.php', // WordPress AJAX
'posts' => json_encode( $all_companies->query_vars ), // everything about your loop is here
'current_page' => get_query_var( 'paged' ) ? get_query_var('paged') : 1,
'max_page' => $all_companies->max_num_pages
) );
wp_enqueue_script( 'cs-ajax' );
wp_reset_postdata();
}
add_action( 'wp_enqueue_scripts', 'misha_my_load_more_scripts' );
/*****
Displaying loadmore script results
*/
function misha_loadmore_ajax_handler(){
// prepare our arguments for the query
$args = json_decode( stripslashes( $_POST['query'] ), true );
$args['paged'] = $_POST['page'] + 1; // we need next page to be loaded
$args['post_status'] = 'publish';
// it is always better to use WP_Query but not here
query_posts( $args );
if( have_posts() ) :
?>
<?php
// run the loop
while( have_posts() ): the_post(); ?>
<?php get_template_part( 'template-parts/bloc_companies' ); ?>
<?php
endwhile
?>
<?php
endif;
die;
}
add_action('wp_ajax_loadmore', 'misha_loadmore_ajax_handler');
add_action('wp_ajax_nopriv_loadmore', 'misha_loadmore_ajax_handler');
/*****
Displaying filtered companies results
*/
add_action( 'wp_ajax_companies', 'display_companies' );
add_action( 'wp_ajax_nopriv_companies', 'display_companies' );
function display_companies() {
$certifs = $_POST['certifs'];
$areas = $_POST['aread'];
if($areas == '') {
$args_areas_query = array('');
} else {
$args_areas_query = array(
'taxonomy' => 'company_areas',
'field' => 'slug',
'terms' => $areas,
);
}
if($certifs == '') {
$args_certifs_query = array('');
} else {
$args_certifs_query = array(
'taxonomy' => 'company_certifications',
'field' => 'slug',
'terms' => $certifs,
);
}
//Args form main loop
$args = array(
'post_type' => 'companies',
'post_status' => 'publish',
'posts_per_page' => 12,
'tax_query' => array(
$args_areas_query,
$args_certifs_query
)
);
$ajax_query = new WP_Query($args);
$num = $ajax_query->post_count;
if($ajax_query->have_posts()) {
?>
<div class="companies_results">
<?php
while ( $ajax_query->have_posts() ) : $ajax_query->the_post(); ?>
<?php get_template_part( 'template-parts/bloc_companies' ); ?>
<?php endwhile;
} else {
echo '<p>Not found</p>';
}
?>
</div>
<?php
wp_reset_query();
wp_die();
}
Ajax.js
//Loadmore ajax on click
$('.loadmore').click(function() {
var button = $(this),
data = {
'action': 'loadmore',
'query': misha_loadmore_params.posts, // that's how we get params from wp_localize_script() function
'page' : misha_loadmore_params.current_page
};
$.ajax({
url : misha_loadmore_params.ajaxurl, // AJAX handler
data : data,
type : 'POST',
beforeSend : function ( xhr ) {
button.text('Loading...'); // change the button text, you can also add a preloader image
},
success : function( data ){
if( data ) {
$('.companies_results').imagesLoaded( function() {
$('.companies_results').append(data);
});
misha_loadmore_params.current_page++;
if ( misha_loadmore_params.current_page == misha_loadmore_params.max_page )
button.remove(); // if last page, remove the button
// you can also fire the "post-load" event here if you use a plugin that requires it
// $( document.body ).trigger( 'post-load' );
} else {
button.remove(); // if no data, remove the button as well
console.log('error');
}
}
});
});
//Apply filters ajax query
$('.applyfilter').click( function() {
var certifs = [];
var areas = [];
//Get values
$('.block-filter_areas input:checked').each(function() {
areas.push($(this).val());
});
$('.block-filter_certifs input:checked').each(function() {
certifs.push($(this).val());
});
$.ajax({
url: misha_loadmore_params.ajaxurl,
type: "POST",
data: {
'action': 'companies',
'areas': areas,
'certifs': certifs,
}
}).done(function(response) {
// when filter applied:
// set the current page to 1
misha_loadmore_params.current_page = 1;
// set the new query parameters
misha_loadmore_params.posts = response.posts;
// set the new max page parameter
misha_loadmore_params.max_page = response.max_page;
$('.companies_results').html(response);
// hide load more button, if there are not enough posts for the second page
if ( response.max_page < 2 ) {
$('.loadmore').hide();
} else {
$('.loadmore').show();
}
});
});
So When I’m applying filters, it works and the corrects results are displaying.
On page load without any filtering, the loadmore feature works fine.
But when I’m applying filters and then click on show more, no results are displaying ..
Thanks for your help !
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
You could possibly look at doing this the same way that WP Job Manager does:
https://github.com/Automattic/WP-Job-Manager/blob/master/assets/js/ajax-filters.js
This is done by triggering a handler to make the query defining what “page” the query should run against. I would recommend using that as an example to build off of, as it works with both filters applied and none being applied.
ALSO ALWAYS ALWAYS ALWAYS SANITIZE USER DATA
Anywhere you’re using $_POST $_GET $_REQUEST etc you should always sanitize the data before using it anywhere. Best to get in the habit of it or bad things could eventually happen.
https://developer.wordpress.org/themes/theme-security/data-sanitization-escaping/
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