Add Infinite Scroll to Ajax Loaded Category Query

Update … Here’s the Final Code That Worked for Me

This may not be perfect, but it seems to be working well for me with no errors. Feel free to add any suggestions for improvement if you have any.

JS Code

jQuery(document).ready(function($) {

    var count = 2;

    jQuery("#la-chooser").change(function() {
        loadArticlebyCat(this.value);
    });

    function loadArticlebyCat(cat){

        data = {
            action: 'infinite_scroll', 
            val: cat,
            afp_nonce: afp_vars.afp_nonce,
        };

        jQuery.ajax({
            url: afp_vars.afp_ajax_url,
            type:'post',
            data: data,
            success: function( data, textStatus, XMLHttpRequest ) {
                jQuery("#tb-ajax-content").html( data );
                jQuery('#infinitBtn span').html('Load More Entries');
                console.log( textStatus );
                console.log( XMLHttpRequest );
                count = 2;
            },
            error: function( MLHttpRequest, textStatus, errorThrown ) {
                console.log( MLHttpRequest );
                console.log( textStatus );
                console.log( errorThrown );
                jQuery("#tb-ajax-content").html( 'No posts found' );
            }
        });

        return false;
    }

    jQuery('#infinitBtn').click(function(){
        loadArticle(count);
        count++;
        return false;
    });

    function loadArticle(pageNumber) {

        var cat = jQuery("#la-chooser").val();

        jQuery.ajax({
            url: afp_vars.afp_ajax_url,
            type:'POST',
            data: "action=infinite_scroll&page_no="+ pageNumber + "&loop_file=loop&val="+ cat +"&afp_nonce="+afp_vars.afp_nonce,
            success: function(html) {
                if(html=="") {
                    jQuery('#infinitBtn span').html('All Entries Loaded');
                } else {
                    jQuery('#infinitBtn span').html('Load More Entries');
                }
                jQuery("#tb-ajax-content").append(html);
            }
        });

        return false;
    }

});

WordPress Functions

Please note I’m using this in a child theme, so you would likely want to use get template directory uri instead of get_stylesheet_directory_uri if you’re not using a child theme.

function ajax_filter_posts_scripts() {

    // Register and enqueue script
    wp_register_script('afp_script', get_stylesheet_directory_uri() . '/js/ajax-filter-posts.js', false, null, false);
    wp_enqueue_script('afp_script');

    // localize script
    wp_localize_script( 'afp_script', 'afp_vars', array(
        'afp_nonce' => wp_create_nonce( 'afp_nonce' ), 
        'afp_ajax_url' => admin_url( 'admin-ajax.php' ),
    ));

}

add_action('wp_enqueue_scripts', 'ajax_filter_posts_scripts', 100);

function wp_infinitepaginate() {

    // Verify nonce
    $nonce = $_POST['afp_nonce'];   
    if ( !isset( $nonce ) || !wp_verify_nonce( $nonce, 'afp_nonce' ) )
        die ( 'Permission denied');

    $paged = $_POST['page_no'];
    $cat = $_POST['val'];
    $args = array(
        'category_name' => $cat,
        'post_status' => 'publish',
        'posts_per_page' => '6',
        'paged' => $paged,
    );

    query_posts($args);
    get_template_part('custom-loop');
    wp_reset_query();

    exit;
}

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

Main Loop Code With Drop-Down Category Selector

<div class="latest-article-chooser clearfix">
    <h1>Latest Blog Posts</h1>
    <p>
        <span>Filter Posts by Category:</span> <select id="la-chooser">
            <option value="">All Categories</option>
                <?php
                    $categories =  get_categories();
                    foreach ($categories as $category) {
                        $option = '<option value="'.$category->category_nicename.'">';
                        $option .= $category->cat_name;
                        $option .= ' ('.$category->count.')';
                        $option .= '</option>'."\n";
                        echo $option;
                    }
                ?>
        </select>
    </p>
</div>

<div id="tb-ajax-content">

<?php
    if (is_front_page()) { 
        $paged = (get_query_var('page')) ? get_query_var('page') : 1;
    } else {
        $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
    }
    $count = 1;
    query_posts(array(
        'post_status' => 'publish',
        'posts_per_page' => '6',
        'paged' => $paged,
    ));

    get_template_part('custom-loop');
?>

</div>

<div class="post-clear"></div>

<a class="button sc blue" href="#" id="infinitBtn"><span>Load More Entries</span></a>

Custom Loop File (custom-loop.php)

There are some theme-specific functions included here so you’d want to replace them with your own functions (or native WordPress functions).

<?php 
    $count = 1;
    if ( have_posts() ) : while ( have_posts() ) : the_post(); 
?>

    <article id="post-<?php the_ID(); ?>" <?php post_class(); ?> itemscope="itemscope" itemtype="http://schema.org/BlogPosting" itemprop="blogPost">

        <div class="entry-wrap">

            <div class="entry-media">
                <?php 
                    if ( tb_option('medium_thumb') ) { 
                        themebeagle_medium_thumbnail(); 
                    } else {
                        themebeagle_large_thumbnail(); 
                    }
                ?>
            </div>

            <div class="entry-container">

                <header class="entry-header">
                    <?php 
                        themebeagle_entry_title();
                        themebeagle_entry_meta(); 
                    ?>
                </header><!-- .entry-header -->

                <div class="entry-content" itemprop="text">
                    <?php themebeagle_excerpt(); ?>
                </div><!-- .entry-content -->

            </div> <!-- .entry-container -->

            <footer class="entry-footer">
                <?php themebeagle_entry_meta_bottom(); ?>
            </footer><!-- .entry-footer -->

        </div> <!-- .entry-wrap -->

    </article> <!-- article.post -->

<?php 
    $count = $count + 1; 
    endwhile; 
    endif; 
    wp_reset_query();
?>