web-dev-qa-db-fra.com

WP_Query ajax loader détecte la fin des publications

J'ai construit le chargeur ajax comme suit.

Comment puis-je détecter quand il atteint la fin de tous les messages? Pour que je puisse faire disparaître le bouton "Plus" ou qu'il ne soit plus cliquable.

Dans le modèle de page:

WP_Query stuff...

if ($press_posts->max_num_pages > 1) :
    echo '<a class="link-button" id="load-more">More</a>';
endif;

functions.php

function more_post_ajax() {
    $offset = $_POST["offset"];
    $ppp = $_POST["ppp"];
    header("Content-Type: text/html");

    $args = array(
        'cat' => 1,
        'posts_per_page' => $ppp,
        'offset' => $offset
    );

    $loop = new WP_Query($args);
    while ($loop->have_posts()) { $loop->the_post();
        get_template_part('template-parts/content', 'ajax');
    }
    exit;
}
add_action('wp_ajax_nopriv_more_post_ajax', 'more_post_ajax');
add_action('wp_ajax_more_post_ajax', 'more_post_ajax');

et javascripts:

<script>
    var ajaxUrl = "<?php echo admin_url('admin-ajax.php')?>";
    var page = 1;
    var ppp = 6; // posts per page

    jQuery("#load-more").on("click", function() {
        jQuery("#load-more").addClass("disabled");
        jQuery.post(ajaxUrl, {
            action: "more_post_ajax",
            offset: (page * ppp) + 1,
            ppp: ppp
        }).success(function(posts) {
            page++;
            jQuery("#press-listing").append(posts); // append to container
            jQuery("#load-more").removeClass("disabled");
        });

    });
</script>
1
Stickers

Modèle de page:

<div class="entry-content">
    <?php 
        $args = array(
            'post_type' => 'post',
            'post_status' => 'publish',
            'posts_per_page' => '2',
            'paged' => 1,
        );
        $my_posts = new WP_Query($args);
        if ($my_posts->have_posts()) : 
    ?>
        <div class="my-posts">
            <?php while ($my_posts->have_posts()) : $my_posts->the_post(); ?>
                <h2><?php the_title(); ?></h2>
                <?php the_excerpt(); ?>
            <?php endwhile; ?>
        </div>
    <?php endif; ?>
    <div class="loadmore">Load More...</div>
</div>

Ajax jQuery (bouton Charger plus):

<script type="text/javascript">
var ajaxurl = "<?php echo admin_url('admin-ajax.php'); ?>";
var page = 2;
jQuery(function($) {
    $('body').on('click', '.loadmore', function() {
        var data = {
            'action': 'load_posts_by_ajax',
            'page': page,
            'security': '<?php echo wp_create_nonce("load_more_posts"); ?>'
        };

        max = <?php echo $my_posts->max_num_pages; ?>

        $.post(ajaxurl, data, function(response) {
            $('.my-posts').append(response);
            if (page < max) {
                // end of posts
            }
            page++;
        });
    });
});
</script>

Les fonctions:

function load_posts_by_ajax_callback() {
    check_ajax_referer('load_more_posts', 'security');
    $paged = $_POST['page'];
    $args = array(
        'post_type' => 'post',
        'post_status' => 'publish',
        'posts_per_page' => '2',
        'paged' => $paged,
   );
    $my_posts = new WP_Query($args);
    if ($my_posts->have_posts()) :
        ?>
        <?php while ($my_posts->have_posts()) : $my_posts->the_post(); ?>
            <h2><?php the_title(); ?></h2>
            <?php the_excerpt(); ?>
        <?php endwhile; ?>
        <?php
    endif;
    wp_die();
}
add_action('wp_ajax_load_posts_by_ajax', 'load_posts_by_ajax_callback');
add_action('wp_ajax_nopriv_load_posts_by_ajax', 'load_posts_by_ajax_callback');

Ajout - Ajax jQuery (Load on scroll):

$(window).scroll(function() {
    if ($(window).scrollTop() == $(document).height() - $(window).height()) {
        var data = {
            'action': 'load_posts_by_ajax',
            'page': page,
            'security': '<?php echo wp_create_nonce("load_more_posts"); ?>'
        };

        $.post(ajaxurl, data, function(response) {
            $('.my-posts').append(response);
            page++;
        });
    }
});

La source

0
Stickers

Je suis d'accord avec le commentateur @TomJNowell qu'il pourrait être intéressant de regarder dans l'API REST. Cependant, concernant votre question spécifique:

Voici une idée:

  • Vérifiez s'il reste des publications dans votre fonction more_post_ajax() et incluez-les dans votre réponse en plus des publications que vous renvoyez. Par exemple, vous pourriez avoir un drapeau more_posts boolean, ou peut-être un compte; Cependant, vous aimeriez le faire.
  • À la fin de js, développez l'implémentation de .success(function(posts) { ... }) pour ajouter une logique qui gère cette nouvelle information dans la réponse. S'il ne reste plus de messages, vous pouvez désactiver/masquer votre élément #load-more et éventuellement ajouter un message à l'utilisateur lui indiquant qu'il ne reste plus de messages.

Je ne sais pas exactement ce qu'il y a dans la partie modèle que vous appelez via get_template_part('template-parts/content', 'ajax') ou ce que cela fait, donc il est difficile d'être plus précis en ce qui concerne ce domaine.

Quoi qu'il en soit, votre instance de WP_Query stockée dans $loop a une propriété posts qui est un tableau de vos publications. Je pourrais supposer que vous souhaitez renvoyer la posts dans votre réponse.

La propriété WP_Queryfound_posts est un décompte de tous les posts correspondant à vos critères sans prise en compte de votre décalage (c'est-à-dire le nombre total de posts), à moins que cette propriété ne soit désactivée avec arg no_found_rows (N/A dans ce cas). Étant donné que vous connaissez vos publications par page et votre décalage, vous avez les informations à retransmettre dans votre réponse si plusieurs publications sont disponibles pour être chargées ou non. Une autre façon pourrait être la propriété max_num_pages.

Vous pouvez les combiner dans un tableau/objet et utiliser wp_send_json() ou wp_send_json_success() pour les envoyer, puis traiter la réponse en js. Vous aurez besoin de parseJSON() de jQuery pour analyser la réponse.

Si vous êtes vraiment marié à ce que votre modèle partiel produit en sortie et à la façon dont vous faites facilement jQuery("#press-listing").append(posts) du côté js pour l'afficher, vous pouvez capturer le résultat de get_template_part('template-parts/content', 'ajax'); en utilisant la mise en mémoire tampon de sortie (un peu sale) pour le collecter et l'inclure votre réponse, par exemple.

ob_start();
get_template_part('template-parts/content', 'ajax');
// call ob_get_contents() and load the return value into an array or string to send back
ob_end_clean();
0
firxworx

Changer dans votre code $offet to $paged variable WP_Query peut garder une trace des pages qui vous donneront le nombre total de pages de votre objet boucle comme

$loop->max_num_pages

<script>
    var ajaxUrl = "<?php echo admin_url('admin-ajax.php')?>";
    var page = 1;
    var ppp = 6; // posts per page

    jQuery("#load-more").on("click", function() {
        jQuery("#load-more").addClass("disabled");
        jQuery.post(ajaxUrl, {
            action: "more_post_ajax",
            page: page,
            ppp: ppp
        }).success(function(posts) {
            // execute this block only if there is post
            if(posts) { 
            page++;
            jQuery("#press-listing").append(posts); // append to container
            jQuery("#load-more").removeClass("disabled");
            }
        });

    });
</script>

Et votre fonction ajax php serait

function more_post_ajax() {
    $page = $_POST["page"];
    $ppp = $_POST["ppp"];
    header("Content-Type: text/html");

    $args = array(
        'cat' => 1,
        'posts_per_page' => $ppp,
        'paged' => $page
    );

    $loop = new WP_Query($args);

    if($loop->max_num_pages <= $page):

    while ($loop->have_posts()) { $loop->the_post();
        get_template_part('template-parts/content', 'ajax');
    }
    exit;

   else:
     echo 0;
     die();

   endif;
}
add_action('wp_ajax_nopriv_more_post_ajax', 'more_post_ajax');
add_action('wp_ajax_more_post_ajax', 'more_post_ajax');
0
Raja Mohammed