I have a custom loop with wp_query, this is a table showing the orders placed by a user. Everything works fine, content displayed, pagination and data are ok.
To test I am showing 4 results per page, what I am trying to do is dynamically load other results with ajax pagination. I want that when I click on page 2 another 4 posts are loaded instead of loading another page.
Now the ajax call seems to work, when I click on page 2 it loads correctly but as a result I get 0 instead of loading other posts. Why is this happening ?
Template.php
<script src="https://mywebsite.com/wp-content/themes/astra-child/woocommerce/myaccount/assets/main.js?<?php $FourDigitRandomNumber = mt_rand(00000,99999); echo $FourDigitRandomNumber; ?>" defer=""></script>
<h3>Custom Endpoint</h3>
<div id="content">
<?php
global $wp_query;
$paged = max( 1, (int) filter_input( INPUT_GET, 'pagina' ) );
$order_statuses = array('wc-completed');
$args = array(
'post_type' => 'shop_order',
'paged' => $paged,
'posts_per_page' => 4,
'post_status' => $order_statuses,
'customer_id' => get_current_user_id(),
);
$loop = new WP_Query( $args );
$post_count = $loop->found_posts;
// The Wordpress post loop
if( $loop->have_posts() ) {
while( $loop->have_posts() ) {
$loop->the_post();
// The order ID
$order_id = $loop->post->ID;
// Get an instance of the WC_Order Object
$order = wc_get_order($loop->post->ID);
$items = $order->get_items();
$orders_id = $order->get_id();
$status = wc_get_order_status_name( $order->get_status() );
$date_created = $order->get_date_created()->date('d/m/Y');
$payment_method = $order->get_payment_method_title();
$order_total = $order->get_formatted_order_total();
foreach ( $items as $item ) {
$product_name = $item->get_name();
$view_order = $order->get_view_order_url();
// Get product image - https://www.businessbloomer.com/woocommerce-easily-get-product-info-title-sku-desc-product-object/
$product = $item->get_product();
if( $product instanceof WC_Product ){
$order_img = $product->get_image();
}
//Get product download button
$downloads = $order->get_downloadable_items();
if(is_array($downloads)) {
foreach($downloads as $product){
$download_button = '<a href="'. $product['download_url'] .'" target="_blank">Download</a>';
}
}
echo '
<table >
<tr >
<td >
<span >Ordine</span>
<span>#'. esc_attr($orders_id) .'</span>
</td>
<td >
<span >Prodotto</span>
<a href="'. wp_kses_post($view_order) .'">'. wp_kses_post($product_name) .'</a>
</td>
<td >
<span >Data</span>
<span>'. wp_kses_post($date_created) .'</span>
</td>
<td >
<span >Prezzo</span>
<span>'. wp_kses_post($order_total) .'</span>
</td>
<td >
<span >Stato</span>
<span >'. wp_kses_post($status) .'</span>
</td>
<td >
<span >File</span>
<a target=”_blank” href="'. esc_url($view_order) .'">Visualizza<i ></i></a>
</td>
</tr>
</table>
';
}
}
}
// Pagination
if ( $post_count > 4 ) {
?><div id="pagination" ><?php
$args = array(
'base' => esc_url( 'https://motustrength.it/account/custom/' ) . '%_%',
'format' => '?pagina=%#%',
'total' => $loop->max_num_pages,
'current' => $paged,
'show_all' => false,
'end_size' => 3,
'mid_size' => 3,
'prev_next' => true,
'prev_text' => __('<i ></i><span>Indietro</span>'),
'next_text' => __('<span>Avanti</span><i ></i>'),
'type' => 'plain',
'add_args' => false,
'add_fragment' => ''
);
echo paginate_links($args);
}
else {
?><div >Nessun download disponibile, non hai ancora acquistato alcun prodotto.</div><?php
}
?></div><?php
File Js
(function( $ ) {
$.fn.wpPagination = function( options ) {
options = $.extend({
links: "a",
action: "pagination",
ajaxURL: "https://" location.host "/wp-admin/admin-ajax.php",
next: ".next"
}, options);
function WPPagination( element ) {
this.$el = $( element );
this.init();
}
WPPagination.prototype = {
init: function() {
this.createLoader();
this.createEnd();
this.handleNext();
this.handleLinks();
},
createLoader: function() {
var self = this;
$('#pagination').prepend( "<span id='pagination-loader'>Loading...</span>" );
$('#pagination-loader').hide();
},
createEnd: function() {
var self = this;
$('#pagination').prepend( "<span id='pagination-end'>End</span>" );
$('#pagination-end').hide();
},
handleNext: function() {
var self = this;
var $next = $( options.next, self.$el );
},
handleLinks: function() {
var self = this,
$links = $( options.links, self.$el ),
$pagination = $( "#pagination" );
$loader = $( "#pagination-loader" );
$end = $( "#pagination-end" );
$links.click(function( e ) {
e.preventDefault();
$('#pagination .next').fadeOut();
$loader.fadeIn();
var $a = $( this ),
url = $a.attr("href"),
page = url.match( /\d / ),
pageNumber = page[0],
data = {
action: options.action,
page: pageNumber,
shop_order: $('#pagination-post-type').text()
};
$.get( options.ajaxURL, data, function( html ) {
$pagination.before( "<div id='page-" pageNumber "'></div>" );
$pagination.before( html );
$a.attr("href", url.replace('/' pageNumber '/', '/' ( parseInt(pageNumber) 1 ) '/'));
if ( !html ) {
$('#pagination .next').remove();
$loader.fadeOut();
$end.fadeIn();
} else {
$loader.fadeOut();
$('#pagination .next').fadeIn();
//smoothScroll($('#page-' pageNumber), 85);
}
});
});
}
};
return this.each(function() {
var element = this;
var pagination = new WPPagination( element );
});
};
$(function() {
if( $( "#pagination" ).length ) {
$( "#pagination" ).wpPagination();
}
});
})( jQuery );
Functions.php
// ajax pag
function get_posts_for_pagination() {
$html = '';
$paged = ( $_GET['page'] ) ? $_GET['page'] : 1;
$post_type = $_GET['shop_order'];
if ( empty($post_type) ) {
return '';
}
if( filter_var( intval( $paged ), FILTER_VALIDATE_INT ) ) {
$paged = max( 1, (int) filter_input( INPUT_GET, 'pagina' ) );
$order_statuses = array('wc-completed');
$args = array(
'post_type' => 'shop_order',
'paged' => $paged,
'posts_per_page' => 4,
'post_status' => $order_statuses,
'customer_id' => get_current_user_id(),
);
$loop = new WP_Query( $args );
$post_count = $loop->found_posts;
// The Wordpress post loop
if( $loop->have_posts() ) {
while( $loop->have_posts() ) {
$loop->the_post();
// The order ID
$order_id = $loop->post->ID;
// Get an instance of the WC_Order Object
$order = wc_get_order($loop->post->ID);
$items = $order->get_items();
$orders_id = $order->get_id();
$status = wc_get_order_status_name( $order->get_status() );
$date_created = $order->get_date_created()->date('d/m/Y');
$payment_method = $order->get_payment_method_title();
$order_total = $order->get_formatted_order_total();
foreach ( $items as $item ) {
$product_name = $item->get_name();
$view_order = $order->get_view_order_url();
// Get product image - https://www.businessbloomer.com/woocommerce-easily-get-product-info-title-sku-desc-product-object/
$product = $item->get_product();
if( $product instanceof WC_Product ){
$order_img = $product->get_image();
}
//Get product download button
$downloads = $order->get_downloadable_items();
if(is_array($downloads)) {
foreach($downloads as $product){
$download_button = '<a href="'. $product['download_url'] .'" target="_blank">Download</a>';
}
}
echo '
<table >
<tr >
<td >
<span >Ordine</span>
<span>#'. esc_attr($orders_id) .'</span>
</td>
<td >
<span >Prodotto</span>
<a href="'. wp_kses_post($view_order) .'">'. wp_kses_post($product_name) .'</a>
</td>
<td >
<span >Data</span>
<span>'. wp_kses_post($date_created) .'</span>
</td>
<td >
<span >Prezzo</span>
<span>'. wp_kses_post($order_total) .'</span>
</td>
<td >
<span >Stato</span>
<span >'. wp_kses_post($status) .'</span>
</td>
<td >
<span >File</span>
<a target=”_blank” href="'. esc_url($view_order) .'">Visualizza<i ></i></a>
</td>
</tr>
</table>
';
}
} wp_reset_query();
}
}
echo $html;
exit();
}
add_action( 'wp_ajax_pagination', 'get_posts_for_pagination' );
add_action( 'wp_ajax_nopriv_pagination', 'get_posts_for_pagination' );
CodePudding user response:
For now I have found a solution even if it was not what I was trying to do, maybe I was wrong from the beginning. The idea was to go to page 2 without reloading the page. With the code below, instead of going to page 2, other elements are simply added to the already existing elements.
Also, if I wanted to add the same ajax function to another template I would have to add more code to the functions.php. I think it is a very dirty and not very functional practice.
Anyway I leave the "correct" code for the workaround.
Template.php
<script src="https://mywebsite.com/wp-content/themes/astra-child/woocommerce/myaccount/assets/custom.js?<?php $FourDigitRandomNumber = mt_rand(00000,99999); echo $FourDigitRandomNumber; ?>" defer=""></script>
<link rel="stylesheet" type="text/css" href="https://mywebsite.com/wp-content/themes/astra-child/woocommerce/myaccount/assets/custom.css?<?php $FourDigitRandomNumber = mt_rand(00000,99999); echo $FourDigitRandomNumber; ?>" />
<h3>Custom Endpoint</h3>
<?php
global $wp_query;
//Variable For Args Query
$paged = max( 1, (int) filter_input( INPUT_GET, 'pagina' ) );
$order_statuses = array('wc-completed');
$args = array(
'post_type' => 'shop_order',
'paged' => $paged,
'posts_per_page' => 4,
'post_status' => $order_statuses,
);
$loop = new WP_Query( $args );
// Loop Content
if( $loop->have_posts() ) {
while( $loop->have_posts() ) {
$loop->the_post();
//Here content
// The order ID
$order_id = $loop->post->ID;
// Get an instance of the WC_Order Object
$order = wc_get_order($loop->post->ID);
$items = $order->get_items();
$orders_id = $order->get_id();
$status = wc_get_order_status_name( $order->get_status() );
$date_created = $order->get_date_created()->date('d/m/Y');
$payment_method = $order->get_payment_method_title();
$order_total = $order->get_formatted_order_total();
foreach ( $items as $item ) {
$product_name = $item->get_name();
$view_order = $order->get_view_order_url();
// Get product image - https://www.businessbloomer.com/woocommerce-easily-get-product-info-title-sku-desc-product-object/
$product = $item->get_product();
if( $product instanceof WC_Product ){
$order_img = $product->get_image();
}
//Get product download button
$downloads = $order->get_downloadable_items();
if(is_array($downloads)) {
foreach($downloads as $product){
$download_button = '<a href="'. $product['download_url'] .'" target="_blank">Download</a>';
}
}
echo '
<table >
<tr >
<td >
<span >Ordine</span>
<span>#'. esc_attr($orders_id) .'</span>
</td>
<td >
<span >Prodotto</span>
<a href="'. wp_kses_post($view_order) .'">'. wp_kses_post($product_name) .'</a>
</td>
<td >
<span >Data</span>
<span>'. wp_kses_post($date_created) .'</span>
</td>
<td >
<span >Prezzo</span>
<span>'. wp_kses_post($order_total) .'</span>
</td>
<td >
<span >Stato</span>
<span >'. wp_kses_post($status) .'</span>
</td>
<td >
<span >File</span>
<a target=”_blank” href="'. esc_url($view_order) .'">Visualizza<i ></i></a>
</td>
</tr>
</table>
';
}
}
// Pagination
?><div id="pagination" ><?php
$args = array(
'base' => esc_url( 'https://motustrength.it/account/custom/' ) . '%_%',
'format' => '?pagina=%#%',
'total' => $loop->max_num_pages,
'current' => $paged,
'show_all' => false,
'end_size' => 3,
'mid_size' => 3,
'prev_next' => true,
'prev_text' => __('<i ></i><span>Indietro</span>'),
'next_text' => __('<span>Avanti</span><i ></i>'),
'type' => 'plain',
'add_args' => false,
'add_fragment' => ''
);
echo paginate_links($args);
}
else {
?><div >Nessun download disponibile, non hai ancora acquistato alcun prodotto.</div><?php
}
?></div><?php
File.js
(function( $ ) {
$.fn.wpPagination = function( options ) {
options = $.extend({
links: "a",
action: "pagination",
ajaxURL: "https://" location.host "/wp-admin/admin-ajax.php",
next: ".next",
previous: ".previous",
disablePreviousNext: false
}, options);
function WPPagination( element ) {
this.$el = $( element );
this.init();
}
WPPagination.prototype = {
init: function() {
this.createLoader();
this.handlePreviousNextLinks();
this.handleLinks();
},
createLoader: function() {
var self = this;
self.$el.before( "<div id='pagination-loader'></div>" );
},
handlePreviousNextLinks: function() {
var self = this;
var $previous = $( options.previous, self.$el );
var $next = $( options.next, self.$el );
if( options.disablePreviousNext ) {
$previous.remove();
$next.remove();
} else {
$previous.addClass( "clicked" );
$next.addClass( "clicked" );
}
},
handleLinks: function() {
var self = this,
$links = $( options.links, self.$el ),
$loader = $( "#pagination-loader" );
$links.click(function( e ) {
e.preventDefault();
var $a = $( this ),
url = $a.attr( "href" ),
page = url.match( /\d / ), // Get the page number
pageNumber = page[0],
data = {
action: options.action, // Pass the AJAX action name along with the page number
page: pageNumber
};
if( !$a.hasClass( "clicked" ) ) { // We don't want duplicated posts
$loader.show(); // Show the loader
$.get( options.ajaxURL, data, function( html ) {
$loader.hide(); // Hide the loader
$loader.before( html ); // Insert posts
$a.addClass( "clicked" ); // Flag the current link as clicked
});
}
});
}
};
return this.each(function() {
var element = this;
var pagination = new WPPagination( element );
});
};
})( jQuery );
(function( $ ) {
$(function() {
if( $( "#pagination" ).length ) {
$( "#pagination" ).wpPagination();
}
});
})( jQuery );
functions.php
// Ajax Pagination
function my_get_posts_for_pagination() {
$paged = $_GET['page']; // Page number
$html = '';
$pag = 0;
if( filter_var( intval( $paged ), FILTER_VALIDATE_INT ) ) {
$order_statuses = array('wc-completed');
$pag = $paged;
$args = array(
'post_type' => 'shop_order',
'paged' => $pag, // Uses the page number passed via AJAX
'posts_per_page' => 4, // Change this as you wish
'post_status' => $order_statuses,
'customer_id' => get_current_user_id(),
);
$loop = new WP_Query( $args );
// The Wordpress post loop
if( $loop->have_posts() ) {
while( $loop->have_posts() ) {
$loop->the_post();
// Build the HTML string with your post's contents
// The order ID
$order_id = $loop->post->ID;
// Get an instance of the WC_Order Object
$order = wc_get_order($loop->post->ID);
$items = $order->get_items();
$orders_id = $order->get_id();
$status = wc_get_order_status_name( $order->get_status() );
$date_created = $order->get_date_created()->date('d/m/Y');
$payment_method = $order->get_payment_method_title();
$order_total = $order->get_formatted_order_total();
foreach ( $items as $item ) {
$product_name = $item->get_name();
$view_order = $order->get_view_order_url();
// Get product image - https://www.businessbloomer.com/woocommerce-easily-get-product-info-title-sku-desc-product-object/
$product = $item->get_product();
if( $product instanceof WC_Product ){
$order_img = $product->get_image();
}
//Get product download button
$downloads = $order->get_downloadable_items();
if(is_array($downloads)) {
foreach($downloads as $product){
$download_button = '<a href="'. $product['download_url'] .'" target="_blank">Download</a>';
}
}
//What you want to show
echo '
<table >
<tr >
<td >
<span >Ordine</span>
<span>#'. esc_attr($orders_id) .'</span>
</td>
<td >
<span >Prodotto</span>
<a href="'. wp_kses_post($view_order) .'">'. wp_kses_post($product_name) .'</a>
</td>
<td >
<span >Data</span>
<span>'. wp_kses_post($date_created) .'</span>
</td>
<td >
<span >Prezzo</span>
<span>'. wp_kses_post($order_total) .'</span>
</td>
<td >
<span >Stato</span>
<span >'. wp_kses_post($status) .'</span>
</td>
<td >
<span >File</span>
<a target=”_blank” href="'. esc_url($view_order) .'">Visualizza<i ></i></a>
</td>
</tr>
</table>
';
}
wp_reset_query();
}
}
}
echo $html;
exit();
}
add_action( 'wp_ajax_pagination', 'my_get_posts_for_pagination' );
add_action( 'wp_ajax_nopriv_pagination', 'my_get_posts_for_pagination' );