Kriuchko
1/8/2019 - 2:04 PM

Ajax

Wordpress ajax

https://premium.wpmudev.org/blog/load-posts-ajax/
https://www.hostinger.com/tutorials/how-to-fix-admin-ajax-file

\!h --- 
function load_blog_posts() {
  check_ajax_referer( 'load_blog_posts' );

  $blog_posts_per_page = get_field( 'blog_posts_per_page', 'option' );
  $offset = $_GET['offset'];
  $args_main = array(
    'post_type' => 'post',
    'post_status' => 'publish',
    'offset' => $offset,
    'posts_per_page' => $blog_posts_per_page
  );
  $blog_posts = new WP_Query( $args_main );

  if( $blog_posts->have_posts() ) :
?>
  <?php while( $blog_posts->have_posts() ) : $blog_posts->the_post(); ++$offset; ?>
    <div class="col-ph-6 col-sm-4 col-md-3">
      <?php get_template_part( 'blocks/post-preview' ); ?>
    </div>
  <?php endwhile; ?>

  <?php if( $blog_posts->found_posts > $offset ): ?>
    <div class="more-btn-holder">
      <a href="<?php echo add_query_arg( array( 'action' => 'load_blog_posts',
                                                'offset' => $offset,
                                                '_wpnonce' => wp_create_nonce( 'load_blog_posts' ) ),
                                                admin_url( 'admin-ajax.php' ) ); ?>" class="load-more load-more-alt">
        <?php the_field( 'blog_load_more_text', 'option' ); ?><i>>></i>
      </a>
    </div>
  <?php endif; ?>
<?php
  endif; wp_reset_query();
  exit;
}
add_action( 'wp_ajax_load_blog_posts', 'load_blog_posts' );
add_action( 'wp_ajax_nopriv_load_blog_posts', 'load_blog_posts' );

<?php
$blog_posts_per_page = get_field( 'blog_posts_per_page', 'option' );

if( $wp_query->found_posts > $blog_posts_per_page ):
?>
  <div class="more-btn-holder">
    <a href="<?php echo add_query_arg( array( 'action' => 'load_blog_posts',
                                              'offset' => $blog_posts_per_page,
                                              '_wpnonce' => wp_create_nonce( 'load_blog_posts' ) ),
                                              admin_url( 'admin-ajax.php' ) ); ?>" class="load-more load-more-alt">
      <?php the_field( 'blog_load_more_text', 'option' ); ?><i>>></i>
    </a>
  </div>
<?php endif; ?>
\!h ---



\!h functions.php

function load_games() {
  check_ajax_referer( 'load_games' );

  $startpost = $_GET['startpost'];
  $games_count_to_load = $_GET['games_count_to_load'];
  $term = $_GET['game-type'];

  $args_final = array();
  $args_main = array(
    'post_type' => 'games',
    'post_status' => 'publish',
    'offset' => $startpost,
    'posts_per_page' => $games_count_to_load
  );

  if(!empty($term))
  {
    $args_filters['tax_query'][] = array('taxonomy' => 'game-type', 'field' => 'slug', 'terms' => $term);
  }

  if( $args_filters ){
    $args_final = array_merge( $args_main, $args_filters );
  } else {
    $args_final = $args_main;
  }

  $games = new WP_Query( $args_final );

  if( $games->have_posts() ) :
?>
  <?php while( $games->have_posts() ) : $games->the_post(); ++$startpost; ?>
     <?php get_template_part( 'game-preview' ); ?>
  <?php endwhile; ?>

  <?php if( $games->found_posts > $startpost ): ?>
    <a href="<?php echo add_query_arg( array( 'action' => 'load_games',
                                              'game-type' => $term,
                                              'startpost' => $startpost,
                                              'games_count_to_load' => $games_count_to_load,
                                              '_wpnonce' => wp_create_nonce( 'load_games' ) ),
                                              admin_url( 'admin-ajax.php' ) ); ?>" class="load-more hide">
      <?php _e( 'Load more' ); ?>
    </a>
  <?php endif; ?>
<?php
  endif; wp_reset_query();
  exit;
}
add_action( 'wp_ajax_load_games', 'load_games' );
add_action( 'wp_ajax_nopriv_load_games', 'load_games' );

\!h page-games.php

<div class="games-holder">
  <div class="games-header">
    <?php
      $games_title = '';
      $all_games_title = get_field( 'all_games_title' );

      if ( $all_games_title ) {
        $games_title = $all_games_title;
      }

      if (isset( $_GET['game-type'] ) && !empty( $_GET['game-type'] )) {
        $game_type_term = get_term_by( 'slug', $_GET['game-type'], 'game-type' );

        if ( $game_type_term->name ) {
          $games_title = $game_type_term->name;
        }
      }
    ?>
    <h2><?php echo $games_title; ?></h2>

    <?php
      $gametype = get_terms( 'game-type', array( 'hide_empty' => 0 ) );
      if ( !empty( $gametype ) ) :
    ?>
      <div class="games-types">
        <form action="<?php the_permalink(); ?>" method="get">
          <select title="<?php _e( 'Game Type' ) ?>" data-placeholder="<?php _e( 'Game Type' ) ?>" name="game-type" onchange="document.location.href=this.options[this.selectedIndex].value;">
            <option value=""></option>

            <?php if ( $all_games_title && isset( $_GET['game-type'] ) && !empty( $_GET['game-type'] ) ): ?>
              <option value="<?php the_permalink(); ?>"><?php echo $all_games_title; ?></option>
            <?php endif; ?>

            <?php foreach ( $gametype as $term ): ?>
              <option value="<?php echo add_query_arg( array( 'game-type' => $term->slug  ) ); ?>#content">
                <?php echo $term->name; ?>
              </option>
            <?php endforeach; ?>
          </select>
        </form>
      </div>
    <?php endif; ?>
  </div>

  <div class="games load-more-holder">
    <?php
      $games_per_page = get_field('games_per_page');
      $games_count_to_load = get_field('games_count_to_load');

      if ( empty( $games_count_to_load ) ) {
        $games_count_to_load = $games_per_page;
      }

      $args_final = array();
      $args_main = array(
        'post_type' => 'games',
        'post_status' => 'publish',
        'posts_per_page' => $games_per_page
      );

      if ( !empty( $_GET['game-type'] ) ) {
        $args_filters['tax_query'][] = array('taxonomy' => 'game-type', 'field' => 'slug', 'terms' => $_GET['game-type']);
      }

      if ( $args_filters ) {
        $args_final = array_merge( $args_main, $args_filters );
      } else {
        $args_final = $args_main;
      }

      $games = new WP_Query( $args_final );

      if ( $games->have_posts() && $games_per_page ):
    ?>
      <?php while ( $games->have_posts() ) : $games->the_post(); ?>
        <?php get_template_part( 'game-preview' ); ?>
      <?php endwhile; ?>

      <?php if( $games->found_posts > $games_per_page ): ?>
        <a href="<?php echo add_query_arg( array( 'action' => 'load_games',
                                                  'game-type' => $_GET['game-type'],
                                                  'startpost' => $games_per_page,
                                                  'games_count_to_load' => $games_count_to_load,
                                                  '_wpnonce' => wp_create_nonce( 'load_games' ) ),
                                                  admin_url( 'admin-ajax.php' ) ); ?>" class="load-more hide">
          <?php _e( 'Load more' ); ?>
        </a>
      <?php endif; ?>
    <?php else: ?>
     <?php get_template_part( 'not-found' ); ?>
    <?php endif; wp_reset_query(); ?>
  </div>
</div>

\!h load-games.js

jQuery(function() {
  initLoadMore();
});

// load more init
function initLoadMore() {
  jQuery('.load-more-holder').loadMore({
    linkSelector: 'a.load-more',
    scroll: true
  });
}

/*
 * jQuery Load More plugin
 */
;(function($, $win) {
  'use strict';

  var ScrollLoader = {
    attachEvents: function() {
      var self = this;

      this.destroySubEvents();

      $win.on('load.ScrollLoader resize.ScrollLoader orientationchange.ScrollLoader', function() { self.onResizeHandler(); });
      $win.on('scroll.ScrollLoader', function() { self.onScrollHandler(); });
      this.$holder.on('ContentLoader/loaded.ScrollLoader', function() { self.onResizeHandler(); });

      this.winProps = {};
      this.holderProps = {};
      this.onResizeHandler();
    },

    onResizeHandler: function() {
      this.winProps.height = $win.height();
      this.holderProps.height = this.$holder.outerHeight();
      this.holderProps.offset = this.$holder.offset().top;

      this.onScrollHandler();
    },

    onScrollHandler: function() {
      this.winProps.scroll = $win.scrollTop();

      if (this.winProps.scroll + this.winProps.height + Math.min(1, this.options.additionBottomOffset) > this.holderProps.height + this.holderProps.offset) {
        this.loadInclude();
      }
    },

    destroySubEvents: function() {
      $win.off('.ScrollLoader');
      this.$holder.off('.ScrollLoader');
    }
  };

  var ClickLoader = {
    attachEvents: function() {
      var self = this;

      this.$holder.on('click.ClickLoader', this.options.linkSelector, function(e) { self.onClickHandler(e); });
    },

    onClickHandler: function(e) {
      e.preventDefault();

      this.loadInclude();
    },

    destroySubEvents: function() {
      this.$holder.off('.ClickLoader');
    }
  };

  var ContentLoader = function($holder, options) {
    this.$holder = $holder;
    this.options = options;

    this.init();
  };

  var ContentLoaderProto = {
    init: function() {
      this.$link = this.$holder.find(this.options.linkSelector);
      this.$newContentTarget = this.options.newContentTarget ? this.$holder.find(this.options.newContentTarget) : this.$holder;

      if (!this.$link.length) {
        this.removeInstance();
        return;
      }

      this.attachEvents();
    },

    loadInclude: function() {
      if (this.isBusy) {
        return;
      }

      var self = this;

      this.toggleBusyMode(true);

      $.get(self.$link.attr('href'), function(source) { self.successHandler(source); });
    },

    successHandler: function(include) {
      var $tmpDiv = jQuery('<div>').html(include);
      var $nextIncludeLink = $tmpDiv.find(this.options.linkSelector);

      if ($nextIncludeLink.length) {
        this.refreshLink($nextIncludeLink);
      } else {
        this.destroy();
      }

      this.appendItems($tmpDiv.children());
    },

    appendItems: function($newItems) {
      var self = this;

      this.$newContentTarget.append($newItems.addClass(this.options.preAppendClass));

      setTimeout(function() { // need this timeout coz need some time for css preAppendClass applied to the new items
        $newItems.removeClass(self.options.preAppendClass);

        self.toggleBusyMode(false);
        self.$holder.trigger('ContentLoader/loaded');
        self.makeCallback('onContentLoad', $newItems);
      }, 100);

      if (window.picturefill) {
        window.picturefill();
      }
    },

    refreshLink: function($nextIncludeLink) {
      this.$link.attr('href', $nextIncludeLink.attr('href'));
      $nextIncludeLink.remove();
    },

    toggleBusyMode: function(state) {
      this.$holder.toggleClass(this.options.busyClass, state);
      this.isBusy = state;
    },

    removeInstance: function() {
      this.$holder.removeData('ContentLoader');
    },

    makeCallback: function(name) {
      if (typeof this.options[name] === 'function') {
        var args = Array.prototype.slice.call(arguments);
        args.shift();
        this.options[name].apply(this, args);
      }
    },

    destroy: function() {
      this.removeInstance();
      this.destroySubEvents();

      this.$link.remove();
    }
  };

  $.fn.loadMore = function(opt) {
    var args = Array.prototype.slice.call(arguments);
    var method = args[0];

    var options = $.extend({
      scroll: false,
      linkSelector: '.load-more',
      newContentTarget: null,
      busyClass: 'is-busy',
      additionBottomOffset: 50,
      preAppendClass: 'new-item'
    }, opt);

    return this.each(function() {
      var $holder = jQuery(this);
      var instance = $holder.data('ContentLoader');

      if (typeof opt === 'object' || typeof opt === 'undefined') {
        ContentLoader.prototype = $.extend(options.scroll ? ScrollLoader : ClickLoader, ContentLoaderProto);

        $holder.data('ContentLoader', new ContentLoader($holder, options));
      } else if (typeof method === 'string' && instance) {
        if (typeof instance[method] === 'function') {
          args.shift();
          instance[method].apply(instance, args);
        }
      }
    });
  };
}(jQuery, jQuery(window)));


function theme_events_ajax_request()
{


    // Always die in functions echoing ajax content
    die();
}

add_action('wp_ajax_theme_events_ajax_request', 'theme_events_ajax_request');
add_action('wp_ajax_nopriv_theme_events_ajax_request', 'theme_events_ajax_request');


$_nonce = wp_create_nonce('theme_events_nonce');
$_link = add_query_arg([
    'action' => 'theme_events_ajax_request',
    'cat_id' => $term->ID,
    'nonce' => $_nonce
], admin_url('admin-ajax.php'));


js
------
function initAjaxPosts() {
	jQuery('.filter-item ul li').click(function(event) {
		event.preventDefault();

		jQuery.ajax({
			url: jQuery(this).find('a').attr('href'),
			action: 'theme_posts_ajax_request',
			success: function() {
				alert('gtadada');
			}
		});
	});
}
\!h ——— page
<div class="strain-grid">
    <div class="load-more-holder">
        <?php
        $strains_per_page = get_field( 'strains_per_page' );
        $strains_count_to_load = get_field( 'strains_count_to_load' );

        if ( empty( $strains_count_to_load ) ) {
          $strains_count_to_load = $strain_per_page;
        }

        $args_final = array();
        $args_main = array(
          'post_type' => 'strain',
          'post_status' => 'publish',
          'posts_per_page' => $strains_per_page
        );

        if ( !empty( $_GET['classification'] ) ) {
          $args_filters['tax_query'][] = array('taxonomy' => 'strain-classification', 'field' => 'slug', 'terms' => $_GET['classification']);
        }

        if ( $args_filters ) {
          $args_final = array_merge( $args_main, $args_filters );
        } else {
          $args_final = $args_main;
        }

        $strains = new WP_Query( $args_final );

        if ( $strains->have_posts() && $strains_per_page ):
        ?>
          <div class="strain-cards">
            <?php while ( $strains->have_posts() ) : $strains->the_post(); ?>
              <?php get_template_part( 'blocks/library/strain-card' ); ?>
            <?php endwhile; ?>
          </div>

          <?php if( $strains->found_posts > $strains_per_page ): ?>
            <a href="<?php echo add_query_arg( array( 'action' => 'load_strains',
                                                      'classification' => $_GET['classification'],
                                                      'startpost' => $strains_per_page,
                                                      'strains_count_to_load' => $strains_count_to_load,
                                                      '_wpnonce' => wp_create_nonce( 'load_strains' ) ),
                                                      admin_url( 'admin-ajax.php' ) ); ?>" class="load-more">
              <?php _e( 'Load more', 'zengolds' ); ?>
            </a>
          <?php endif; ?>
        <?php else: ?>
            <?php get_template_part( 'blocks/library/not_found' ); ?>
        <?php endif; wp_reset_query(); ?>
    </div>
</div>

\!h ——— functions.php

function load_strains() {
  check_ajax_referer( 'load_strains' );

  $startpost = $_GET['startpost'];
  $strains_count_to_load = $_GET['strains_count_to_load'];
  $term = $_GET['classification'];

  $args_final = array();
  $args_main = array(
    'post_type' => 'strain',
    'post_status' => 'publish',
    'offset' => $startpost,
    'posts_per_page' => $strains_count_to_load
  );

  if ( !empty( $term ) ) {
    $args_filters['tax_query'][] = array( 'taxonomy' => 'strain-classification', 'field' => 'slug', 'terms' => $term );
  }

  if( $args_filters ){
    $args_final = array_merge( $args_main, $args_filters );
  } else {
    $args_final = $args_main;
  }

  $strains = new WP_Query( $args_final );

  if( $strains->have_posts() ) :
?>
    <?php while( $strains->have_posts() ) : $strains->the_post(); ++$startpost; ?>
    <?php get_template_part( 'blocks/library/strain-card' ); ?>
    <?php endwhile; ?>

    <?php if( $strains->found_posts > $startpost ): ?>
    <a href="<?php echo add_query_arg( array( 'action' => 'load_strains',
                                              'classification' => $term,
                                              'startpost' => $startpost,
                                              'strains_count_to_load' => $strains_count_to_load,
                                              '_wpnonce' => wp_create_nonce( 'load_strains' ) ),
                                              admin_url( 'admin-ajax.php' ) ); ?>" class="load-more">
      <?php _e( 'Load more', 'zengolds' ); ?>
    </a>
    <?php endif; ?>
<?php
  endif; wp_reset_query();
  exit;
}
add_action( 'wp_ajax_load_strains', 'load_strains' );
add_action( 'wp_ajax_nopriv_load_strains', 'load_strains' );

\!h --- js

jQuery(function() {
	initLoadMore();
});

// load more init
function initLoadMore() {
  jQuery('.load-more-holder').loadMore({
    linkSelector: 'a.load-more',
    newContentTarget: '.strain-cards'
  });
}


/*
 * jQuery Load More plugin
 */
;(function($, $win) {
	'use strict';

	var ScrollLoader = {
		attachEvents: function() {
			var self = this;

			$win.on('load.ScrollLoader resize.ScrollLoader orientationchange.ScrollLoader', function() { self.onResizeHandler(); });
			$win.on('scroll.ScrollLoader', function() { self.onScrollHandler(); });
			this.$holder.on('ContentLoader/loaded.ScrollLoader', function() { self.onResizeHandler(); });

			this.winProps = {};
			this.holderProps = {};
			this.onResizeHandler();
		},

		onResizeHandler: function() {
			this.winProps.height = $win.height();
			this.holderProps.height = this.$holder.outerHeight();
			this.holderProps.offset = this.$holder.offset().top;

			this.onScrollHandler();
		},

		onScrollHandler: function() {
			this.winProps.scroll = $win.scrollTop();

			if (this.winProps.scroll + this.winProps.height + Math.min(1, this.options.additionBottomOffset) > this.holderProps.height + this.holderProps.offset) {
				this.loadInclude();
			}
		},

		destroySubEvents: function() {
			$win.off('.ScrollLoader');
			this.$holder.off('.ScrollLoader');
		}
	};

	var ClickLoader = {
		attachEvents: function() {
			var self = this;

			this.$holder.on('click.ClickLoader', this.options.linkSelector, function(e) { self.onClickHandler(e); });
		},

		onClickHandler: function(e) {
			e.preventDefault();

			this.loadInclude();
		},

		destroySubEvents: function() {
			this.$holder.off('.ClickLoader');
		}
	};

	var ContentLoader = function($holder, options) {
		this.$holder = $holder;
		this.options = options;

		this.init();
	};

	var ContentLoaderProto = {
		init: function() {
			this.$link = this.$holder.find(this.options.linkSelector);
			this.$newContentTarget = this.options.newContentTarget ? this.$holder.find(this.options.newContentTarget) : this.$holder;

			if (!this.$link.length) {
				this.removeInstance();
				return;
			}

			this.attachEvents();
		},

		loadInclude: function() {
			if (this.isBusy) {
				return;
			}

			var self = this;

			this.toggleBusyMode(true);

			$.get(self.$link.attr('href'), function(source) { self.successHandler(source); });
		},

		successHandler: function(include) {
			var $tmpDiv = jQuery('<div>').html(include);
			var $nextIncludeLink = $tmpDiv.find(this.options.linkSelector);

			if ($nextIncludeLink.length) {
				this.refreshLink($nextIncludeLink);
			} else {
				this.destroy();
			}

			this.appendItems($tmpDiv.children());
		},

		appendItems: function($newItems) {
			var self = this;

			this.$newContentTarget.append($newItems.addClass(this.options.preAppendClass));

			setTimeout(function() { // need this timeout coz need some time for css preAppendClass applied to the new items
				$newItems.removeClass(self.options.preAppendClass);

				self.toggleBusyMode(false);
				self.$holder.trigger('ContentLoader/loaded');
			}, 100);

			if (window.picturefill) {
				window.picturefill();
			}
		},

		refreshLink: function($nextIncludeLink) {
			this.$link.attr('href', $nextIncludeLink.attr('href'));
			$nextIncludeLink.remove();
		},

		toggleBusyMode: function(state) {
			this.$holder.toggleClass(this.options.busyClass, state);
			this.isBusy = state;
		},

		removeInstance: function() {
			this.$holder.removeData('ContentLoader');
		},

		destroy: function() {
			this.removeInstance();
			this.destroySubEvents();

			this.$link.remove();
		}
	};

	$.fn.loadMore = function(opt) {
		var args = Array.prototype.slice.call(arguments);
		var method = args[0];

		var options = $.extend({
			scroll: false,
			linkSelector: '.load-more',
			newContentTarget: null,
			busyClass: 'is-busy',
			additionBottomOffset: 50,
			preAppendClass: 'new-item'
		}, opt);

		return this.each(function() {
			var $holder = jQuery(this);
			var instance = $holder.data('ContentLoader');

			if (typeof opt === 'object' || typeof opt === 'undefined') {
				ContentLoader.prototype = $.extend(options.scroll ? ScrollLoader : ClickLoader, ContentLoaderProto);

				$holder.data('ContentLoader', new ContentLoader($holder, options));
			} else if (typeof method === 'string' && instance) {
				if (typeof instance[method] === 'function') {
					args.shift();
					instance[method].apply(instance, args);
				}
			}
		});
	};
}(jQuery, jQuery(window)));