I have two different AJAX load more functions in my website. One for my archive page, the second for the taxonomy page.
The issue is, there is a conflict when both AJAX handler functions are in my functions.php. When there is only one handler function, the latter works fine.
The JS code for both AJAX action:
/*
* AJAX Load More for archive page
*/
$('.load-more-archive').click(function(){
var button = $(this),
data = {
'action': handler,
'query': posts_myajax,
'page' : current_page_myajax
};
$.ajax({
url : '../wp-admin/admin-ajax.php', // AJAX handler
data : data,
type : 'POST',
beforeSend : function ( xhr ) {
button.hide();
},
success : function( data ){
if( data ) {
$('.wrapper-archive').append(data);
button.show();
current_page_myajax++;
if ( current_page_myajax == max_page_myajax )
button.remove();
} else {
//button.remove();
}
}
});
});
/*
* AJAX Load More for taxonomy page
*/
$('.load-more-tax').click(function(){
var button = $(this),
data = {
'action': handler,
'tax_post_type': current_post_type,
'tax_term': tax_term_id,
'query': posts_myajax,
'page' : current_page_myajax,
};
$.ajax({
url : '../wp-admin/admin-ajax.php',
data : data,
type : 'POST',
beforeSend : function ( xhr ) {
button.hide();
},
success : function( data ){
if( data ) {
$('.wrapper-taxonomy').append(data);
button.show();
current_page_myajax++;
if ( current_page_myajax == max_page_myajax )
button.remove();
} else {
//button.remove();
}
}
});
});
Here is PHP code of both AJAX handler:
/**
* AJAX handler for archive page
*/
function archive_loadmore_ajax_handler(){
$args = json_decode( stripslashes( $_POST['query'] ), true );
$args['paged'] = $_POST['page'] + 1;
$args['post_type'] = $_POST['action'];
$args['posts_per_page'] = 4;
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) : while ( $the_query->have_posts() ) : $the_query->the_post();
get_template_part( 'template-parts/content', 'cpt-archive' );
endwhile;
endif;
die;
}
add_action('wp_ajax_'. $_POST['action'] .'', 'archive_loadmore_ajax_handler');
add_action('wp_ajax_nopriv_'. $_POST['action'] .'', 'archive_loadmore_ajax_handler');
/**
* AJAX handler for taxonomy page
*/
function taxonomy_loadmore_ajax_handler(){
$args = json_decode( stripslashes( $_POST['query'] ), true );
$args['paged'] = $_POST['page'] + 1;
$args['post_type'] = $_POST['tax_post_type'];
$args['posts_per_page'] = 4;
$args['tax_query'] = array(
array (
'taxonomy' => $_POST['action'],
'field' => 'id',
'terms' => $_POST['tax_term']
)
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) : while ( $the_query->have_posts() ) : $the_query->the_post();
get_template_part( 'template-parts/content', 'cpt-archive' );
endwhile;
endif;
die;
}
add_action('wp_ajax_'. $_POST['action'] .'', 'taxonomy_loadmore_ajax_handler');
add_action('wp_ajax_nopriv_'. $_POST['action'] .'', 'taxonomy_loadmore_ajax_handler');
I understand that there is a conflict when calling the AJAX script, but I don’t find the way how to solve it. Any help would be much appreciated. Thank you!
EDIT
I updated the PHP AJAX and JS AJAX following the recommendations:
The JS
$('.load-more-archive').click(function(){
var button = $(this),
data = {
'action': 'load_archive',
'my_post_type': current_post_type,
'query': posts_myajax,
'page' : current_page_myajax
};
$.ajax({
url : 'http://localhost:8888/sites/mysite/wp-admin/admin-ajax.php',
data : data,
type : 'POST',
beforeSend : function ( xhr ) {
button.hide();
},
success : function( data ){
if( data ) {
$('.wrapper-archive').append(data);
isLoaded();
button.show(); // Insert new posts
current_page_myajax++;
if ( current_page_myajax == max_page_myajax )
button.remove();
} else {
//button.remove();
}
}
});
});
THE PHP
function mysite_archive_loadmore_ajax_handler(){
$args = json_decode( stripslashes( $_POST['query'] ), true );
$args['paged'] = $_POST['page'] + 1;
$args['post_type'] = $_POST['my_post_type'];
$args['posts_per_page'] = 4;
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) : while ( $the_query->have_posts() ) : $the_query->the_post();
get_template_part( 'template-parts/content', 'cpt-archive' );
endwhile;
endif;
die;
}
add_action('wp_ajax_load_archive', 'mysite_archive_loadmore_ajax_handler');
add_action('wp_ajax_nopriv_load_archive', 'mysite_archive_loadmore_ajax_handler');
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
The use of $_POST['action'] in the WP_Query and as a dynamic action name is dangerous, and in the code triggers the handler on all AJAX requests even those you don’t want. This is unavoidable and a dead end that cannot be fixed. Alternatives are mandatory.
Instead, use a static non-dynamic action name, E.g. mathieu_loadmode_post_archive or mathieu_loadmode_taxonomy_archive, then pass the post type or taxonomy name in your javascripts AJAX the same way you’re passing tax_term or tax_post_type.
Other notes:
- do not use relative paths for
admin-ajax.php, the examples use localised data or absolute paths for a reason, your code will fail if your URL structure needs more than on..with relative paths - whitelist those options, only allow a limited subset of values, right now I could request any data I want from your site, or ask it for something extremely slow and expensive. User data is not trustworthy, don’t pass it into APIs/classes without checks. E.g. what’s to stop me adding a
meta_valueparameter, or one of the__not_inparameters. Or requesting all posts by an author for an internal post type that’s not meant to be accessible.
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