AJAX Load More on Custom Post Grid - javascript

I cant get this to work. I am trying to create a custom post type grid with ajax load more button to show 6 mosts per page in the grid. I can get the posts to show but the Load More button just scrolls to the top of the page like a normal anchor link.
My theme code:
<div class="tabgrid">
<?php
$postsPerPage = 6;
$args = array(
'post_type' => 'dslc_projects',
'posts_per_page' => $postsPerPage,
'offset' => $offset
);
$loop = new WP_Query($args);
while ($loop->have_posts()) : $loop->the_post();
?><div class="project-grid-item">
<a href="<?php the_permalink() ?>">
<h3><?php the_title() ?></h3>
<p>View project...</p> </a>
</div><?php
endwhile; ?>
<?php echo '<div id="more_posts">Load More</div>';
wp_reset_postdata();
?>
</div>
</div>
My PHP:
function more_post_ajax(){
$offset = $_POST["offset"];
$ppp = $_POST["ppp"];
header("Content-Type: text/html");
$args = array(
'post_type' => 'post',
'posts_per_page' => $ppp,
'offset' => $offset
);
$loop = new WP_Query($args);
while ($loop->have_posts()) { $loop->the_post();
the_content();
}
exit;
}
add_action('wp_ajax_nopriv_more_post_ajax', 'more_post_ajax');
add_action('wp_ajax_more_post_ajax', 'more_post_ajax');
My JS:
var ajaxUrl = "<?php echo admin_url('admin-ajax.php')?>";
var page = 1; // What page we are on.
var ppp = 6; // Post per page
$("#more_posts").on("click",function(){ // When btn is pressed.
$("#more_posts").attr("disabled",true); // Disable the button, temp.
$.post(ajaxUrl, {
action:"more_post_ajax",
offset: (page * ppp) + 1,
ppp: ppp
}).success(function(posts){
page++;
$(".tabgrid").append(posts); // CHANGE THIS!
$("#more_posts").attr("disabled",false);
});
});
can anyone see what could be wrong here?

Your anchor is just a normal anchor and href="#" means scroll to top. Your JS code is trying to add a handler to and element with the id "#more_posts" but your anchor doesn't have an id.
Try replacing your anchor with <div id="more_posts">Load More</div>

Related

AJAX Interfering with if statement in while loop?

I am trying to load my sidebars in my while loop by using if statements that call them after a certain number of posts. It's important to note that I am using AJAX code (provided below) to load in posts on scroll and I believe it may be causing the issue.
Though they are sidebars, they are not physically a sidebar but rather content loaded between posts.
I've tried for a week to locate the problem but I cannot seem to get the sidebars to load with AJAX as a if statement in the while loop.
Important to note: The sidebar will load after the number of posts if it's not loaded through AJAX. So if it's in the initial load, the sidebars load. But when you continue to scroll to say the third or fourth bar it will not load and the AJAX will only load the (parts/content).
I need to either be able to resolve the if statement so it works within the while loop that loads through AJAX or I'm open to an alternate solution as long as it doesn't remove the AJAX.
A lot of work has been put into making this loop work and help is greatly appreciated!
front-page.php
<?php
$current_page = max( 1, get_query_var( 'paged' ) );
$the_query = new WP_Query( array(
'cat' => '-21',
'post_type' => 'post',
'posts_per_page' => 5,
'paged' => $current_page,
'tax_query' => array(
array(
'taxonomy' => 'topics',
'operator' => 'NOT EXISTS',
'field' => 'term_id',
'terms' => $term_id
)
)
) );
wp_localize_script( 'my_loadmore', 'misha_loadmore_params', array(
'ajaxurl' => admin_url( 'admin-ajax.php', 'relative' ),
'posts' => json_encode( $the_query->query_vars ),
'current_page' => $current_page,
'max_page' => $the_query->max_num_pages
) );
?>
<div id="main" class="container-fluid">
<?php if ($the_query->have_posts()) : ?>
<?php $count = 0; ?>
<?php while ($the_query->have_posts()) : $the_query->the_post(); get_template_part( 'parts/content', get_post_format() ); ?> <!-- This parts/content loads -->
<?php $count++; ?>
<!-- the dynamic_sidebar does not load -->
<?php if ($count == 2 && is_active_sidebar('sidebar1') ) : ?>
<div class="side-container first-side">
<?php dynamic_sidebar('sidebar1'); ?>
</div>
<?php endif; ?>
<?php if ($count == 10 && is_active_sidebar('sidebar2') ) : ?>
<div class="side-container first-side">
<?php dynamic_sidebar('sidebar2'); ?>
</div>
<?php endif; ?>
<?php if ($count == 20 && is_active_sidebar('sidebar3') ) : ?>
<div class="side-container third-side">
<?php dynamic_sidebar('sidebar3'); ?>
</div>
<?php endif; ?>
<?php endwhile; ?>
<?php endif; ?>
<?php wp_reset_postdata(); ?>
<?php get_footer(); ?>
</div><!-- END CONTAINER -->
parts/content -- this loads as expected including code if it's helpful
<div class="row post"> <!-- Post is mentioned in the below JS to load -->
<div class="col-sm-5">
<h2>Text</h2>
</div>
<div class="col-sm-7">
<h3>text</h3>
</div>
</div><!-- END ROW-->
sidebar code - works when initially loaded but doesn't when AJAX calls on this code such as the last two sidebars in front-page.php
<?php
$term = get_term_by( 'slug', get_query_var( 'term' ), get_query_var( 'taxonomy' ) ); ?>
<?php while( $flexible_posts->have_posts() ) : $flexible_posts->the_post(); global $post; ?>
<div class="sidebar-area">
//sidebar code here
}
endwhile;
?>
myloadmore.js - AJAX Call
jQuery(function($){
var canBeLoaded = true,
bottomOffset = 2000;
$(window).scroll(function(){
if ( misha_loadmore_params.current_page >= misha_loadmore_params.max_page ) {
return;
}
var data = {
'action': 'loadmore',
'query': misha_loadmore_params.posts,
'page' : misha_loadmore_params.current_page
};
if( $(document).scrollTop() > ( $(document).height() - bottomOffset ) && canBeLoaded == true ){
$.ajax({
url : misha_loadmore_params.ajaxurl,
data: data,
type: 'POST',
beforeSend: function( xhr ){
// AJAX call is in process, we shouldn't run it again until complete
canBeLoaded = false;
},
success:function(data){
if( data ) {
$('#main').find('div.post:last-of-type').after( data ); // where to insert posts
canBeLoaded = true; // the ajax is completed, now we can run it again
misha_loadmore_params.current_page++;
bottomOffset = ( $( '#main > div.post:last' ).offset() || {} ).top
}
}
});
}
});
});
functions.php - Added for further context
function misha_my_load_more_scripts() {
wp_register_script( 'my_loadmore', get_stylesheet_directory_uri() . '/js/myloadmore.js',
array( 'jquery' ), '', true );
wp_enqueue_script( 'my_loadmore' );
}
add_action( 'wp_enqueue_scripts', 'misha_my_load_more_scripts' );
function misha_loadmore_ajax_handler() {
$args = json_decode( wp_unslash( $_POST['query'] ), true );
$args['paged'] = $_POST['page'] + 1; // load the next page
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
get_template_part( 'parts/content', get_post_format() );
endwhile;
endif;
wp_die();
}
add_action( 'wp_ajax_loadmore', 'misha_loadmore_ajax_handler' ); // Authenticated users
add_action( 'wp_ajax_nopriv_loadmore', 'misha_loadmore_ajax_handler' ); // Non-authenticated users
The trick here was to add the if statements inside of the AJAX handlers as well. Perhaps someone with AJAX experience can add to this one day to explain why it works, but all I know is that it does. All the code from my question is the same below is the difference from the functions.php ajax handler function.
function misha_loadmore_ajax_handler() {
$args = json_decode( wp_unslash( $_POST['query'] ), true );
$args['paged'] = $_POST['page'] + 1; // load the next page
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
get_template_part( 'parts/content', get_post_format() );
<?php if ($count == 2 && is_active_sidebar('sidebar1') ) : ?>
<div class="side-container first-side">
<?php dynamic_sidebar('sidebar1'); ?>
</div>
<?php endif; ?>
<?php if ($count == 10 && is_active_sidebar('sidebar2') ) : ?>
<div class="side-container first-side">
<?php dynamic_sidebar('sidebar2'); ?>
</div>
<?php endif; ?>
<?php if ($count == 20 && is_active_sidebar('sidebar3') ) : ?>
<div class="side-container third-side">
<?php dynamic_sidebar('sidebar3'); ?>
</div>
<?php endif;
endwhile;
endif;
wp_die();
}

when button clicked send post-id inside variable

I have a query that displays events and there is a buy now button.
How do I make that when I press this button I send in a php session the post-id of the post that this button is inside of.
With what I have done so far the problem is that when I press the button I get the variable of the post-id of the last post in the loop instead of the post-id of the button I am pressing.
This is my code:
function calendario_posts( ) {
ob_start();
// WP_Query arguments
$paged = (get_query_var(‘paged’)) ? get_query_var(‘paged’) : 1;
$args = array (
'category_name' => 'calendario',
'posts_per_page' => '6',
'paged' => $paged
);
// The Query
$featured_post_query = new WP_Query( $args );
// The Loop
if ( $featured_post_query->have_posts() ) {
while ( $featured_post_query->have_posts() ) {
$featured_post_query->the_post();
?>
<div class="teatro-all">
<?php the_post_thumbnail(gallery); ?>
<h2 class="teatro-group teatro-title"><?php the_title(); ?></h2>
<h5 class="teatro-group teatro-fecha"> <?php the_field('fecha'); ?></h5>
<h5 class="teatro-group teatro-precio" >Precio desde: <?php the_field('precio'); ?></h5>
<?php $eventTitle = get_the_title(); ?>
<center><a class="teatro-buy teatro-button" href="http://localhost/newiga/tickets/">COMPRAR</a><br>
<center><a class="teatro-read-more teatro-button" href="<?php the_permalink(); ?>">LEER MAS</a></center>
<script> var buybutton = document.getElementById("teatro-buy");
buybutton.onclick = function(){
<?php $_SESSION['eventId'] = get_the_ID();?>
}
</script>
<?php
}
} else {
// no posts found
}
// Restore original Post Data
wp_reset_postdata();
}
function calendario_shortcode() {
$output = calendario_posts();
$output = ob_get_clean();
return $output;
}
add_shortcode( 'calendario', 'calendario_shortcode' );

Need to fire an alert after "page load" on same page

This is a WordPress site and I have a template that renders all posts in a list at this URL http://www.example.com/articles. When the user clicks on a post title, it loads the content of the post using the same template but with a different URL http://www.example.com/articles/?article_id=298. What I cannot figure out is how to show an alert after the page loads the post content. I've tried setTimeout, $(document).ready, $(window).load, window.onload=funtion(), and now $(document).on("pagecontainerload",function().
JQuery/JavaScript
$('a.open-alert').click(function() {
$(document).on("pagecontainerload",function(){
window.alert('hey');
});
});
HTML
<?php
$tearsheet = get_query_var('article_id');
if($tearsheet != '') {
echo 'there is something here';
} else {
$args = array(
'post_type' => 'post',
'posts_per_page' => -1,
);
$query = new WP_Query( $args );
if($query->have_posts()) :
while($query->have_posts()) :
$query->the_post();
?>
<div>
<?php $id = get_the_ID(); ?>
<?php $title = get_the_title(); ?>
<a class="open-alert" href="<?php bloginfo('url'); echo '/find-articles/?article_id='.$id; ?>"><?php echo $title; ?></a>
</div>
<?php
endwhile;
endif;
}
?>
The click handler will never be executed, since the page unloads and a new page is loaded - the one in the link <a class="open-alert" href="<?php bloginfo.... You may have a return false in the onclick handler, but that would mean, the link will not be executed.
In order to do this dynamically, consider reloading only the container within that page, containing the post text by some Ajax functionality.

Load More Posts Ajax Button in WordPress

I've had a look through the old questions and tried many of the different methods that there seems to be to do this. The closest I've got to working is this one here: How to implement pagination on a custom WP_Query Ajax
I've tried everything and it just doesn't work. Absolutely nothing changes on the page. If you inspect the Load More Button and click it, the jQuery is making the Load More Button action as it changes from <a id="more_posts">Load More</a> to <a id="more_posts" disables="disabled">Load More</a> which even that doesn6't seem right to me anyway. It's not adding the posts, I think I'm missing something simple but for the life of me I can't work it out.
The code in my template file is:
<div id="ajax-posts" class="row">
<?php
$postsPerPage = 3;
$args = [
'post_type' => 'post',
'posts_per_page' => $postsPerPage,
'cat' => 1
];
$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;
echo '<a id="more_posts">Load More</a>';
wp_reset_postdata();
?>
</div>
The code in my functions file is:
function more_post_ajax(){
$offset = $_POST["offset"];
$ppp = $_POST["ppp"];
header("Content-Type: text/html");
$args = [
'suppress_filters' => true,
'post_type' => 'post',
'posts_per_page' => $ppp,
'cat' => 1,
'offset' => $offset,
];
$loop = new WP_Query($args);
while ($loop->have_posts()) { $loop->the_post();
the_content();
}
exit;
}
add_action('wp_ajax_nopriv_more_post_ajax', 'more_post_ajax');
add_action('wp_ajax_more_post_ajax', 'more_post_ajax');
And my jQuery in the footer is:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script type="text/javascript">
jQuery(document).ready( function($) {
var ajaxUrl = "<?php echo admin_url('admin-ajax.php')?>";
// What page we are on.
var page = 5;
// Post per page
var ppp = 3;
$("#more_posts").on("click", function() {
// When btn is pressed.
$("#more_posts").attr("disabled",true);
// Disable the button, temp.
$.post(ajaxUrl, {
action: "more_post_ajax",
offset: (page * ppp) + 1,
ppp: ppp
})
.success(function(posts) {
page++;
$("#ajax-posts").append(posts);
// CHANGE THIS!
$("#more_posts").attr("disabled", false);
});
});
});
</script>
Can anybody see something I'm missing or able to help?
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
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.
If I'm not using any category then how can I use this code? Actually, I want to use this code for custom post type.

Adding a "more" Button

I'm trying to add a "load more" button and limit the results below, so that there aren't 1000 things loading all at once in the portfolio page, here: http://typesetdesign.com/portfolio/
My knowledge of PHP isn't very good, so I'm not sure what I'm supposed to do. I know I could limit the projects here:
<?php query_posts( 'post_type=project&posts_per_page=200' );
But how would I then load more if I limited that result?
Here is the page coding for that entire page:
<div id="projects" class="clearfix">
<?php $page_skills = get_post_meta($post->ID, "_ttrust_page_skills", true); ?>
<?php if ($page_skills) : // if there are a limited number of skills set ?>
<?php $skill_slugs = ""; $skills = explode(",", $page_skills); ?>
<?php if (sizeof($skills) > 1) : // if there is more than one skill, show the filter nav?>
<ul id="filterNav" class="clearfix">
<li class="allBtn"><?php _e('All', 'themetrust'); ?></li>
<?php
$j=1;
foreach ($skills as $skill) {
$skill = get_term_by( 'slug', trim(htmlentities($skill)), 'skill');
if($skill) {
$skill_slug = $skill->slug;
$skill_slugs .= $skill_slug . ",";
$a = '<li><a href="#" data-filter=".'.$skill_slug.'">';
$a .= $skill->name;
$a .= '</a></li>';
echo $a;
echo "\n";
$j++;
}
}?>
</ul>
<?php $skill_slugs = substr($skill_slugs, 0, strlen($skill_slugs)-1); ?>
<?php else: ?>
<?php $skill = $skills[0]; ?>
<?php $s = get_term_by( 'name', trim(htmlentities($skill)), 'skill'); ?>
<?php if($s) { $skill_slugs = $s->slug; } ?>
<?php endif;
$temp_post = $post;
$args = array(
'ignore_sticky_posts' => 1,
'posts_per_page' => 200,
'post_type' => 'project',
'skill' => $skill_slugs
);
$projects = new WP_Query( $args );
else : // if not, use all the skills ?>
<ul id="filterNav" class="clearfix">
<li class="allBtn"><?php _e('All', 'themetrust'); ?></li>
<?php $j=1;
$skills = get_terms('skill');
foreach ($skills as $skill) {
$a = '<li><a href="#" data-filter=".'.$skill->slug.'">';
$a .= $skill->name;
$a .= '</a></li>';
echo $a;
echo "\n";
$j++;
}?>
</ul>
<?php
$temp_post = $post;
$args = array(
'ignore_sticky_posts' => 1,
'posts_per_page' => 200,
'post_type' => 'project'
);
$projects = new WP_Query( $args );
endif; ?>
<div class="thumbs masonry">
<?php while ($projects->have_posts()) : $projects->the_post(); ?>
<?php
global $p;
$p = "";
$skills = get_the_terms( $post->ID, 'skill');
if ($skills) {
foreach ($skills as $skill) {
$p .= $skill->slug . " ";
}
}
?>
<?php get_template_part( 'part-project-thumb'); ?>
<?php endwhile; ?>
<?php $post = $temp_post; ?>
</div>
Thanks so much, any input is a help!
Edit
Using Tables with pagination bootstrap style http://datatables.net/examples/basic_init/multiple_tables.html
Massive data base with pagination take a look here: https://stackoverflow.com/a/3707457/2293454
I didn't see your site, now I have, what you might need is something like this:
https://stackoverflow.com/a/21408418/2293454
as you can see that example has a limiter iMyLoadLimit = 5, so, wen the user scroll down the page, it will load more based on the total number of fetched data, if you load 100 articles or 1000, they will be divided by the limiter in the java, the result will be that every time the user scroll down it will display the next 5 or whatever number you want to display...
I hope that helps...
You need pagination (server side) and might want infinite scrolling (client side)
You may want to look at:
Simple PHP Pagination script
http://jscroll.com/
How to paginate query results for Infinite Scroll?

Categories

Resources