Load More Posts Ajax Button in Wordpress

Load More Posts Ajax Button in WordPress

UPDATE 24.04.2016.

I've created tutorial on my page https://madebydenis.com/ajax-load-posts-on-wordpress/ about implementing this on Twenty Sixteen theme, so feel free to check it out :)

EDIT

I've tested this on Twenty Fifteen and it's working, so it should be working for you.

In index.php (assuming that you want to show the posts on the main page, but this should work even if you put it in a page template) I put:

    <div id="ajax-posts" class="row">
<?php
$postsPerPage = 3;
$args = array(
'post_type' => 'post',
'posts_per_page' => $postsPerPage,
'cat' => 8
);

$loop = new WP_Query($args);

while ($loop->have_posts()) : $loop->the_post();
?>

<div class="small-12 large-4 columns">
<h1><?php the_title(); ?></h1>
<p><?php the_content(); ?></p>
</div>

<?php
endwhile;
wp_reset_postdata();
?>
</div>
<div id="more_posts">Load More</div>

This will output 3 posts from category 8 (I had posts in that category, so I used it, you can use whatever you want to). You can even query the category you're in with

$cat_id = get_query_var('cat');

This will give you the category id to use in your query. You could put this in your loader (load more div), and pull with jQuery like

<div id="more_posts" data-category="<?php echo $cat_id; ?>">>Load More</div>

And pull the category with

var cat = $('#more_posts').data('category');

But for now, you can leave this out.

Next in functions.php I added

wp_localize_script( 'twentyfifteen-script', 'ajax_posts', array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'noposts' => __('No older posts found', 'twentyfifteen'),
));

Right after the existing wp_localize_script. This will load WordPress own admin-ajax.php so that we can use it when we call it in our ajax call.

At the end of the functions.php file I added the function that will load your posts:

function more_post_ajax(){

$ppp = (isset($_POST["ppp"])) ? $_POST["ppp"] : 3;
$page = (isset($_POST['pageNumber'])) ? $_POST['pageNumber'] : 0;

header("Content-Type: text/html");

$args = array(
'suppress_filters' => true,
'post_type' => 'post',
'posts_per_page' => $ppp,
'cat' => 8,
'paged' => $page,
);

$loop = new WP_Query($args);

$out = '';

if ($loop -> have_posts()) : while ($loop -> have_posts()) : $loop -> the_post();
$out .= '<div class="small-12 large-4 columns">
<h1>'.get_the_title().'</h1>
<p>'.get_the_content().'</p>
</div>';

endwhile;
endif;
wp_reset_postdata();
die($out);
}

add_action('wp_ajax_nopriv_more_post_ajax', 'more_post_ajax');
add_action('wp_ajax_more_post_ajax', 'more_post_ajax');

Here I've added paged key in the array, so that the loop can keep track on what page you are when you load your posts.

If you've added your category in the loader, you'd add:

$cat = (isset($_POST['cat'])) ? $_POST['cat'] : '';

And instead of 8, you'd put $cat. This will be in the $_POST array, and you'll be able to use it in ajax.

Last part is the ajax itself. In functions.js I put inside the $(document).ready(); enviroment

var ppp = 3; // Post per page
var cat = 8;
var pageNumber = 1;


function load_posts(){
pageNumber++;
var str = '&cat=' + cat + '&pageNumber=' + pageNumber + '&ppp=' + ppp + '&action=more_post_ajax';
$.ajax({
type: "POST",
dataType: "html",
url: ajax_posts.ajaxurl,
data: str,
success: function(data){
var $data = $(data);
if($data.length){
$("#ajax-posts").append($data);
$("#more_posts").attr("disabled",false);
} else{
$("#more_posts").attr("disabled",true);
}
},
error : function(jqXHR, textStatus, errorThrown) {
$loader.html(jqXHR + " :: " + textStatus + " :: " + errorThrown);
}

});
return false;
}

$("#more_posts").on("click",function(){ // When btn is pressed.
$("#more_posts").attr("disabled",true); // Disable the button, temp.
load_posts();
});

Saved it, tested it, and it works :)

Images as proof (don't mind the shoddy styling, it was done quickly). Also post content is gibberish xD

Sample Image

Sample Image

Sample Image

UPDATE

For 'infinite load' instead on click event on the button (just make it invisible, with visibility: hidden;) you can try with

$(window).on('scroll', function () {
if ($(window).scrollTop() + $(window).height() >= $(document).height() - 100) {
load_posts();
}
});

This should run the load_posts() function when you're 100px from the bottom of the page. In the case of the tutorial on my site you can add a check to see if the posts are loading (to prevent firing of the ajax twice), and you can fire it when the scroll reaches the top of the footer

$(window).on('scroll', function(){
if($('body').scrollTop()+$(window).height() > $('footer').offset().top){
if(!($loader.hasClass('post_loading_loader') || $loader.hasClass('post_no_more_posts'))){
load_posts();
}
}
});

Now the only drawback in these cases is that you could never scroll to the value of $(document).height() - 100 or $('footer').offset().top for some reason. If that should happen, just increase the number where the scroll goes to.

You can easily check it by putting console.logs in your code and see in the inspector what they throw out

$(window).on('scroll', function () {
console.log($(window).scrollTop() + $(window).height());
console.log($(document).height() - 100);
if ($(window).scrollTop() + $(window).height() >= $(document).height() - 100) {
load_posts();
}
});

And just adjust accordingly ;)

Hope this helps :) If you have any questions just ask.

Load More Custom Posts On Click Ajax WordPress

There is a good amount here to fix.

Your Ajax is syntax is off a bit. Also, you can specify posts per page for the return with PHP, so you don't need to send that, you can keep your page attribute on the frontend.

$("#more_posts").on("click", function(e) {


$.ajax({
// use the ajax object url
url: ajax_object.ajax_url,
data: {
action: "more_post_ajax", // add your action to the data object
offset: page * 4 // page # x your default posts per page
},
success: function(data) {
// add the posts to the container and add to your page count
page++;
$('.projects').append(data);

},
error: function(data) {
// test to see what you get back on error
console.log(data);
}
});

});

For your initial PHP function, you should only specify the amount of posts you want to show at first. If you use -1 it will just show all posts at the start, which you don't want. You also don't need to use the paged parameter. You only need offsets.

<?php 
$args = array(
'post_type' => 'project',
'status' => 'publish',
'order' => 'ASC',
'posts_per_page' => 4,
);
$posts = new WP_Query($args);
?>

<div class="projects">

<?php
while ($posts->have_posts()) {
$posts->the_post(); ?>

<div class="project">
<?php the_title(); ?>
</div>

<?php
wp_reset_postdata();
}; ?>

</div>

For your more posts function, you only need to specify an offset, and can add your additional posts right in that function.

function more_post_ajax(){
$offset = $_POST["offset"];


$args = array(
'post_type' => 'project',
'status' => 'publish',
'posts_per_page' => 4,
'order' => 'ASC',
'offset' => $offset,
);

$post = new WP_Query($args);
while ($post->have_posts()) { $post->the_post();
<div class="project">the_title();</div>
}

wp_reset_postdata();

die(); // use die instead of exit
}

add_action('wp_ajax_nopriv_more_post_ajax', 'more_post_ajax');
add_action('wp_ajax_more_post_ajax', 'more_post_ajax');

I have not tested this, but this should get you closer to a working set.

Load more posts in the same category - WordPress + Ajax + Timber

To be honest, it's difficult to understand you, but it seems to me that your problem is that you are pointing all the time to a global post

function get_news() {
global $post;

You need to explicitly request the category what does this mean, I will explain

You need to transfer id categories to the server, and not use global $post.
The algorithm is as follows:

1) return the category id to the button on the client

<button data-cid="{category_id}">Load more posts</button>

or somewhere in the parent element of the category

<div class="category" data-cid="<?php print $category_id; ?>">
<!-- 10 posts -->
<article class="post">...</article>
....
<button>Load more posts</button>
</div>

2) After clicking on the button, get this СID (category id) and send it to the server

function load_more_news() {
var page = 1;

$(document).on('click', '#load-more-news', function(e) {
let $el = $(this); // of e.currentTarget;
e.preventDefault();
page++;

$.ajax({
type: 'POST',
url: '/wp-admin/admin-ajax.php',
dataType: 'html',
data: {
'action': 'get_news',
'get_page': page,
'cid': $el.data('cid') // CID or $el.parents('[data-cid]').data('cid');
},
success: function(data) {
if ($('<div></div>').html(data).find('.archive__item.ended').size() > 0) $('#load-more-news').parents('.cta').remove();
else $('#load-more-news').parents('.cta').show();
$('#archive__list').append(data);
},
error: function(data) {
console.log(data);
}
});
});
}

3) use this on server instead of global post

'category__in' => array($_POST['cid'])

Addition:

What means: when I click on the button "Load more posts". No post are display. ?

  1. What is returned from the server?
  2. Check what you get with ::get_posts()?
  3. Why don't you just use get_posts of native wordpress api function ?

Check and debug all data that comes to the server and returns

Organize your code:
1.) send ajax url to the client

wp_register_script('your-script', PLUG_URL.'your-script.js', array('jquery'), filemtime(  PLUG_DIR.'your-script.js' ), true);

wp_localize_script('your-script', 'glb',
array(
'ajax_url' => admin_url('admin-ajax.php')
)
);

and use it and use this instead of hardcore with $.post function of jquery (recommended)

let payload = {
page: 2
}
$.post(glb.ajax_url, {action: 'get_news', data: payload, function(e) {
....
});

2.) Check what comes to the server

function get_news() {
wp_send_json($_POST['data']);
}
$.post(glb.ajax_url, {action: 'get_news', data: payload, function(e) {
console.log(e); // {page: 2}
});

function get_news() {
if(!isset($_POST['data'])) {
wp_send_json_error();
}
$data = $_POST['data'];

$posts = get_posts( array(
'numberposts' => 10,
'post_status' => 'publish',
'category__in' => [$category],
'orderby' => 'date',
'order' => 'DESC',
'post_type' => 'post',
'paged' => $data['page']
));
wp_send_json($posts);
}
$.post(glb.ajax_url, {action: 'get_news', data: payload, function(e) {
console.log(e); // ???
});

Make checks, return data and look for where you have a "hole"

Load More Posts Ajax Button in Wordpress - fix

instead

 '&ppp' + ppp 

do

 '&ppp=' + ppp 


Related Topics



Leave a reply



Submit