同位素AJAX过滤并加载更多

时间:2019-03-15 10:10:14

标签: javascript php jquery ajax wordpress

我正在使用Isotope Layout来组织一系列的div,我已经分别成功地使AJAX负载增加了,并且使AJAX过滤器成功了,但是我想将两者结合起来。

从本质上讲,您可以加载更多,但是如果选择过滤器,则按“加载更多”只会在该过滤器上加载更多。

我的方法如下:

  • 如果用户单击加载更多,则使用下一页结果会发出AJAX请求以获取下一组项目。
  • 如果用户选择一个类别,则会清除当前结果集,并初始化一个新查询以获取该类别中的项目

代码实现:

load-more.js

/**
 * Load more script using AJAX
 */
jQuery(document).ready(function ($) {

  let has_run = false;

  // Hook into click event
  $('button.load-more-posts').click(function (e) {
    e.preventDefault();

    let button = $(this);
    let nonce = $(this).data("nonce");

    let $grid = $('#grid').isotope({
      itemSelector: '.grid-item',
    });

    // Disable the button
    button.prop("disabled", true);

    // Check the offset
    if (has_run == false) {
      button.data('current-page', $(this).data("current-page"));
    }

    // Perform AJAX request
    $.ajax({
      type: 'POST',
      dataType: 'json',
      url: ajax_load_more_object.ajax_url,
      data: {
        action: 'ajax_load_more_posts',
        security: nonce,
        current_page: button.data('current-page'),
      },
      beforeSend: function (xhr) {
        button.text('Fetching...');
      },
      success: function (response) {
        if (response) {
          button.text('Load more');

          // An array to store new items added via AJAX
          var new_items = [];

          // Run through JSON
          $.each(response, function (key, value) {

            var $new_item =

              $(`<div class="grid-item article-post-card ${value.category[0]['slug']}">
              <a class="article-post-card__anchor" href=" ${value.permalink}" alt="${value.title}">
                    <div class="article-post-card__featured-image-container">
                      <div class="article-post-card__overlay"></div>
                      <div class="article-post-card__featured-image">
                          ${value.thumbnail}
                      </div>

                      <div class="article-post-card__category-label">
                          ${value.category[0]['name']}
                      </div>

                  </div>

                    <div class="article-post-card__content-wrapper">

                      <div class="article-post-card__publish-date">
                          <time class="updated" datetime="${value.post_time}">${value.date}</time>
                      </div>

                      <div class="article-post-card__title">
                          ${value.title}
                      </div>

                      <div class="article-post-card__excerpt">
                        ${value.introduction}
                      </div>

                  </div>
              </a>
          </div>`);

            new_items.push($new_item[0]);
          });

          // Add the new items to the grid
          $grid
            .isotope('insert', new_items)
            .imagesLoaded().progress(function () {
              $grid.isotope('layout');
            });

          // Set the current page to the next page
          var current_page = button.data("current-page");
          var max_pages = button.data("max-pages");

          button.data("current-page", current_page + 1);

          if (current_page >= max_pages) {
            button.text("No more posts to load");
          } else {
            // Undo Button Disable
            button.prop("disabled", false);
          }

          // Update boolean so that page count is not reset
          has_run = true;

          // Return false as we're at the end
          return false;

          // If the AJAX function returned no data
        } else {
          button.remove();
        }
      },
      error: function (xhr, status, error) {
        console.log("There was an error", error);
      }
    });
  });
});

load-more.php

function ajax_load_more_posts_callback()
{
    // First check the nonce, if it fails the function will break
    check_ajax_referer('ajax_load_more_posts', 'security');

    // Get the data we have from the load more button
    $current_page = $_POST['current_page'];

    if ($current_page != null && absint($current_page)) {

        // Finally, we'll set the query arguments and instantiate WP_Query
        $args = array(
            'post_type' => 'post',
            'status' => 'published',
            'orderby'    => 'post_date',
            'order' => 'DESC',
            'paged' => $current_page
        );

        $query = new WP_Query($args);

        $post_list = array();

        if ($query->have_posts()) :

            while ($query->have_posts()) : $query->the_post();

                $introduction = !get_field('introduction') ? get_the_excerpt() : get_field('introduction');

                $post_list[] = array(
                    'category' => get_the_category(),
                    'tags' => get_the_tags(),
                    'title' => get_the_title(),
                    'introduction' => $introduction,
                    'post_time' => get_post_time('c', true),
                    'date' => get_the_date(),
                    'permalink' => get_permalink(),
                    'thumbnail' => get_the_post_thumbnail(),

                );
            endwhile;
        endif;

        echo json_encode($post_list);

        wp_die();
    }
}

get-posts.js

  /**
   * The selectable filters
   */
  let $filters = $('.filters input');
  let $resultCount = $('.filter-box__result-count');

  // Inititialize Isotope
  const $grid = $('#grid').isotope({
    itemSelector: '.grid-item',
    percentagePosition: true,
    animationEngine: 'best-available',
    animationOptions: {
      duration: 800,
    },
    filter: '*',
    masonry: {
      columnWidth: '.grid-item',
      gutter: 30,
    },
  })

  // The items in the grid
  const $items = $grid.data('isotope');

  /**
   * Each time an image is loaded, re-layout the grid.
   * This prevents any weird overlapping.
   */
  $grid.imagesLoaded().progress(function () {
    $grid.isotope('layout');
  });

  /**
   * Apply filters to Isotope when any filters are updated.
   * This will also update the result count and add some block elements.
   */
  $filters.change(function () {
    // An empty array to contain filters
    let $selectedFilters = [];

    // Loop through filters and add values if checked
    $('.filters input').each(function (counter, element) {
      if (element.checked) {
        $selectedFilters.push(element.value);
      }
    })

    console.log($selectedFilters);

    // If there are filters in the filters array, join them
    if ($selectedFilters.length > 0) {
      $('.filter-box__applied-filters-area').show();
      $filters = $selectedFilters.join(', ');
    } else {
      $filters = '*';
    }

    // Perform AJAX request
    $.ajax({
      type: 'POST',
      dataType: 'json',
      url: ajax_get_posts_object.ajax_url,
      data: {
        action: 'ajax_get_posts',
        filters: $selectedFilters,
      },
      beforeSend: function (xhr) {
        console.log('Retreiving');
      },
      success: function (response) {
        if (response) {

          // An array to store new items added via AJAX
          var new_items = [];

          // Run through JSON
          $.each(response.posts, function (key, value) {
            console.log(value);

            var $new_item =

              $(`<div class="grid-item article-post-card ${value.category[0]['slug']}">
              <a class="article-post-card__anchor" href=" ${value.permalink}" alt="${value.title}">
                    <div class="article-post-card__featured-image-container">
                      <div class="article-post-card__overlay"></div>
                      <div class="article-post-card__featured-image">
                          ${value.thumbnail}
                      </div>

                      <div class="article-post-card__category-label">
                          ${value.category[0]['name']}
                      </div>

                  </div>

                    <div class="article-post-card__content-wrapper">

                      <div class="article-post-card__publish-date">
                          <time class="updated" datetime="${value.post_time}">${value.date}</time>
                      </div>

                      <div class="article-post-card__title">
                          ${value.title}
                      </div>

                      <div class="article-post-card__excerpt">
                        ${value.introduction}
                      </div>

                  </div>
              </a>
          </div>`);

            new_items.push($new_item[0]);
          });

          console.log(response.pages);
          console.log(response.current);

          $grid.isotope('remove', $grid.isotope('getItemElements'));

          $grid.isotope({
              filter: $filters
            })
            .isotope('insert', new_items)
            .imagesLoaded().progress(function () {
              $grid.isotope('layout');
            });

          updateFilterCount();

          // Return false as we're at the end
          return false;

          // If the AJAX function returned no data
        } else {}
      },
      error: function (xhr, status, error) {
        console.log("There was an error", error);
      }
    });
  });

get-posts.php

function ajax_get_posts_callback()
{
    $filters = $_POST['filters'] ?? '';

    $filter_string = join(",",  $filters);

    $args = array(
        'post_type' => 'post',
        'status' => 'published',
        'category_name' => $filter_string,
        'orderby'    => 'post_date',
        'order' => 'DESC',
    );

    $query = new WP_Query($args);

    $post_list = array();

    if ($query->have_posts()) :

        $pages = $query->max_num_pages;

        while ($query->have_posts()) : $query->the_post();

            $introduction = !get_field('introduction') ? get_the_excerpt() : get_field('introduction');

            $post_list[] = array(
                'category' => get_the_category(),
                'tags' => get_the_tags(),
                'title' => get_the_title(),
                'introduction' => $introduction,
                'post_time' => get_post_time('c', true),
                'date' => get_the_date(),
                'permalink' => get_permalink(),
                'thumbnail' => get_the_post_thumbnail(),

            );
        endwhile;
    endif;

    $data = [
        'posts' => $post_list,
        'pages' => $pages,
        'current' => 1
    ];

    echo json_encode($data);

    wp_die();
}

基本上,我需要一种方法来传递选定的类别,以便在发生过滤时加载更多内容。

0 个答案:

没有答案