How to paging when load ajax with wp_query? - ajax

I have an AJAX function that runs a PHP WP_Query function, and I'm not sure how these results would be outputted dynamically with pagination. The code in function.php
function feature_procject_list() {
// The $_REQUEST contains all the data sent via ajax
if ( isset($_REQUEST) ): ?>
<?php
$post_type = $_REQUEST['post_type'];
$id_cat = $_REQUEST['id_cat'];
$paged = ( get_query_var( 'paged' ) ) ? absint( get_query_var( 'paged' ) ) : 1;
$arr_2 = array(
'posts_per_page'=> 4,
'cat' => $id_cat,
'paged' => $paged,
);
$wp_query = new WP_Query( $arr_2 );
?>
<?php if($wp_query->have_posts()): ?>
<?php while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>
<div class="single_project">
<a class='img_thumb' href="<?php echo get_permalink();?>"><?php the_post_thumbnail('medium'); ?></a>
<h4><?php the_title(); ?></h4>
<p class="date"><?php the_date('j F \a\t G:i'); ?></p>
<?php the_excerpt(); ?>
</div>
<?php endwhile;
//wp_reset_postdata();
?>
<div id="paging_wrap">
<?php my_pagination(); ?>
<?php //paginate(); ?>
</div><!-- #paging_wrap -->
<?php else: ?>
<h4><?php _e( 'Sorry, no posts matched your criteria.' ); ?></h4>
<?php endif; ?>
<?php endif;die();
}
add_action( 'wp_ajax_feature_procject_list', 'feature_procject_list' );
add_action( 'wp_ajax_nopriv_feature_procject_list', 'feature_procject_list' );
function my_pagination() {
global $wp_query;
$big = 999999999; // need an unlikely integer
echo paginate_links( array(
'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
'format' => '?paged=%#%',
'current' => max( 1, get_query_var('paged') ),
'total' => $wp_query->max_num_pages
) );
}
And get it on the page template:
function get_list_feature_project(id_category) {
$.ajax({
url: ajaxurl,
data: {
'action':'feature_procject_list',
'id_cat' : id_category
},
beforeSend : function(){
$('#loading').show();
},
success:function(data) {
// This outputs the result of the ajax request
$('#loading').hide();
$('.list_post').html(data);
},
error: function(errorThrown){
console.log(errorThrown);
}
});
}
The post still show but paging not working.

Related

AJAX Search returns "You do not have sufficient permissions to access this page" on non-admin user

I have this demo website that I'm making:
https://theme.artware.gr/
The problem I am facing is on the search functionality. You can click on the right/top side search to see the issue. When I am logged-in as admin, the search works fine, but when I view the page as a guest I get the error: "You do not have sufficient permissions to access this page".
This is my code so far:
// AJAX Search (no WooCommerce)
if ( !class_exists( 'WooCommerce' ) ) {
function simple_search_scripts(){
wp_enqueue_script( 'simple_search', get_stylesheet_directory_uri() . '/js/search.js', array(), '1.0.0', true);
wp_localize_script('simple_search', 'myAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php', 'relative' ), 'nonce' => wp_create_nonce('ajax-nonce') ));
}
// Create shortcode
function simple_search(){
simple_search_scripts(); ?>
<input type="text" name="keyword" id="keyword" onkeyup="fetch()" placeholder="<?php _e('Αναζήτηση...'); ?>" />
<div id="datafetch"></div>
<?php
}
add_shortcode('simple_search', 'simple_search');
// Fetch data
function simple_search_callback(){
$the_query = new WP_Query( array( 'posts_per_page' => 10, 's' => esc_attr( $_GET['keyword'] ), 'post_type' => 'post' ) );
if( $the_query->have_posts() ) : while( $the_query->have_posts() ) : $the_query->the_post();
$myquery = esc_attr( $_GET['keyword'] );
$a = $myquery;
$search = get_the_title();
if( stripos("/{$search}/", $a) !== false) { ?>
<div class="result-sin">
<?php $image = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'medium' ); ?>
<div class="result-sin-img">
<?php if ($image) { ?>
<img src="<?php echo $image[0]; ?>" width="<?php echo $image[1]; ?>" height="<?php echo $image[2]; ?>" />
<?php } ?>
</div>
<div class="result-sin-tit"><?php the_title();?></div>
<div class="result-sin-txt"><?php the_excerpt();?></div>
</div>
<?php }
endwhile;
wp_reset_postdata();
endif;
die();
}
add_action('wp_ajax_simple_search', 'simple_search_callback' );
add_action('wp_ajax_nopriv_simple_search', 'simple_search_callback' );
}
And the search.js:
function fetch(){
jQuery.ajax({
async: true,
url: myAjax.ajaxurl,
type: 'GET',
data: {
action: 'simple_search',
keyword: jQuery('#keyword').val(),
nonce: myAjax.nonce
},
success: function(data) {
jQuery('#datafetch').html( data );
}
});
}
And on the header, I simply call a shortcode [simple_search] . Everything post I read on SO said that the wp_ajax_nopriv_ACTION was missing. But I already have that.
UPDATE
I tried using method GET, that didn't work. I also used: wp_localize_script('simple_search', 'myAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php', 'relative' ), 'nonce' => wp_create_nonce('ajax-nonce') )); to better enqueue the admin-ajax.php, that didn't work either.
Somewhere In my theme I had require_once('file.php') that had the line below:
if ( !current_user_can( 'manage_options' ) ) { wp_die( __( 'You do not have sufficient permissions to access this page.' ) ); }
When I removed this, the problem was fixed.

How to build a load more button and a filtering system with ajax on wordpress?

I managed to build a ajax load more following this tutorial.
I managed to make it work for my blog post on my blog page. So I didn't change anything.
Now I try to make the same for my custom post type, so I simply duplicate all code, changing the variable names :
Here is my custom post type archive page:
<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args=array(
'post_type' =>'formation',
'posts_per_page' =>5,
'paged' => $paged
);
$query = new WP_Query( $args ); //Check the WP_Query docs to see how you can limit which posts to display ?>
<?php if ( $query->have_posts() ) : ?>
<div id="cc_formation_wrap" class="flex-row">
<?php while ( $query->have_posts() ) : $query->the_post();
$termsArray = get_the_terms( $post->ID, "categories-formations" ); //Get the terms for this particular item
$termsString = ""; //initialize the string that will contain the terms
foreach ( $termsArray as $term ) { // for each term
$termsString .= $term->slug.' '; //create a string that has all the slugs } ?>
<div class="<?php echo $termsString;?> flex-col-md-4 item related-formation-post">
<article id="post-<?php the_ID(); ?>" <?php post_class();?>>
<div class="isotope-thumbnail">
<?php
if ( has_post_thumbnail() ) {
the_post_thumbnail('masonryLayout');
}; ?>
</div>
<div class="isotope-title">
<h3><?php the_title(); ?></h3>
</div>
<div class="entry-meta">
<?php if(get_field('duree')){
$duree = get_field_object('duree');
echo '<div><span class="isotope-duree">' . get_field('duree') . '</span></div>';}?>
</div>
<div class="isotope-excerpt">
<?php echo get_post_meta(get_the_ID(), '_yoast_wpseo_metadesc', true); ?>
</div>
<div class="isotope-cta">
Voir
</div>
</article>
</div>
<!-- end item -->
<?php endwhile; ?>
</div>
<!-- end isotope-list -->
<?php
global $wp_query;
if ( $wp_query->max_num_pages > 1 ) :
echo '<div id="cc_formation_loadmore">More posts</div>';
endif;
else :
get_template_part( 'template-parts/content', 'none' );
endif; ?>
Here is the code for functions.php file :
/*FITLERING AND LOADING MORE ON FORMATION PAGE*/
add_action( 'wp_enqueue_scripts', 'cc_formation_script_and_styles');
function cc_formation_script_and_styles() {
if( is_post_type_archive('formation') ){
global $wp_query;
wp_register_script( 'load-more', get_stylesheet_directory_uri() . '/js/load-more.js', array('jquery') );
wp_localize_script( 'load-more', 'cc_formation_loadmore_params', array(
'ajaxurl' => site_url() . '/wp-admin/admin-ajax.php', // WordPress AJAX
'posts' => json_encode( $wp_query->query_vars ), // everything about your loop is here
'current_page' => $wp_query->query_vars['paged'] ? $wp_query->query_vars['paged'] : 1,
'max_page' =>$wp_query->max_num_pages
) );
wp_enqueue_script( 'load-more' );
}
}
add_action('wp_ajax_loadmoreformationbutton', 'cc_formation_loadmore_ajax_handler');
add_action('wp_ajax_nopriv_loadmoreformationbutton', 'cc_formation_loadmore_ajax_handler');
function cc_formation_loadmore_ajax_handler(){
$args = json_decode( stripslashes( $_POST['query'] ), true );
$args['paged'] = $_POST['page'] + 1;
$args['post_status'] = 'publish';
$args["post_type"] = 'formation';
query_posts( $args );
if( have_posts() ) :
while( have_posts() ): the_post();
$termsArray = get_the_terms($post->ID, "categories-formations");
$termsString ="";
foreach ( $termsArray as $term ) {
$termsString .= $term->slug;
}
?>
<div class="<?php echo $termsString;?> flex-col-md-4 item related-formation-post">
<article id="post-<?php the_ID(); ?>" <?php post_class();?>>
<div class="isotope-thumbnail">
<?php
if ( has_post_thumbnail() ) {
the_post_thumbnail('masonryLayout');
} ;
?>
</div>
<div class="isotope-title">
<h3><?php the_title(); ?></h3>
</div>
<div class="isotope-excerpt">
<?php echo get_post_meta(get_the_ID(), '_yoast_wpseo_metadesc', true); ?>
</div>
<div class="isotope-cta">
Voir
</div>
</article>
</div> <!-- end item -->
<?php
endwhile;
endif;
die;
}
add_action('wp_ajax_ccformationfilter', 'cc_formation_filter_function');
add_action('wp_ajax_nopriv_ccformationfilter', 'cc_formation_filter_function');
function cc_formation_filter_function(){
$args = array(
'post_type' => 'formation',
'post_per_page'=>5,
'tax_query' => array(
array(
'taxonomy' => 'categories-formations',
'field' => 'slug',
'terms' => array('git','python','django','unix')
)
),
);
// run the query
query_posts( $args );
if( have_posts() ) :
ob_start();
while( have_posts() ): the_post();
$termsArray = get_the_terms($post->ID, "categories-formations");
$termsString ="";
foreach ( $termsArray as $term ) {
$termsString .= $term->slug;
}
?>
<div class="<?php echo $termsString;?> flex-col-md-4 item related-formation-post">
<article id="post-<?php the_ID(); ?>" <?php post_class();?>>
<div class="isotope-thumbnail">
<?php
if ( has_post_thumbnail() ) {
the_post_thumbnail('masonryLayout');
}
?>
</div>
<div class="isotope-title">
<h3><?php the_title(); ?></h3>
</div>
<div class="entry-meta">
<?php if(get_field('duree')){
$duree = get_field_object('duree');
echo '<div><span class="isotope-duree">' . get_field('duree') . '</span></div>';
}
?>
</div>
<div class="isotope-excerpt">
<?php echo get_post_meta(get_the_ID(), '_yoast_wpseo_metadesc', true); ?>
</div>
<div class="isotope-cta">
Voir
</div>
</article>
</div> <!-- end item -->
<?php
endwhile;
$posts_html = ob_get_contents();
ob_end_clean();
else:
$posts_html = '<p>Nothing found for your criteria.</p>';
endif;
echo json_encode( array(
'posts' => json_encode( $wp_query->query_vars ),
'max_page' => $wp_query->max_num_pages,
'found_posts' => $wp_query->found_posts,
'content' => $posts_html
) );
die();
}
So I changed the ajax action name, the params function etc. I kept the global wp_query but don't know if I also have to change that.
Then in a separate js file I put the following :
jQuery(function($){
/* LOAD MORE FUNCTION ON FORMATION ARCHIVE PAGE */
$('#cc_formation_loadmore').click(function(){
$.ajax({
url : cc_formation_loadmore_params.ajaxurl, // AJAX handler
data : {
'action': 'loadmoreformationbutton', // the parameter for admin-ajax.php
'query': cc_formation_loadmore_params.posts, // loop parameters passed by wp_localize_script()
'page' : cc_formation_loadmore_params.current_page // current page
},
type : 'POST',
beforeSend : function ( xhr ) {
$('#cc_formation_loadmore').text('Loading...'); // some type of preloader
},
success : function( posts ){
if( posts ) {
$('#cc_formation_loadmore').text( 'More posts' );
$('#cc_formation_wrap').append( posts ); // insert new posts
cc_formation_loadmore_params.current_page++;
if ( cc_formation_loadmore_params.current_page == cc_formation_loadmore_params.max_page )
$('#cc_formation_loadmore').hide(); // if last page, HIDE the button
} else {
$('#cc_formation_loadmore').hide(); // if no data, HIDE the button as well
}
}
});
return false;
});
/* FILTERING FUNCTION ON FORMATION ARCHIVE PAGE */
$('#formation_filters').change(function(){
$.ajax({
url : cc_formation_loadmore_params.ajaxurl,
data : $('#formation_filters').serialize(), // form data
dataType : 'json', // this data type allows us to receive objects from the server
type : 'POST',
success : function( data ){
// when filter applied:
// set the current page to 1
cc_formation_loadmore_params.current_page = 1;
// set the new query parameters
cc_formation_loadmore_params.posts = data.posts;
// set the new max page parameter
cc_formation_loadmore_params.max_page = data.max_page;
// change the button label back
// insert the posts to the container
$('#cc_formation_wrap').html(data.content);
// hide load more button, if there are not enough posts for the second page
if ( data.max_page < 2 ) {
$('#cc_formation_loadmore').hide();
} else {
$('#cc_formation_loadmore').show();
}
}
});
// do not submit the form
return false;
});
});
With this, the load more works. It displays the next custom posts type on my archive page.
But the filtering function doens't work.
So I need help to understand which variables I have to change. When I click on a filter checkbox, it first loads my blog post, and then the others filtering chekcbox don't work.
So I don't understand why it calls my blog posts.. What am I doing wrong ????
Looking for advice on this.
Thanks
Ok i finaly found my solultion !
1-In my project I first build a blog page (with normal blog posts) with categories filters and an ajax load more button.
Here is the code in my home.php
<?php
/**
* The main template file
*
* This is the most generic template file in a WordPress theme
* and one of the two required files for a theme (the other being style.css).
* It is used to display a page when nothing more specific matches a query.
* E.g., it puts together the home page when no home.php file exists.
*
* #link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* #package mysite
*/
get_header();
?>
<div id="primary" class="content-area">
<main id="main" class="site-main">
<div class="flex-container">
<div class="flex-row">
<header class="page-header">
<?php
single_post_title('<h1 class="page-title">', '</h1>' );
?>
</header><!-- .page-header -->
</div>
<div class="flex-row">
<form action="#" method="POST" id="post_filters">
<p>Clear</p>
<?php
if( $terms = get_terms( array( 'taxonomy' => 'category' ) ) ) :
foreach( $terms as $term ) :
echo '<p><input type="radio" id="' . $term->term_id . '" value="' . $term->term_id . '" name="category_filters" class="category_filter"/><label for="' . $term->term_id. '">' . $term->name . '</label></p>';
endforeach;
endif;
?>
<!-- required hidden field for admin-ajax.php -->
<input type="hidden" name="action" value="ccfilter" />
</form>
</div>
<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => 5,
'paged' => $paged
);
$query = new WP_Query( $args ); ?>
<?php
if ( $query->have_posts() ) :
$count = (int)0;?>
<div id="cc_posts_wrap" class="flex-row">
<?php
while ( $query->have_posts() ) : $count++;
$query->the_post();
if($count == 1){
$span = 'flex-col-xs-12';
$limit = 20;
}
if($count == 2 || $count == 3){
$span = 'flex-col-sm-6';
$limit = 13;
}
if($count > 3){
$span = 'flex-col-sm-4';
$limit = 13;
}
//If its not 3 or higher, increase the count
$termsArray = get_the_terms($post->ID, "category"); //Get the terms for this particular item
$termsString =""; //initialize the string that will contain the terms
foreach ( $termsArray as $term ) { // for each term
$termsString .= $term->slug;
}
?>
<div class="<?php echo $termsString .' ' . $span ;?> item">
<article id="post-<?php the_ID(); ?>" <?php post_class();?>>
<div class="post-featured-thumbnail">
<?php
if ( has_post_thumbnail() ) {
if($count == 1){
the_post_thumbnail('blog_featured');
}else{
the_post_thumbnail();
}
}
if ( 'post' === get_post_type() ) :
?>
<div class="entry-meta">
<?php
category_sticker();
?>
</div><!-- .entry-meta -->
<?php endif; ?>
</div>
<div class="post-content">
<header class="entry-header">
<?php
if ( is_singular() ) :
the_title( '<h1 class="entry-title">', '</h1>' );
else :
the_title( '<h2 class="entry-title">', '</h2>' );
endif;
?>
</header><!-- .entry-header -->
<div class="entry-content">
<?php echo excerpt($limit); ?>
</div><!-- .entry-content -->
</div>
</article><!-- #post-<?php the_ID(); ?> -->
</div>
<?php endwhile;
?>
</div> <!-- end isotope-list -->
<?php global $wp_query; // you can remove this line if everything works for you
if ( $wp_query->max_num_pages > 1 ) :
echo '<div id="cc_loadmore">More posts</div>'; // you can use <a> as well
endif;
else :
get_template_part( 'template-parts/content', 'none' );
endif;
?>
</div>
</main><!-- #main -->
</div><!-- #primary -->
<?php
get_footer();
Then in function php, the code for the load more button and the filters functions :
/*FUNCTION FILTER AND AJAX LOAD MORE*/
add_action( 'wp_enqueue_scripts', 'cc_script_and_styles');
function cc_script_and_styles() {
if ( is_home() ) {
global $wp_query;
wp_register_script( 'cc_scripts', get_stylesheet_directory_uri() . '/js/script.js', array('jquery') );
wp_localize_script( 'cc_scripts', 'cc_loadmore_params', array(
'ajaxurl' => site_url() . '/wp-admin/admin-ajax.php', // WordPress AJAX
'posts' => json_encode( $wp_query->query_vars ), // everything about your loop is here
'current_page' => $wp_query->query_vars['paged'] ? $wp_query->query_vars['paged'] : 1,
'max_page' => $wp_query->max_num_pages
) );
wp_enqueue_script( 'cc_scripts' );
}
}
add_action('wp_ajax_loadmorebutton', 'cc_loadmore_ajax_handler');
add_action('wp_ajax_nopriv_loadmorebutton', 'cc_loadmore_ajax_handler');
function cc_loadmore_ajax_handler(){
$params = json_decode( stripslashes( $_POST['query'] ), true );
$params['paged'] = $_POST['page'] + 1;
$params['post_status'] = 'publish';
query_posts( $params );
if( have_posts() ) :
while( have_posts() ): the_post();
$termsArray = get_the_terms($post->ID, "category");
$termsString ="";
foreach ( $termsArray as $term ) {
$termsString .= $term->slug;
}
?>
<div class="<?php echo $termsString ;?> flex-col-sm-4 item">
<article id="post-<?php the_ID(); ?>" <?php post_class();?>>
<div class="post-featured-thumbnail">
<?php
if ( has_post_thumbnail() ) {
if($count == 1){
the_post_thumbnail('blog_featured');
}else{
the_post_thumbnail();
}
}
;
if ( 'post' === get_post_type() ) :
?>
<div class="entry-meta">
<?php
category_sticker();
?>
</div><!-- .entry-meta -->
<?php endif; ?>
</div>
<div class="post-content">
<header class="entry-header">
<?php
if ( is_singular() ) :
the_title( '<h1 class="entry-title">', '</h1>' );
else :
the_title( '<h2 class="entry-title">', '</h2>' );
endif;
?>
</header><!-- .entry-header -->
<div class="entry-content">
<?php echo excerpt($limit); ?>
</div><!-- .entry-content -->
</div>
</article><!-- #post-<?php the_ID(); ?> -->
</div>
<?php
endwhile;
endif;
die;
}
add_action('wp_ajax_ccfilter', 'cc_filter_function');
add_action('wp_ajax_nopriv_ccfilter', 'cc_filter_function');
function cc_filter_function(){
if( isset( $_POST['category_filters'] ) )
$args['tax_query'] = array(
array(
'taxonomy' => 'category',
'field' => 'id',
'terms' => $_POST['category_filters'],
"posts_per_page" => 5
)
);
query_posts( $args );
global $wp_query;
if( have_posts() ) : $count = (int)0;
ob_start();
while( have_posts() ): $count++;
the_post();
if($count == 1){
$span = 'flex-col-xs-12';
$limit = 20;
}
if($count == 2 || $count == 3){
$span = 'flex-col-sm-6';
$limit = 13;
}
if($count > 3){
$span = 'flex-col-sm-4';
$limit = 13;
}
$termsArray = get_the_terms($post->ID, "category");
$termsString ="";
foreach ( $termsArray as $term ) {
$termsString .= $term->slug;
}
?>
<div class="<?php echo $termsString .' ' . $span ;?> item">
<article id="post-<?php the_ID(); ?>" <?php post_class();?>>
<div class="post-featured-thumbnail">
<?php
if ( has_post_thumbnail() ) {
if($count == 1){
the_post_thumbnail('blog_featured');
}else{
the_post_thumbnail();
}
}
;
if ( 'post' === get_post_type() ) :
?>
<div class="entry-meta">
<?php
category_sticker();
?>
</div><!-- .entry-meta -->
<?php endif; ?>
</div>
<div class="post-content">
<header class="entry-header">
<?php
if ( is_singular() ) :
the_title( '<h1 class="entry-title">', '</h1>' );
else :
the_title( '<h2 class="entry-title">', '</h2>' );
endif;
?>
</header><!-- .entry-header -->
<div class="entry-content">
<?php echo excerpt($limit); ?>
</div><!-- .entry-content -->
</div>
</article><!-- #post-<?php the_ID(); ?> -->
</div>
<?php
endwhile;
$posts_html = ob_get_contents();
ob_end_clean();
else:
$posts_html = '<p>Nothing found for your criteria.</p>';
endif;
echo json_encode( array(
'posts' => json_encode( $wp_query->query_vars ),
'max_page' => $wp_query->max_num_pages,
'found_posts' => $wp_query->found_posts,
'content' => $posts_html
) );
die();
}
Then, in a separate js file, the functions for the load more button and filters function :
jQuery(function($){
/* LOAD MORE FUNCTION */
$('#cc_loadmore').click(function(){
$.ajax({
url : cc_loadmore_params.ajaxurl, // AJAX handler
data : {
'action': 'loadmorebutton', // the parameter for admin-ajax.php
'query': cc_loadmore_params.posts, // loop parameters passed by wp_localize_script()
'page' : cc_loadmore_params.current_page // current page
},
type : 'POST',
beforeSend : function ( xhr ) {
$('#cc_loadmore').text('Loading...'); // some type of preloader
},
success : function( posts ){
if( posts ) {
$('#cc_loadmore').text( 'More posts' );
$('#cc_posts_wrap').append( posts ); // insert new posts
cc_loadmore_params.current_page++;
if ( cc_loadmore_params.current_page == cc_loadmore_params.max_page )
$('#cc_loadmore').hide(); // if last page, HIDE the button
} else {
$('#cc_loadmore').hide(); // if no data, HIDE the button as well
}
}
});
return false;
});
/* FILTERING FUNCTION */
$('#post_filters').change(function(){
$.ajax({
url : cc_loadmore_params.ajaxurl,
data : $('#post_filters').serialize(), // form data
dataType : 'json', // this data type allows us to receive objects from the server
type : 'POST',
success : function( data ){
cc_loadmore_params.current_page = 1;
cc_loadmore_params.posts = data.posts;
cc_loadmore_params.max_page = data.max_page;
$('#cc_posts_wrap').html(data.content);
if ( data.max_page < 2 ) {
$('#cc_loadmore').hide();
} else {
$('#cc_loadmore').show();
}
}
});
return false;
}); });
For blog posts, it's done and it works !
Explanations :
As you can see here, in functions.php, and the cc_script_and_styles function, and the -'cc_loadmore_params' are used everywhere in the js file. Be careful to write the same function in all places!
The action of the ajax call in the js file, 'loadmorebutton', is the same name than in the hook 'wp_ajax_loadmorebutton' in functions.php
add_action('wp_ajax_loadmorebutton', 'cc_loadmore_ajax_handler');
add_action('wp_ajax_nopriv_loadmorebutton', 'cc_loadmore_ajax_handler');
The value of the hidden input in home.php : 'ccfilter' is the same than in the hook of the function cc_filter_function(){
and
add_action('wp_ajax_ccfilter', 'cc_filter_function');
add_action('wp_ajax_nopriv_ccfilter', 'cc_filter_function');
Now, we also want to add similar filters and a load more button for a custom post type.
Here is my custom post type archive :
get_header();
?>
<div id="primary" class="content-area">
<main id="main" class="site-main">
<div class="flex-container">
<div class="flex-row">
<header class="page-header">
<?php
post_type_archive_title( '<h1 class="page-title">', '</h1>' );
?>
</header><!-- .page-header -->
</div>
<div class="flex-row">
<form action="#" method="POST" id="formation_filters">
<p>Clear</p>
<?php
if( $terms = get_terms( array( 'taxonomy' => 'categories-formations' ) ) ) :
foreach( $terms as $term ) :
echo '<p><input type="radio" id="' . $term->term_id . '" value="' . $term->term_id . '" name="category_formation_filters" class="category_formation_filters"/><label for="' . $term->term_id. '">' . $term->name . '</label></p>';
endforeach;
endif;
?>
<!-- required hidden field for admin-ajax.php -->
<input type="hidden" name="action" value="ccformationfilter" />
</form>
</div>
<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args=array(
'post_type' =>'formation',
'posts_per_page' =>5,
'paged' => $paged
);
$query = new WP_Query( $args );?>
<?php if ( $query->have_posts() ) : ?>
<div id="cc_formation_wrap" class="flex-row">
<?php while ( $query->have_posts() ) : $query->the_post();
$termsArray = get_the_terms( $post->ID, "categories-formations" );
$termsString = "";
foreach ( $termsArray as $term ) {
$termsString .= $term->slug.' ';
}
?>
<div class="<?php echo $termsString;?> flex-col-md-4 item related-formation-post">
<article id="post-<?php the_ID(); ?>" <?php post_class();?>>
<div class="isotope-thumbnail">
<?php
if ( has_post_thumbnail() ) {
the_post_thumbnail('masonryLayout');
} ;
?>
</div>
<div class="isotope-title">
<h3><?php the_title(); ?></h3>
</div>
<div class="entry-meta">
<?php if(get_field('duree')){
$duree = get_field_object('duree');
echo '<div><span class="isotope-duree">' . get_field('duree') . '</span></div>';
}
?>
</div>
<div class="isotope-excerpt">
<?php echo get_post_meta(get_the_ID(), '_yoast_wpseo_metadesc', true); ?>
</div>
<div class="isotope-cta">
Voir
</div>
</article>
</div> <!-- end item -->
<?php endwhile;
?>
</div> <!-- end isotope-list -->
<?php
if ( $query->max_num_pages > 1 ) :
echo '<div id="cc_formation_loadmore">More posts</div>';
endif;
else :
get_template_part( 'template-parts/content', 'none' );
endif; ?>
</div>
</main>
</div>
<script>
var posts_myajax = '<?php echo serialize( $query->query_vars ) ?>',
current_page_myajax = 1,
max_page_myajax = <?php echo $query->max_num_pages ?>
</script>
<script src="<?php bloginfo('template_url')?>/js/load-more.js"></script>
<?php get_footer();?>
Here we build the same type of filters, we just changed the name of the taxonomy, and declare the post_type parameter. We make our ajax call at the bottom of the file with new variables names. And we call a separate js file load-more.js.
In order to keep clean structure, I also created a separate file called : formation-query.php. In functions.php, I call it with:
require get_template_directory() . '/inc/formation-query.php';
We don't duplicate the function cc_script_and_styles() {
We just create our two functions for load more and filters with new variables names.
add_action('wp_ajax_loadmoreformationbutton', 'cc_formation_loadmore_ajax_handler');
add_action('wp_ajax_nopriv_loadmoreformationbutton', 'cc_formation_loadmore_ajax_handler');
function cc_formation_loadmore_ajax_handler(){
$args = json_decode( stripslashes( $_POST['query'] ), true );
$args['paged'] = $_POST['page'] + 1;
$args['post_status'] = 'publish';
$args["post_type"] = 'formation';
query_posts( $args );
global $wp_query;
if( have_posts() ) :
while( have_posts() ): the_post();
$termsArray = get_the_terms($post->ID, "categories-formations");
$termsString ="";
foreach ( $termsArray as $term ) {
$termsString .= $term->slug;
}
?>
<div class="<?php echo $termsString;?> flex-col-md-4 item related-formation-post">
<article id="post-<?php the_ID(); ?>" <?php post_class();?>>
<div class="isotope-thumbnail">
<?php
if ( has_post_thumbnail() ) {
the_post_thumbnail('masonryLayout');
} ;
?>
</div>
<div class="isotope-title">
<h3><?php the_title(); ?></h3>
</div>
<div class="isotope-excerpt">
<?php echo get_post_meta(get_the_ID(), '_yoast_wpseo_metadesc', true); ?>
</div>
<div class="isotope-cta">
Voir
</div>
</article>
</div> <!-- end item -->
<?php
endwhile;
endif;
die;
}
add_action('wp_ajax_ccformationfilter', 'cc_formation_filter_function');
add_action('wp_ajax_nopriv_ccformationfilter', 'cc_formation_filter_function');
function cc_formation_filter_function(){
$args["post_type"] = 'formation';
$args['tax_query'] = array(
array(
'taxonomy' => 'categories-formations',
'field' => 'id',
'terms' => $_POST['category_formation_filters'],
"posts_per_page" => 5
)
);
$query = new WP_Query($args);
if( $query->have_posts() ) :
ob_start();
while( $query->have_posts() ): $query->the_post();
$termsArray = get_the_terms($post->ID, "categories-formations");
$termsString ="";
foreach ( $termsArray as $term ) {
$termsString .= $term->slug;
}
?>
<div class="<?php echo $termsString;?> flex-col-md-4 item related-formation-post">
<article id="post-<?php the_ID(); ?>" <?php post_class();?>>
<div class="isotope-thumbnail">
<?php
if ( has_post_thumbnail() ) {
the_post_thumbnail('masonryLayout');
}
?>
</div>
<div class="isotope-title">
<h3><?php the_title(); ?></h3>
</div>
<div class="entry-meta">
<?php if(get_field('duree')){
$duree = get_field_object('duree');
echo '<div><span class="isotope-duree">' . get_field('duree') . '</span></div>';
}
?>
</div>
<div class="isotope-excerpt">
<?php echo get_post_meta(get_the_ID(), '_yoast_wpseo_metadesc', true); ?>
</div>
<div class="isotope-cta">
Voir
</div>
</article>
</div> <!-- end item -->
<?php
endwhile;
$posts_html = ob_get_contents();
ob_end_clean();
else:
$posts_html = '<p>Nothing found for your criteria.</p>';
endif;
echo json_encode( array(
'posts' => json_encode( $query->query_vars ),
'max_page' => $query->max_num_pages,
'found_posts' => $query->found_posts,
'content' => $posts_html
) );
die();
}
Now in a separate load-more.js file :
/* LOAD MORE FUNCTION ON FORMATION ARCHIVE PAGE */
$('#cc_formation_loadmore').click(function(){
data = {
'action': 'loadmoreformationbutton',
'query': posts_myajax,
'page' : current_page_myajax
};
$.ajax({
url : '/mysite/wp-admin/admin-ajax.php', // AJAX handler
data : data,
type : 'POST',
beforeSend : function ( xhr ) {
$('#cc_formation_loadmore').text('Loading...');
},
success : function( posts ){
if( posts ) {
$('#cc_formation_loadmore').text( 'More posts' );
$('#cc_formation_wrap').append( posts );
current_page_myajax++;
if ( current_page_myajax == max_page_myajax )
$('#cc_formation_loadmore').hide();
} else {
$('#cc_formation_loadmore').hide();
}
}
});
return false;
});
/* FILTERING FUNCTION ON FORMATION ARCHIVE PAGE */
$('#formation_filters').change(function(){
$.ajax({
url : '/mysite/wp-admin/admin-ajax.php',
data : $('#formation_filters').serialize(),
dataType : 'json',
type : 'POST',
success : function( data ){
current_page_myajax = 1;
posts_myajax = data.posts;
max_page_myajax = data.max_page;
$('#cc_formation_wrap').html(data.content);
if ( data.max_page < 2 ) {
$('#cc_formation_loadmore').hide();
} else {
$('#cc_formation_loadmore').show();
}
}
});
return false;
});
});
As you can see,
The 'loadmoreformationbutton' in the hook is the ajax action name in the js file.
The value of hidden input in the form 'ccformationfilter' is the name of the filter ajax function.
Now you can duplicate this if you need others load more buttons and filters for other custom post type !
It took me a while before understanding that function names had to be the same in every file. The different loops are of course also important.
As an option, you could avoid PITA with your own code followed by tutorial by using the pre-built plugin to achieve Ajax Load More and filtering in Wordpress.
https://wordpress.org/plugins/ajax-load-more/
It's a really good one I've used multiple times to implement Load More by Ajax in my websites.
The free version has plenty of features.

How to get Advanced Custom Fields values with Ajax in Wordpress

I'm trying to do a WP_query on a custom-post-type but for some reason I cannot get the values from the custom-field-types of these posts.
Here is what I got so far (functions.php)
function fetch_cases(){
$args = array(
'post_type' => array('case'),
'post_status' => array('publish'),
'posts_per_page' => 5
);
$query = new WP_Query($args);
if($query->have_posts()) {
while($query->have_posts() ){
$query->the_post();
?>
<a href="<?php the_permalink(); ?>">
<div style="background-image:url('<?= get_field('case_picture'); ?>')">
<p><?= get_field('case_title') ?></p>
</div>
</a>
<?php }
}
die();
add_action('wp_ajax_nopriv_fetch_cases', 'fetch_cases');
add_action('wp_ajax_fetch_cases','fetch_cases');
}
And in my JS file have the following:
$.ajax({
url: "/wp-admin/admin-ajax.php",
data: {
action: "fetch_cases"
},
success: function(data) {
$(".fetch_cases").append(data);
},
error: function(errorThrown) {
console.log(errorThrown);
}
});
Can someone tell me what I'm doing wrong?
I also tried to do:
<?php the_field('case_picture'); ?>
but with no luck? what am I missing?
add_action() should be outside your custom function. Try this instead.
function fetch_cases(){
$args = array(
'post_type' => array('case'),
'post_status' => array('publish'),
'posts_per_page' => 5
);
$query = new WP_Query($args);
if($query->have_posts()) {
while($query->have_posts() ){
$query->the_post();
?>
<a href="<?php the_permalink(); ?>">
<div style="background-image:url('<?= get_field('case_picture'); ?>')">
<p><?= get_field('case_title') ?></p>
</div>
</a>
<?php }
}
die();
}
add_action('wp_ajax_nopriv_fetch_cases', 'fetch_cases');
add_action('wp_ajax_fetch_cases','fetch_cases');
you can use this logic by storing the field as a hidden value and pass in ajax through js
$query = new WP_Query($args);
if($query->have_posts()) {
while($query->have_posts() ){
$query->the_post();
?>
<a href="<?php the_permalink(); ?>">
<div style="background-image:url('<?= get_field('case_picture'); ?>')">
<p><?= get_field('case_title') ?></p>
<input type="hidden" id="hidden" name="hidden_field" value="<?= get_field('case_picture'); ?>"> // store the value
</div>
</a>
<?php }
}
die();
Now get the data in jquery and pass through ajax
<script>
var hidden=//Grab data here.
$.ajax({
url: "/wp-admin/admin-ajax.php",
data: {
action: "fetch_cases",
image:hidden, // Pass the data
},
success: function(data) {
$(".fetch_cases").append(data);
},
error: function(errorThrown) {
console.log(errorThrown);
}
});
</script>
and use the data in ajax called
function fetch_cases()
{
$image=$_POST['image'];
}
get_field method has 2nd parameter which is post ID, pass this and check. It should work.
$post_id = $post->ID;
$value = get_field( 'case_picture', $post_id );

WP_Query on function not showing pagination

I have this code and its working fine, the only problem is that its not showing pagination. This code is on my functions.php file.
add_action( 'wp_ajax_nopriv_load-filter', 'prefix_load_cat_posts' );
add_action( 'wp_ajax_load-filter', 'prefix_load_cat_posts' );
function prefix_load_cat_posts () {
global $post;
$cat_id = $_POST[ 'cat' ];
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
$args = array (
'cat' => $cat_id,
'posts_per_page' => 6,
'order' => 'DESC',
'paged' => $paged
);
$cat_query = new WP_Query($args);
if($cat_query->have_posts()) :
while($cat_query->have_posts()) : $cat_query->the_post();
get_template_part( 'template-parts/content', get_post_format() );
endwhile;
wp_reset_query();
?>
<div class="page-nation">
<ul class="pagination pagination-large">
<?php
$pagination = get_the_posts_pagination(array(
'mid_size' => 2,
'prev_text' =>esc_html__('Previous', 'travel-tour'),
'next_text' => esc_html__('Next', 'travel-tour'),
'screen_reader_text' => ' ',
) );
echo $pagination;
?>
</ul>
</div>
<?php
endif;
die();
}
and this is my jquery ajax script
<script>
jQuery(document).ready(function () {
jQuery('.js-category-button').on('click', function(e){
e.preventDefault();
jQuery('.preloadswitch').addClass('addpreloader');
var catID = jQuery(this).data('slug');
var catName = jQuery(this).attr('href');
var ajaxurl = '<?php echo esc_js( admin_url( 'admin-ajax.php' ) ) ?>';
jQuery.ajax({
type: 'POST',
url: ajaxurl,
crossDomain : true,
dataType: 'html',
data: {"action": "load-filter", cat: catID },
beforeSend: function () {
jQuery(".the-categories").html('<div></div>').fadeIn('slow');
jQuery(".page-nation").hide();
//window.location.hash = "#"+jQuery("#comehere").attr("id");
jQuery('html,body').animate({scrollTop:jQuery('#comehere').offset().top}, 1000);
window.history.pushState('obj', 'newtitle', catName);
},
success: function(response) {
jQuery(".the-categories").append(response);
jQuery('.preloadswitch').removeClass('addpreloader');
return false;
}
});
})
});
</script>
I don't what to do here anymore, I have been searching on the web for possible working function but with no luck.
I just need to show the pagination
Comment out or remove the wp_reset_query();, or move it to after the pagination; and use paginate_links() instead of get_the_posts_pagination().
Here's the altered 'if-else' block in your prefix_load_cat_posts() function:
if($cat_query->have_posts()) :
while($cat_query->have_posts()) : $cat_query->the_post();
get_template_part( 'template-parts/content', get_post_format() );
endwhile;
//wp_reset_query();
?>
<div class="page-nation">
<ul class="pagination pagination-large">
<?php
$pagination = paginate_links(array(
'mid_size' => 2,
'prev_text' =>esc_html__('Previous', 'travel-tour'),
'next_text' => esc_html__('Next', 'travel-tour'),
'current' => $paged,
'total' => $cat_query->max_num_pages,
'type' => 'array',
'base' => home_url( '/%_%' ),
) );
echo '<li>' . implode( '</li><li>', $pagination ) . '</li>';
?>
</ul>
</div>
<?php
endif;
[EDIT] Try setting the base parameter.

wordpress showing comments from a post retrieved with ajax

i'm loading a post with ajax.
The code is
$(document).ready(function(){
loadPostsFun = function(){
$.ajax({
url: "http://lab1.koalamedia.es/ajax/",
//url: "/random/",
success: function(response){
$("#randomPost").html( response );
}
});
};
$("#another").click(function(){
loadPostsFun();
return false;
});
});
The response is generated by a custom template with this code:
<?php
query_posts('showposts=1&orderby=rand');
the_post();
$args = array( 'numberposts' => 1, 'orderby' => 'date' );
$rand_posts = get_posts( $args );
?>
<?php
foreach( $rand_posts as $post ) : setup_postdata($post);
?>
<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<?php if ( is_front_page() ) { ?>
<h2 class="entry-title"><?php the_title(); ?></h2>
<?php } else { ?>
<h1 class="entry-title"><?php the_title(); ?></h1>
<?php } ?>
<div class="entry-content">
<?php the_content(); ?>
<?php wp_link_pages( array( 'before' => '<div class="page-link">' . __( 'Pages:', 'twentyten' ), 'after' => '</div>' ) ); ?>
<?php comments_popup_link(__('Comments (0)'), __('Comments (1)'), __('Comments (%)')); ?>
</div><!-- .entry-content -->
</div><!-- #post-## -->
<?php
//comments_template( '', true ); //this doesn't work
comment_form();
//wp_list_comments(''); //this doesn't work
?>
<?php endforeach; ?>
The ajax request works but the comments doesn't show.All the post data is there.
How can i show the comments?
neither comments_template or wp_list_comments work.
You can view a demo or download the template sample i've done here
Without much tweaking wp_list_comments() works in a comments template (usually comments.php) only.
Use get_comments(), pass the post ID as parameter:
$comments = get_comments(array ( 'post_id' => $post->ID );
if ( $comments )
{
foreach ( $comments as $comment )
{
print "<li>$comment->comment_author<br>$comment->comment_content</li>";
}
}
i've found the problem, i forgot to set the global variable:
global $withcomments;
i was using
$withcomments = true;
comments_template();
but without the global it didn't work.
Now works like normal comments do.

Resources