1

I have a problem that is getting me bald atm. I have a ajax call that handles a loop that handles some querys and returns posts for me.

So far so good, but the first time the user sees the page we should load 10 posts, and then we want to click a button to request 5 more.

So far so good.

But when we request the 5 more posts we get the 5 first posts again.

My batchloop

<?php   
// Our include  
define('WP_USE_THEMES', false);  
require_once('../../../wp-load.php');  

// Our variables  
$posts = (isset($_GET['numPosts'])) ? $_GET['numPosts'] : 0;  
$page = (isset($_GET['pageNumber'])) ? $_GET['pageNumber'] : 0;  
$category = (isset($_GET['category_name'])) ? $_GET['category_name'] : 0;  

var_dump($posts);

$args = array(  
    'posts_per_page' => $posts,
    'category_name'  => $category, 
    'post_status'    => 'publish',
    'orderby'        => 'date',
    'order'          => 'DESC',
    'paged'          => $page 
);

query_posts($args);  

// $query = new WP_query($args);

// our loop  
if (have_posts()) {  

    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; query_posts($args);

       while (have_posts()){  
              the_post();  

              get_template_part( 'thumbs', get_post_format() );  
       }  
} 

// unset($page, $posts, $category);

// wp_reset_postdata();
wp_reset_query();
?> 

Does anybody sees what im doing wrong?

EDIT:

batch handler

 function _batchhandler() { 
        var getamount = localStorage.getItem('amount'); 

        console.log('amount of posts to retrive ' + JSON.parse(getamount));

        // Ajax call
        $.ajax({
            type: 'GET',
            data: {
                posts: getamount, 
                page: page,
                category: 'work'
            },
            dataType: 'html',
            url: 'http://dev.xxx.se/wp-content/themes/xxx/batch.php',
            beforeSend: function() {
                _setHeader;
                if( page != 1 ) {
                    console.log('Loading');
                    // Show the preloader
                    $('body').prepend('<div class="preloader"><span class="rotate"></span></div>');
                }
                // If we reach the end we hide the show more button
                if( page >= total ) {
                    $('.load').hide();
                }
            },
            success: function(data) {
                console.log(page);  
                var scroll = ($('.thumb').height() * posts);
                // If thumbs exist append them
                if( data.length ) { 
                    // Append the data
                    $('#batch').append(data);

                    // Remove the crappy width and height attrs from the image * Generated by WP *
                    $('img').removeAttr('height').removeAttr('width');

                    // Animate each new object in a nice way
                    (function _showitem() {
                        $('#batch .thumb:hidden:first').addClass('show', 80, _showitem);

                        // On the last request do load any more
                        loading = false;  
                    })();

                    // Remove the preloader
                    $('.preloader').fadeOut(200, function() {
                        $('.preloader').remove();   
                    });
                }
                // return false;
            },
            complete: function() {
                // Delete storage
                localStorage.clear();

                // Update the scroller to match the updated content length
                if (scroller)
                    setTimeout("scroller.refresh()", 300);

                // Initalize the load more button
                _clickhandler();
            },
            error: function() {
                console.log('No page found');
            }
        });
    }

and my load more button function

 $('.load').on('click', function(event) {
            event.preventDefault(); 
            // Delete storage
            localStorage.clear();

            if(!loading) {
                loading = true;
                // Increase our pagenumber per click
                page++;
                count++;
                // Remove preloader
                $('.preloader').remove();

                setTimeout(function() {
                    $('#batch').css({
                        '-webkit-transform' : 'translateY(-' + ($('#batch li').outerHeight() * count)  + 'px)'
                    });
                }, 30);

                // Clear storage and set a new
                localStorage.setItem('amount', JSON.stringify(amount.medium));
                var getamount = localStorage.getItem('amount');

                // Send the request to the handler                  
                _batchhandler(page);    
            }      

        });

Everything seems fine, the first 10 (1-10) posts loads as the should, but the first time "load more" is clicked we get the next 5 results but the results are posts that loaded the first time (5-10). If we click the "load more" again, we get the correct result

1
  • +1 for the phrase "I have a problem that is getting me bald atm" Commented Apr 10, 2013 at 12:08

1 Answer 1

1

Caveat, I can't really test this right now. However, there are several things that I think could be improved from your code.

First if we read the codex or some tips on using ajax we can setup an ajax callback function that isn't pointing to a file where we have to bootstrap the WordPress load functions.

I will make the assumption that all your script is in a JS file and being properly enqueued:

// embed the javascript file that makes the AJAX request
wp_enqueue_script( 'wpa-95258-ajax-request', plugin_dir_url( __FILE__ ) . 'js/ajax.js', array( 'jquery' ) );

// declare the URL to the file that handles the AJAX request (wp-admin/admin-ajax.php)
wp_localize_script( 'wpa-95258-ajax-request', 'wpa-95258-ajax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );

Using wp_localize_script we can pass some variables to a script object that will then be available in the script. We'll use this for the .ajax URL parameter. We also need an action parameter, because WordPress will look for

// this hook is fired if the current viewer is not logged in
do_action( 'wp_ajax_nopriv_' . $_REQUEST['action'] );

// if logged in:
do_action( 'wp_ajax_' . $_POST['action'] );

So we can use that later on to attach a callback function to any ajax action. First I've adapted your .ajax to have an action and use the WordPress ajax url:

function _batchhandler() { 
    var getamount = localStorage.getItem('amount'); 

    console.log('amount of posts to retrive ' + JSON.parse(getamount));

    // Ajax call
    $.ajax({
        type: 'GET',
        data: {
            posts: getamount, 
            page: page,
            category: 'work',
            action: 'batchhandler' // use this to add a callback
        },
        dataType: 'html',
        url: wpa-95258-ajax.ajaxurl, //from localize script
        beforeSend: function() {
            _setHeader;
            if( page != 1 ) {
                console.log('Loading');
                // Show the preloader
                $('body').prepend('<div class="preloader"><span class="rotate"></span></div>');
            }
            // If we reach the end we hide the show more button
            if( page >= total ) {
                $('.load').hide();
            }
        },
        success: function(data) {
            console.log(page);  
            var scroll = ($('.thumb').height() * posts);
            // If thumbs exist append them
            if( data.length ) { 
                // Append the data
                $('#batch').append(data);

                // Remove the crappy width and height attrs from the image * Generated by WP *
                $('img').removeAttr('height').removeAttr('width');

                // Animate each new object in a nice way
                (function _showitem() {
                    $('#batch .thumb:hidden:first').addClass('show', 80, _showitem);

                    // On the last request do load any more
                    loading = false;  
                })();

                // Remove the preloader
                $('.preloader').fadeOut(200, function() {
                    $('.preloader').remove();   
                });
            }
            // return false;
        },
        complete: function() {
            // Delete storage
            localStorage.clear();

            // Update the scroller to match the updated content length
            if (scroller)
                setTimeout("scroller.refresh()", 300);

            // Initalize the load more button
            _clickhandler();
        },
        error: function() {
            console.log('No page found');
        }
    });
}

Now that we have a hook to attach to we can build the callback function without the bootstrapped loader. I'd also recommend getting rid of query_posts(). That does wonky things to the query and it is generally recommended around here to use new WP_Query.

I've adjusted your batchloop.php to be a callback function instead:

function wp_ajax_batchhandler_callback(){

    // Our variables  
    $posts = (isset($_GET['numPosts'])) ? $_GET['numPosts'] : 0;  
    $page = (isset($_GET['pageNumber'])) ? $_GET['pageNumber'] : 0;  
    $category = (isset($_GET['category_name'])) ? $_GET['category_name'] : 0;  

    var_dump($posts);

    $args = array(  
        'posts_per_page' => $posts,
        'category_name'  => $category, 
        'post_status'    => 'publish',
        'orderby'        => 'date',
        'order'          => 'DESC',
        'paged'          => $page 
    );

    $ajax_query = new WP_query($args);

    // our loop  
    if ($ajax_query->have_posts()) {  

        while ($ajax_query->have_posts()){  
            $ajax_query->the_post();  
            get_template_part( 'thumbs', get_post_format() );  
        }  
    } 

    // unset($page, $posts, $category);

    wp_reset_postdata();

}
add_action( 'wp_ajax_nopriv_batchhandler', 'batchhandler_callback' ); //logged out users
add_action( 'wp_ajax_batchhandler', 'batchhandler_callback' ); //logged in users

Like I said, I didn't test this but it looks like you are using:

$page = (isset($_GET['pageNumber'])) ? $_GET['pageNumber'] : 0; 

To get the page number that you are using in the query. However, you aren't sending the pageNumber in the .ajax function so I doubt you'll get proper pagination. However, you should now be hooked up with the appropriate way to make ajax calls in WordPress, and I think pagination can be fixed by passing the pageNumber variable.

5
  • Hello, thx for the answer. Will try it out and my js files arent properly enqueued due to wp generates code that i dont need nor is it necessary for my use of wp.
    – Jonas
    Commented Apr 10, 2013 at 12:28
  • Nope, this didnt work unfortually. i dont enqueue the scripts as you stated due to wordpress generating code that I dont need nor think is necessary for my use of WP
    – Jonas
    Commented Apr 10, 2013 at 12:37
  • "wp generates code that i dont need nor is it necessary for my use of wp" Such as? Enqueueing is just the way you are supposed to load scripts. Though if you are printing them directly you can just use straight php to print the ajaxurl in place of my wp_localize_script(). And I said it probably wouldn't work, but it should get you pretty close. The part I couldn't figure out from reading what how you were passing the next page number via load more. Commented Apr 10, 2013 at 15:00
  • Hi, the code it self has no error, its WP that handles the pagination stuff a little bit different becuase i want to get another amount of posts on the second page, WP handles it as it should be the first page again even tho its not. So haft to figure out how to get pass that problem...The current JS and WP_QUERY hasnt any problems..
    – Jonas
    Commented Apr 10, 2013 at 17:58
  • "The current JS and WP_QUERY hasnt any problems" That doesn't mean you are using best practices. I agree the main problem I am having too is in figuring out how to send the pagination page number. You almost look like you are doing an "Infinite Scroll" reboot. Have you checked out the WordPress plugin for that? Commented Apr 10, 2013 at 22:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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