Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I wanna start by apologize for this post being so long, but I feel it may help others since I am having this problem and figured I might as well be as detailed as possible.

I am having a problem with this is the loop.php file loading the same post multiple times and I have tried the prevent duplicate post method and nothing working. As you can see below I am loading the function to post into the ajax function and I get a success call but at this point I am not sure if the loop file is the problem. When the site 1st loads it loads the 1st set of post and then when it gets the 2nd set of post its fine but everything after that is all the same post, its like the loop file loads but the query is stuck or something.

Any suggestions? Any help is greatly appreciated.

loop.php file

<div class="post-left">
<?php query_posts(array('post__not_in' => $id_merge,'posts_per_page'=>'2'));
      $do_not_duplicate = $post->ID;

 if (have_posts()) : while (have_posts()) : the_post();
 if( $post->ID == $do_not_duplicate ) continue;
 $ids[] = get_the_ID(); ?>
<div class="images-grid-page-wrapper">
<?php the_title(); ?>
</div>
<?php endwhile; endif; // End the loop. Whew. ?>
</div>


<div class="post-mid">
<?php query_posts(array('post__not_in' => $id_merge,'posts_per_page'=>'3'));
      $do_not_duplicate = $post->ID;

 if (have_posts()) : while (have_posts()) : the_post();
 if( $post->ID == $do_not_duplicate ) continue;

 $ids[] = get_the_ID(); ?>
<div class="images-grid-page-wrapper">
<?php the_title(); ?>
</div>
<?php endwhile; endif; // End the loop. Whew. ?>
</div>

functions.php

add_action('wp_ajax_infinite_scroll', 'wp_infinitepaginate');           // for logged in user
add_action('wp_ajax_nopriv_infinite_scroll', 'wp_infinitepaginate');    // if user not logged in

function wp_infinitepaginate(){
    $loopFile        = $_POST['loop_file'];
    get_template_part( $loopFile );
    exit;
}

ajax

jQuery(document).ready(function($) {
    var count = 1;
    var total = <?php echo $wp_query->max_num_pages; ?>;
    $(window).scroll(function(){
            if  ($(window).scrollTop() == $(document).height() - $(window).height()){
               if (count > total){
                    return false;
               }else{
                    loadArticle(count);
               }
               count++;
            }
    }); 

    function loadArticle(){    
            $('a#inifiniteLoader').show('fast');
            $.ajax({
                url: "<?php bloginfo('wpurl') ?>/wp-admin/admin-ajax.php",
                type:'POST',
                data: "action=infinite_scroll&loop_file=loop", 
                success: function(html){
                    $('a#inifiniteLoader').hide('1000');
                    $("#content").append(html);    // This will be the div where our content will be loaded
                }
            });
        return false;
    }
});
share|improve this question
    
see this answer for a full working code example of loading posts via ajax –  Milo Dec 30 '12 at 4:23
    
The problem is not loading a post into ajax, that works fine, the problem is the post are being recalled several times, therefore making duplicate post. –  Jeremy Love Dec 30 '12 at 8:00
    
The important bit to note is where the offset is passed to the query, which you are not doing. Also note the use of localize script, eliminating the need to put php in your js. –  Milo Dec 30 '12 at 13:25
add comment

1 Answer

You have got a few things to consider here.

Let's start the way the Browser does.

You build up the HTML, so far so good, containing the Structure and everything for your site. No articles are shown.

The next step your Browser has to do is make the AJAX call.

Here are the first things to be considered. In your document.ready function you do not send the offset of posts to your AJAX-php function. As far as I can tell from your code, you always want to show 5 posts when the function is called.

Therefore, consider this:

At first, the count is 0. With every successful Reload the count increases by 5. You should place this part into the success part of your AJAX call. Also, your AJAX-php function has to know the offset of the posts to be delivered.

Another thing to consider is, that you may have another query on your Site than the one in your AJAX-function. So be sure the var total is the correct number, but I won't go into this any further by now and leave it like you had it. You get the idea.

Your Javascript should be like this:

jQuery(document).ready(function($) {
    var count = 0;
    var total = <?php echo $wp_query->max_num_pages; ?>;
    $(window).scroll(function(){
            if ($(window).scrollTop() == $(document).height() - $(window).height()){
               if (count > total){
                    return false;
               }else{
                    loadArticle(count);
               }
            }
    }); 

    function loadArticle(count){    
            $('a#inifiniteLoader').show('fast');
            // I prefer doing the ajaxdata with an array
            var ajaxdata = { 
               'action' : 'infinite_scroll'
               'offset' : count
            }
            $.ajax({
                url: "<?php bloginfo('wpurl') ?>/wp-admin/admin-ajax.php",
                type:'POST',
                data: ajaxdata, 
                success: function(html){
                    $('a#inifiniteLoader').hide('1000');
                    $("#content").append(html);    // This will be the div where our content will be loaded
                        count = count + 5; // Increase the number of posts that are already shown.
                }
            });
        return false;
    }
});

As you can see, I created an Array for the ajaxdata - it is easier to take a look at it this way. I also removed the loopfile=loop, as you can see later, because I would do the response in another way.

So far so good - now we should consider building your AJAX response a little different. You registered it the right way, but i would handle it not with the get_template_part, do another function, passing the variables.

The registering of the AJAX function would be like this:

add_action('wp_ajax_infinite_scroll', 'wp_infinitepaginate');           // for logged in user
add_action('wp_ajax_nopriv_infinite_scroll', 'wp_infinitepaginate');    // if user not logged in

function wp_infinitepaginate(){
    load_ajax_results($_POST['count']);
    exit;
}

The last step is the actual function to put together your output. You can place this one anywhere, your functions.php or another file. I prefer creating a file ajax-functions.php which is included in my functions.php, containing all the above functions (except the Javascript of course)

<?php

    function load_ajax_results( $offset ) {
    // I use the $_POST['count'] as $offset here
?>

    <div class="post-left">
    <?php
        $args = array(
            'numberposts' => '2', // 2 Posts to show here
            'offset'      => $offset // the number of Posts to skip, given by the AJAX call
        );
        query_posts( $args ); // nothing else should be needed

        if (have_posts()) : while (have_posts()) : the_post();
        ?>
            <div class="images-grid-page-wrapper">
                <?php the_title(); ?>
            </div>
        <?php endwhile; endif; // End the loop. Whew. ?>
        <?php wp_reset_query(); // reset it ?>
    </div>


    <div class="post-mid">
    <?php 
        $offset = $offset + 2; // because we had 2 Posts before
        $args = array(
            'numberposts' => '3', // 3 Posts to show here
            'offset'      => $offset // the number of Posts to skip, given by the AJAX call
        );
        query_posts( $args ); // nothing else should be needed

        if (have_posts()) : while (have_posts()) : the_post();
        ?>
            <div class="images-grid-page-wrapper">
                <?php the_title(); ?>
            </div>
        <?php endwhile; endif; // End the loop. Whew. ?>
    </div>

<?php

    }

?>

As I use the offset here, I do not have to check if any of the Posts has already been shown before.

The main Problem you had is that you had an error thinking about the AJAX function. This function does not know anything about what is going on in the Browser, so you have to tell it which Posts to show. It is a new instance everytime it is called - and so the Values, which posts have been delivered the last time, are not stored.

Did not test this on my installation, but I hop you get the idea behind it. If there are any errors, sorry, and if there are any questions, please comment :)

share|improve this answer
    
Thanks for replying, I went over your code and I like your suggestion about loading the post through a function instead of a loop, I think that helps a little more and is a little bit cleaner. However after trying your code it still duplicates the post, you wouldnt happen to have any more suggestions would you? –  Jeremy Love Dec 30 '12 at 1:57
    
Try running the function without AJAX first, checking if everything works fine. Just run the function in a template. If everything works out fine (mainly the offset), check if the correct values are submitted in your Ajax (just echo the offset somewhere). You'll probably recognize where the error is. Unfortunately, I can't tell by now what is wrong.. –  fischi Dec 30 '12 at 11:02
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.