Reputation: 179
I'm trying to create a load more button that loads more custom post types on click, however, I keep receiving a 400 (Bad Request) error. Here is the code i'm using.
// Header.php
<!doctype html>
<html <?php language_attributes(); class="no-js">
<head>
<!-- meta tags & links --->
<script type="text/javascript">
ajaxurl = <?php echo admin_url('admin-ajax.php'); ?>;
// HTML:
<div class="project">
<?php
$posts_array = array(
'post_type' => 'project',
'status' => 'publish',
'order' => 'ASC',
'posts_per_page' => -1,
'paged' => $paged
);
$posts = get_posts($posts_array);
$count = 0;
?>
<?php foreach ($posts as $post) : $count++; ?>
<div class="project">
<php echo the_title(); ?>
</div>
<?php endforeach; wp_reset_query(); ?>
</div>
<button id="more_posts">Load More</button>
// JavaScript:
$("#more_posts").on("click", function() {
// When btn is pressed.
$.ajax({
url: ajaxurl,
action: "more_post_ajax",
offset: page * ppp + 1,
ppp: ppp
}).success(function(posts) {
page++;
$(".projects").append(posts);
});
});
// Functions.php
function more_post_ajax(){
$offset = $_POST["offset"];
$ppp = $_POST["ppp"];
header("Content-Type: text/html");
$args = array(
'post_type' => 'project',
'status' => 'publish',
'posts_per_page' => $ppp,
'order' => 'ASC',
'offset' => $offset,
);
$loop = new WP_Query($args);
while ($loop->have_posts()) { $loop->the_post();
the_title();
}
exit;
}
add_action('wp_ajax_nopriv_more_post_ajax', 'more_post_ajax'); add_action('wp_ajax_more_post_ajax', 'more_post_ajax');
Upvotes: 2
Views: 11300
Reputation: 21
Just in case anyone is looking at this in the future and aren't sure on why they can't make it work theres a couple of things that need changing in the above code for starters in the js you need to define the variable page before the on click function...
var page = 1;
$("#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);
}
});
});
This code appends the data to the admin-ajax url which means you have to use $_GET not $_POST to retrieve the offset variable in your php function:
$offset = $_GET["offset"];
Upvotes: 1
Reputation: 1072
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.
Upvotes: 3