http://exo.mk/wp-content/uploads/2018/02/100_5036-e1518683887524.jpg

Posted on:February 15 2018at8:33 am

Milancho Ivanov

Software Developer

The following code can help you to create ajax infinite scroll for your custom post types search. As an example in this blog we will use search page for custom post types.

Firstly, you create a custom query that will get the search text from the input and store it in a variable $searchtext. Then you add this variable together with $paged variable and the name of your custom post type into the $args array.  At this point your custom query in the search.php file should look something like this:

$searchtext=$_GET['s'];							
$paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
	$args = array(
		's' => $searchtext,
		'post_type' => 'your-custom-post-name',
		'paged'=>$paged
		);								
$query = new WP_Query($args);

After you finish with the custom query you need to place “load more” and “load pervious” button bellow and above the custom loop. Just keep in mind that you need to enqueue  “awesome icons” into your script in order the code to work properly. Your custom loop in the search.php should look something like this:

<?php if( is_paged() ): ?>
     <div class=" text-center">
          <a class="btn-exo-load exo-load-more" data-prev="1" data-searchtext="<?php echo $searchtext ?>" data-page="<?php echo exo_check_paged(1); ?>" data-search="<?php echo exo_grab_current_uri(); ?>" data-url="<?php echo admin_url('admin-ajax.php'); ?>">
	       <span class="exo-icon exo-loading fa fa-refresh "></span>
	       <span class="text">Load Previous</span>
          </a>
     </div><!--container text-->							
<?php endif; ?>
<div class="exo-posts-container">			
     <?php if ( $query->have_posts() ) : 
       echo '<div class="page-limit" data-page = "'.$_SERVER["REQUEST_URI"].'">';
	        /* Start the Loop */ 
            while($query -> have_posts()) : $query -> the_post(); 
	       // YOUR CONTENT GOES HERE
            endwhile;		
       echo '</div>';						  
     wp_reset_postdata();								
     else:  									
     endif; ?>						
</div> <!--container-->						
<div class=" text-center">
     <a class="btn-exo-load exo-load-more" data-searchtext="<?php echo $searchtext ?>" data-page="<?php echo exo_check_paged(1); ?>" data-search="<?php echo exo_grab_current_uri(); ?>" data-url="<?php echo admin_url('admin-ajax.php'); ?>">
          <span class="exo-icon exo-loading fa fa-refresh "></span>
	  <span class="text">Load More</span>
     </a>
</div><!--container text-->

Secondly, you need to create and enqueue java script file. This java script On Click of the buttons “load previous” or “load more” will make ajax request and asynchronously call the function exo_load_more in the function.php. In addition, the script will also take care of the animation scrolling effect of the blog page.

Java script code:

jQuery(document).ready(function($){
     /*ajax search page */
          revealPosts();
     /* variable decalarations */
	  var last_scroll = 0;	
     $(document).on('click','.exo-load-more:not(.loading)', function(){
	  var that = $(this);
	  var page = $(this).data('page');
	  var newPage = page+1;
	  var ajaxurl = $(this).data('url');
	  var prev = that.data('prev');
	  var search = that.data('search');
	  var searchtext = that.data('searchtext');		
		if( typeof prev === 'undefined' ){
			prev = 0;
		}
		if( typeof search === 'undefined' ){
			search = 0;
		}		
		that.addClass('loading').find('.text').slideUp(320);
		that.find('.exo-icon').addClass('spin');
		$.ajax({			
			url : ajaxurl,
			type : 'post',
			data : {				
				page : page,
				prev : prev,
				search: search,
				searchtext: searchtext,
				action: 'exo_load_more'				
			},		
			error : function( response ){
				console.log(response);
			},
			success : function( response ){				
				if( response == 0 ){					
					$('.exo-posts-container').append( '<div class="text-center"><h3>You reached the end of the line!</h3><p>No more posts to load.</p></div>' );
					that.slideUp(320);					
				} else {					
					setTimeout(function(){				
						if( prev == 1 ){
							$('.exo-posts-container').prepend( response );
							newPage = page-1;
						} else {
							$('.exo-posts-container').append( response );
						}						
						if( newPage == 1 ){							
							that.slideUp(320);							
						} else {							
							that.data('page', newPage);						
							that.removeClass('loading').find('.text').slideDown(320);
							that.find('.exo-icon').removeClass('spin');							
						}						
						revealPosts();						
					}, 1000);					
				}			
			}
		});
	});

	   /* scroll function */

	$(window).scroll( function(){		
		var scroll = $(window).scrollTop();
		console.log(scroll);
		if( Math.abs( scroll - last_scroll ) > $(window).height()*0.1 ) {
			last_scroll = scroll;			
			$('.page-limit').each(function( search ){				
				if( isVisible( $(this) ) ){					
					history.replaceState( null, null, $(this).attr("data-page") );
					return(false);					
				}				
			});			
		}		
	});	

	/* helper functions */

	function revealPosts(){		
		var posts = $('article:not(.reveal)');
		var i = 0;		
		setInterval(function(){			
			if( i >= posts.length ) return false;			
			var el = posts[i];
			$(el).addClass('reveal');			
			i++			
		}, 200);		
	}

	function isVisible( element ){		
		var scroll_pos = $(window).scrollTop();
		var window_height = $(window).height();
		var el_top = $(element).offset().top;
		var el_height = $(element).height();
		var el_bottom = el_top + el_height;
		return ( ( el_bottom - el_height*0.25 > scroll_pos ) && ( el_top < ( scroll_pos+0.5*window_height ) ) );		
	}	
});

On the end, you need to place the following functions in your functions.php file:

  1. exo_check_paged
  2. exo_grab_current_uri
  3. exo_load_more

The function exo_check_paged is checking if the page is paged and return the page, while the exo_grab_current_uri is returning the current uri of the page.

function exo_check_paged( $num = null ){	
	$output = '';	
	if( is_paged() ){ $output = 'page/' . get_query_var( 'paged' ); }	
	if( $num == 1 ){
		$paged = ( get_query_var( 'paged' ) == 0 ? 1 : get_query_var( 'paged' ) );
		return $paged;
	} else {
		return $output;
	}	
}

function exo_grab_current_uri() {
	$http = ( isset( $_SERVER["HTTPS"] ) ? 'https://' : 'http://' );
	$referer = $http . $_SERVER["HTTP_HOST"];
	$archive_url = $referer . $_SERVER["REQUEST_URI"];	
	return $archive_url;
}

Function exo_load_more is where the magic is happening. The slug of the search page is looking something like this: http://www.your-website-url/page/number-of-page/?s=searchtext, where the “searchtext” is the text that you enter in the input field. If we like that the slug is changing dynamically than we need to explode the current slug, that is stored in the variable $search on the place where it is the question mark”?”. After that we need to take the first element of the array that will be equal to http://www.your-website-url/page/number-of-page and explode it again but this time on the place where the “page” is, so the first element of the second array will be http://www.your-website-url/. On the end, you are creating new slug by taking the first element of the second array and dynamically adding the $page and the $search text on it.

$address = $page_trailSecond[0].'page/'.$paged.'/?s='.$searchtext;

The code of the whole function is given bellow:

add_action('wp_ajax_nopriv_exo_load_more','exo_load_more');
add_action('wp_ajax_exo_load_more','exo_load_more');

function exo_load_more(){
	$paged = $_POST["page"]+1;
	$prev = $_POST["prev"];	
	$search = $_POST["search"];
	$searchtext=$_POST["searchtext"];
		//echo $search;			
	if( $prev == 1 && $_POST["page"] != 1 ){
		$paged = $_POST["page"]-1;
	}			
	$args = array(
		'post_type' => 'exoblog',
		's'=> $searchtext ,
		'paged'=>$paged
		);
	$query = new WP_Query($args);	
	     // Split the string where the "?" is in the slug. Take all the slug before "?"
		if ($search != '0'){
			$searchVal = explode('?',$search);
			$page_trailFirst = $searchVal;
		} else {
			$page_trailFirst = '';
		}
	        // Split slug trail on word "page" and take everything before the word "page"
			$page_trailSecond = explode('page',$page_trailFirst[0]);
			$address = $page_trailSecond[0].'page/'.$paged.'/?s='.$searchtext;	
		$query = new WP_Query($args );
	  if ( $query->have_posts() ) :
		echo '<div class="page-limit" data-page="'.$address.'">';		
		  /* Start the Loop */ 
		  while($query -> have_posts()) : $query -> the_post(); 
				get_template_part( 'content' );
		  endwhile;		
		echo '</div>';		
	  else:
		echo 0;
	endif;
	wp_reset_postdata(); 
	die(); 
 }

AND YOU ARE DONE

You may still feel like you’re missing some vital information. And you are. But you’ll never learn it all, and this is a good start.





Leave a Reply

Your email address will not be published. Required fields are marked *

*
*
*

Let's Get In Touch!


Ready to start your next project with us? That's great! Give us a call or send us an email and we will get back to you as soon as possible!

Blvd Mitropolit Teodosij Gologanov 57 - 1/2