3 Steps for Creating AJAX Post Filters

AJAX Posts (or Custom Post Types) Filter for your website by the Date, by Categories (Taxonomies) or by the Custom Field Values. Ascending or Descending order direction.

#admin-ajax.php, #noplugins  /   277

So many people asks me about post filters. So I decided to write a simple post about it — so everyone could understand how it works. 

In this post I will show you how to create an asynchronous filter by yourself, which allows to filter posts by taxonomy terms, meta values and sort results by date.

Step 1. Everything begins with the HTML form #

Our filter form will consist of 4 parts. I’ll describe each part of the form separately.

I want to filter posts by taxonomy terms #

First part of the form is a dropdown <select> of taxonomies. To create that <select> you may freely use get_terms() function. This function can work not only with custom taxonomies but with default categories and tags as well.

if( $terms = get_terms( 'category', 'orderby=name' ) ) : // to make it simple I use default categories
	echo '<select name="categoryfilter"><option>Select category...</option>';
	foreach ( $terms as $term ) :
		echo '<option value="' . $term->term_id . '">' . $term->name . '</option>'; // ID of the category as the value of an option
	endforeach;
	echo '</select>';
endif;

I want to filter posts by custom field values as well #

I use range of prices. In our case price is a custom field value that is stored in wp_postmeta table under the _price key in database.

<input type="text" name="price_min" placeholder="Min price" />
<input type="text" name="price_max" placeholder="Max price" />

By date: Ascending or Descending #

Simple radio buttons will help us to sort posts in ascending or descending order.

<label>
	<input type="radio" name="date" value="ASC" /> Date: Ascending
</label>
<label>
	<input type="radio" name="date" value="DESC" selected="selected" /> Date: Descending
</label>

Actually the featured image is just an attachment ID that is stored like a custom field value under _thumbnail_id key. We will just check that it exists.

<label>
	<input type="checkbox" name="featured_image" /> Only posts with featured image
</label>

Complete form code #

You may skip all the previous field description and use the code below as is. Insert it anywhere you want the filter to be.

<form action="<?php echo site_url() ?>/wp-admin/admin-ajax.php" method="POST" id="filter">
	<?php
		if( $terms = get_terms( 'category', 'orderby=name' ) ) : // to make it simple I use default categories
			echo '<select name="categoryfilter"><option>Select category...</option>';
			foreach ( $terms as $term ) :
				echo '<option value="' . $term->term_id . '">' . $term->name . '</option>'; // ID of the category as the value of an option
			endforeach;
			echo '</select>';
		endif;
	?>
	<input type="text" name="price_min" placeholder="Min price" />
	<input type="text" name="price_max" placeholder="Max price" />
	<label>
		<input type="radio" name="date" value="ASC" /> Date: Ascending
	</label>
	<label>
		<input type="radio" name="date" value="DESC" selected="selected" /> Date: Descending
	</label>
	<label>
		<input type="checkbox" name="featured_image" /> Only posts with featured image
	</label>
	<button>Apply filter</button>
	<input type="hidden" name="action" value="myfilter">
</form>
<div id="response"></div>

Some comments:

  • Line #1. I use default WordPress function site_url() to get actual website URL.
  • Line #1. admin-ajax.php is the default WordPress AJAX processor. I place it into the form action attribute just for simplicity.
  • Line #23. Hidden input field with the myfilter attribute is required — this is how WordPress recognize what function to use.
  • Line #25. #response div element is the container where the code will paste the result data.

Step 2. jQuery script to Send a Request and to Receive Result Data #

In this part of the post I suppose that you know something about jQuery, at least how to include it to a website page. Here is the complete jQuery-based processing code. It will send the request when the form is submitted.

jQuery(function($){
	$('#filter').submit(function(){
		var filter = $('#filter');
		$.ajax({
			url:filter.attr('action'),
			data:filter.serialize(), // form data
			type:filter.attr('method'), // POST
			beforeSend:function(xhr){
				filter.find('button').text('Processing...'); // changing the button label
			},
			success:function(data){
				filter.find('button').text('Apply filter'); // changing the button label back
				$('#response').html(data); // insert data
			}
		});
		return false;
	});
});

Step 3. PHP code to Process the Request #

I think it is the most interesting part. In this part you decide how to filter the posts the best way. This code is fully based on WP_Query.

function misha_filter_function(){
	$args = array(
		'orderby' => 'date', // we will sort posts by date
		'order'	=> $_POST['date'] // ASC ΠΈΠ»ΠΈ DESC
	);
 
	// for taxonomies / categories
	if( isset( $_POST['categoryfilter'] ) )
		$args['tax_query'] = array(
			array(
				'taxonomy' => 'category',
				'field' => 'id',
				'terms' => $_POST['categoryfilter']
			)
		);
 
	// create $args['meta_query'] array if one of the following fields is filled
	if( isset( $_POST['price_min'] ) && $_POST['price_min'] || isset( $_POST['price_max'] ) && $_POST['price_max'] || isset( $_POST['featured_image'] ) && $_POST['featured_image'] == 'on' )
		$args['meta_query'] = array( 'relation'=>'AND' ); // AND means that all conditions of meta_query should be true
 
	// if both minimum price and maximum price are specified we will use BETWEEN comparison
	if( isset( $_POST['price_min'] ) && $_POST['price_min'] && isset( $_POST['price_max'] ) && $_POST['price_max'] ) {
		$args['meta_query'][] = array(
			'key' => '_price',
			'value' => array( $_POST['price_min'], $_POST['price_max'] ),
			'type' => 'numeric',
			'compare' => 'between'
		);
	} else {
		// if only min price is set
		if( isset( $_POST['price_min'] ) && $_POST['price_min'] )
			$args['meta_query'][] = array(
				'key' => '_price',
				'value' => $_POST['price_min'],
				'type' => 'numeric',
				'compare' => '>'
			);
 
		// if only max price is set
		if( isset( $_POST['price_max'] ) && $_POST['price_max'] )
			$args['meta_query'][] = array(
				'key' => '_price',
				'value' => $_POST['price_max'],
				'type' => 'numeric',
				'compare' => '<'
			);
	}
 
 
	// if post thumbnail is set
	if( isset( $_POST['featured_image'] ) && $_POST['featured_image'] == 'on' )
		$args['meta_query'][] = array(
			'key' => '_thumbnail_id',
			'compare' => 'EXISTS'
		);
 
	$query = new WP_Query( $args );
 
	if( $query->have_posts() ) :
		while( $query->have_posts() ): $query->the_post();
			echo '<h2>' . $query->post->post_title . '</h2>';
		endwhile;
		wp_reset_postdata();
	else :
		echo 'No posts found';
	endif;
 
	die();
}
 
 
add_action('wp_ajax_myfilter', 'misha_filter_function'); 
add_action('wp_ajax_nopriv_myfilter', 'misha_filter_function');

Now you know the basics and you can easily create filters like this on WordPress:

Product filter example from eBay

If you still have problems with filters, please leave a comment below.

Only the best of WordPress

Subscribe to this weekly newsletter to receive the latest blog posts by email.I respect your privacy. Your email is safe with me.

Comments 277

← Older
  • Hi! Great plugin!
    Can you help me with having 2 select boxes with different taxonomies, for example ‘width’ and ‘length’. I would select tax_id1 and tax_id2 and return the matched posts on the same page using my ajax function.

    • Hi Thank you!

      In this step it is very good described how to do it for a taxonomy.

      • thanks for the reply!

        yes i understood that but i would need get posts from two taxonomies. my posts have two custom taxonomies (with 3 options each). so the query should return the posts that match both taxonomies. my first question was probably a little wrong.

        any ideas how i could do this with 2 select boxes?

        • I see, but clarify please what exactly you do not understand? Do you have problems with query args or maybe with HTML form?

          • okey. yes my problem is with query args. I dont know how i can get the id’s of both select forms and and return the posts that match both id’s. if i had only ne select form then it would not be any problems.

            Thank you very mutch for taking time to help people!

        • Ok, Bob, here it is:

          $args['tax_query'] = array();
           
          if( isset( $_POST['selectbox1'] ) ) {
          	$args['tax_query'][] = array(
          		array(
          			'taxonomy' => 'TAXONOMY NAME 1',
          			'field' => 'id',
          			'terms' => $_POST['selectbox1']
          		)
          	);
          }
           
          if( isset( $_POST['selectbox2'] ) ) {
          	$args['tax_query'][] = array(
          		array(
          			'taxonomy' => 'TAXONOMY NAME 2',
          			'field' => 'id',
          			'terms' => $_POST['selectbox2']
          		)
          	);
          }
          • thanks for the reply! unfortunately that didnt solve my problem.

            been trying to get the query working and use your code but something is still wrong. ill paste my code so its easier to understand. now i can get the category ids in the address bar but the query always loads the same content to the window.

            i need the content to load without refreshing the whole page or moveing to another page.

            the form

            <form action="" method="get" id="filter" accept-charset="utf-8">
             
             
            				<?php if( $terms = get_terms('liikevaihto') ) : // to make it simple I use default categories
            					echo '<select name="liikevaihto" id="liikevaihto"><option>Liikevaihto</option>';
            					foreach ( $terms as $term ) :
            						echo '<option value="' . $term->term_id . '">' . $term->term_id . '</option>'; // ID of the category as the value of an option
            					endforeach;
            					echo '</select>';
            				endif;
             
            				if( $terms2 = get_terms('sijoitusmuoto') ) : // to make it simple I use default categories
            					echo '<select name="sijoitusmuoto" id="sijoitusmuoto"><option>Sijoitusmuoto</option>';
            					foreach ( $terms2 as $term2 ) :
            						echo '<option value="' . $term2->term_id . '">' . $term2->term_id . '</option>'; // ID of the category as the value of an option
             
            					endforeach;
            					echo '</select>';
            				endif; ?>
             
             
            				<input class="haku-btn" type="submit" name="" onclick="cat_ajax_get_five('<?php echo $term->term_id; ?>');" value="Hae">
            			<!-- </form> -->
            			</form>
            add_action( 'wp_ajax_nopriv_load-filter-five', 'prefix_load_cat_posts_five' );
            	add_action( 'wp_ajax_load-filter-five', 'prefix_load_cat_posts_five' );
             
            	function prefix_load_cat_posts_five () {
            		$vaihto = $_POST['liikevaihto'];
            		$muoto = $_POST['sijoitusmuoto'];

            functions.php

            $tax_id = $_POST['liikevaihto'];
            		$tax_id2 = $_POST['sijoitusmuoto'];
            		if ($tax_id != 0 && $tax_id2 != 0) {
            			$args = array (
            				'term' => $tax_id,
            				'posts_per_page' => -1,
            				'post_type' => 'jasenet',
            				'post_status' => 'publish',
            				'order' => 'DESC',
            				'tax_query' => array(
            					'relation' => 'AND',
            						array(
            							'taxonomy' => 'liikevaihto',
            							'field'    => 'id',
            							'terms'    => $tax_id,
            							'operator' => 'IN'
            						),
            						array(
            							'taxonomy' => 'siojoitusmuoto',
            							'field'    => 'id',
            							'terms'    => $tax_id2,
            							'operator' => 'IN'
            						)
            				)
            			);
            		} else {
            			$args = array (
            				'posts_per_page' => -1,
            				'orderby' => 'date',
            				'post_type' => 'jasenet',
            				'post_status' => 'publish',
            				'order' => 'DESC'
            			);
            		}
             
            		$jasenquery = get_posts( $args );
            		global $post;
             
            		ob_start ();
             
            			$jasenquery = new WP_Query($args);

            jquery script

            function cat_ajax_get_five(taxID, taxID2) {
            		 $("#liikevaihto").change(function(){
            			var ajaxurl = '<?php echo admin_url( 'admin-ajax.php' ); ?>';
            			jQuery.ajax({
            				type: 'POST',
            				url: ajaxurl,
            				data: { action: "load-filter-five", "select": jQuery('#liikevaihto').val() },
             
            				success: function(response) {
            					jQuery("#jasen-content").html(response);
            					return false;
            				}
            			})
            		})
            	}

            if you or anyone has advice it would bee much appriciated. been struggling with this for too long already.

            thanks!

          • You jQuery code is incorrect – please look how it is implemented in the tutorial.

          • thanks for the reply!

            I changed the code as u suggested and the ajax processes as it should but its not calling the filter function in function.php. the content remains as it was.

            do you see any errors in this query?

            function misha_filter_function(){
            		$args['tax_query'] = array();
             
            		if( isset( $_POST['liikevaihto'] ) ) {
            			$args['tax_query'][] = array(
            				array(
            					'taxonomy' => 'liikevaihto',
            					'field' => 'id',
            					'terms' => $_POST['vaihto'],
            					'posts_per_page' => 2,
            				        'orderby' => 'date',
            				)
            			);
            		}
             
            		if( isset( $_POST['sijoitusmuoto'] ) ) {
            			$args['tax_query'][] = array(
            				array(
            					'taxonomy' => 'sijoitusmuoto',
            					'field' => 'id',
            					'terms' => $_POST['muoto'],
            					'posts_per_page' => 2,
            					'orderby' => 'date',
            					)
            				);
            		}
            		else {
            			$args = array(
            				'posts_per_page' => -1,
            				'orderby' => 'date',
            				'post_type' => 'jasenet',
            				'post_status' => 'publish',
            			);
             
            		}
                            $query = new WP_Query($args);
            //and so on 
             
                             wp_die();
            <form action="<?php echo site_url() ?>/wp-admin/admin-ajax.php" method="POST" id="filter">
             
             
            				<?php if( $terms = get_terms('liikevaihto') ) : // to make it simple I use default categories
            					echo '<select name="vaihto" id="liikevaihto"><option>Liikevaihto</option>';
            					foreach ( $terms as $term ) :
            						echo '<option value="' . $term->term_id . '">' . $term->term_id . '</option>'; // ID of the category as the value of an option
            					endforeach;
            					echo '</select>';
            				endif;
             
            				if( $terms2 = get_terms('sijoitusmuoto') ) : // to make it simple I use default categories
            					echo '<select name="muoto" id="sijoitusmuoto"><option>Sijoitusmuoto</option>';
            					foreach ( $terms2 as $term2 ) :
            						echo '<option value="' . $term2->term_id . '">' . $term2->term_id . '</option>'; // ID of the category as the value of an option
             
            					endforeach;
            					echo '</select>';
            				endif; ?>
             
            				<button class="haku-btn">Hae</button>
            				<input type="hidden" name="action"  value="myfilter">
             
            			</form>
          • okey i got the function to trigger now but the query is incorrect. im using the one you suggested but always skips to my else { }.

            $args['tax_query'] = array();
             
            if( isset( $_POST['selectbox1'] ) ) {
            	$args['tax_query'][] = array(
            		array(
            			'taxonomy' => 'TAXONOMY NAME 1',
            			'field' => 'id',
            			'terms' => $_POST['selectbox1']
            		)
            	);
            }
             
            if( isset( $_POST['selectbox2'] ) ) {
            	$args['tax_query'][] = array(
            		array(
            			'taxonomy' => 'TAXONOMY NAME 2',
            			'field' => 'id',
            			'terms' => $_POST['selectbox2']
            		)
            	);
            }

            can you see an error in this query?

            thanks misca!

          • THANK YOU MISHA!! YOU SAVED MY ASS!! GOT IT WORKING!

            Thank you so much!!!! if you want i can post the code here for the future if someone has the same problem that i do.?

          • I’m glad you’ve figured it out! πŸ™ƒ Sure, it would be great if you share your solution.

  • How can I get term_id dynamically in the misha_filter_function() funtion?

    I am using it on custom taxonomy archive page (in Custom Post Type). Please check code below

     
    $term_id = get_queried_object()->term_id;
     
    $params = array(
    		'posts_per_page' => $_POST['misha_number_of_results'], // when set to -1, it shows all posts
    'orderby' => $order[0], // example: date
    'order'	=> $order[1], // example: ASC
    'post_type' => 'custom',
    'tax_query'=> array(
        array('taxonomy' => 'custom-category', 
        'field' => 'term_id', 
        'terms' => $term_id, 
        'operator' => 'IN')
    );

    The above code is not working, but if i add term_id manually it works. But it is unable to get term id by its own. The reason for customizing above is, on custom taxonomy pages it is adding all posts in the loop while using filters.

    • Hi,

      You can add it with the $_POST array.

      • Thank you for the quick reply, but how can I get $_POST[‘term_id’] work inside misha_loadmore_ajax_handler(){} function and pass the value? I am talking about https://rudrastyh.com/wordpress/ajax-load-more-with-filters.html this article??

      • Somehow, I achieved this and now able to get the term_id misha_loadmore_ajax_handler(){} via ajax. Everything works fine the only problem is. It is duplicating the posts if we set the number of results through the per page filter.

      • how much posts it duplicates?

        • Same number of posts that are remaining in the loop. I’m simply trying to add a dropdown filter With a numeric meta field (custom post type, custom taxonomy). For example, if I set post per page to 5 and there are total 10 posts, first 5 post are loading correctly in queried order but after load more button click it load same 5 posts again. If I set post per page to 10, then it works perfectly.

        • I tested it a lot, but can’t figure it out. Your default code (twenty seventeen theme example) is also not working correctly. If we use filters the load more function doesn’t run correctly. Both works but only if we run them independently. (Ref: https://rudrastyh.com/wordpress/ajax-load-more-with-filters.html)

        • Hi Misha, On further digging I found that the loop parameter

          'query': misha_loadmore_params.posts

          is localizing/sending the default post query in all conditions. and in that case

          $params = json_decode( stripslashes( $_POST['query'] ), true );

          will take the default query only. I think this line is the main culprit

          misha_loadmore_params.posts = data.posts;

          and is not setting the new query parameters.

          So when we use the filter it works and create the queried loop, but the load more function is not getting that loop and taking only the default post lopp.

          Can you guide me how to fix this?

          • Hi again,

            Didn’t you forget to change the posts_per_page value in Settings > Reading as well?

            posts per page value

        • I have tried that setting also. The only problem is, when we use post per page and other filters and call it. On first page or load it loads correct posts but on second page it loads posts from default template query instead of my filter query. You just test your default codes you will notice this.

          • Finally, After digging it for 4 days. I got the solution (which was pretty simple)

            $params = json_decode( stripslashes( $_POST['query'] ), true );

            the above line is not inserting any query_vars set by our filter function. So it just keeps on showing posts from default loop for misha_loadmore_ajax_handler(){} function. The reason was

            $_POST['query']

            is returning a serilized form of data; not in JSON format. My fix is,

            $params = unserialize( stripslashes( $_POST['query']) );

            I am not sure, if above solution is the best. Please let me know if there could be any better solution?

          • I’m glad you’ve figured it out πŸ™ƒ But for me everything works good with json_decode() and json_encode() functions.

  • hi, I wondered how I can do multi-taxonomy filtering. thanks

  • Howdy Misha,

    Awesome tutorial! Well written and extreme helpful! πŸ™

  • Hello.
    First, what a beautiful tutorial, easier than a lot of other solution I crossed on the web.
    Secondly, I’m sorry but I’m not English , sorry in advance for my poor language ;)
    Thirdly , I’m not a Dev, or something like that, but I love puting my hands into the code and often I works :)

    I spent 10 years on Magento and only discover WordPress now…. Woua, easier.

    I have a question which is simple for you I think, and it’s more about PHP, or how to get data without a “loop”.

    Into the function file, in your exemple, you suggest to call the title, and it works fine.

    But me, I want to call a template part, with more data and PHP.

    I success, BUT, on frontend, it call the template into the template, as many time there’s a post.

    So it breaks all the HTML and I can’t manage the results.

    For EXEMPLE : if my template would be,

    <div class"exemple"><div>

    On front, I get this :

    <div class"exemple">data<div class"exemple">data<div class"exemple">data<div><div><div>

    How to call template as many time there is a result for post but with this displaying ?

    <div class"exemple"><div>
    <div class"exemple"><div>
    <div class"exemple"><div>
    <div class"exemple"><div>
    <div class"exemple"><div>
    ...

    MANY MANY THANKS :)

    • Hi,

      Everything depend on the template part you include πŸ™ƒ

      Usually, while working with get_template_part() I recommend yo use query_posts() function instead WP_Query().

      If the HTML structure is only issue you faced, you can add the closing/opening div element manually like this:

      // loop begins
      while( have_posts() ):
       
      	// your template
      	get_template_part( .... );
      	echo '</div>'; // this line
       
      endwhile;
      // loop ends
  • Hello Misha,

    I’m back again with a little question.
    I red all the comments before on your article, spent a lot of time by myself searching on the web, trying things… before disturb you again.

    I saw that others already tried to use two filters and I did it, it works fine :)

    My little problem is, when I want to get only one filter, if one post isset and the other empty.

    I think I’m didn’t have the php skills and I’m sorry.

    Here’s the last code I’ve tried / you probably gonna laugh ;)

     
    // for taxonomies / if destinations and activities are set
    	if( isset( $_POST['categoryfilter'] ) && isset ($_POST['activitefilter'])  ) {
    		$args['tax_query'] = array(
     
    		'relation' => 'AND',
     
    			array(
    				'taxonomy' => 'destination',
    				'field' => 'id',
    				'terms' => $_POST['categoryfilter']
    			),
    			array(
    				'taxonomy' => 'activite',
    				'field' => 'id',
    				'terms' => $_POST['activitefilter']
    			),
    		);
     
     
    	} else {
    	if( isset( $_POST['categoryfilter']) || !empty( $_POST['activitefilter'] ) )// for taxonomies / only destinations are set
    		$args['tax_query'] = array(
    				'taxonomy' => 'destination',
    				'field' => 'id',
    				'terms' => $_POST['categoryfilter']
    		);
    	if( !empty( $_POST['categoryfilter']) || isset( $_POST['activitefilter'] ) )// for taxonomies / only activities are set
    		$args['tax_query'] = 
    			array(
    				'taxonomy' => 'activite',
    				'field' => 'id',
    				'terms' => $_POST['activitefilter']
    		);
     
    	}

    And, little “bonus question”. Did someone already ask about dynamics fields ? For exemple, if one activity is selected, display only destinations with results.

    I think it would be hard to have this behaviour ?

    • Hi,

      There should be an answer somewhere in comments, but I don’t remember where πŸ™ƒ

      So, here is the tip:

      // first of all before filtering define the empty tax_query
      $args['tax_query'] = array();
       
      // or with relation
      $args['tax_query'] = array( 'relation' => 'AND' );
       
      // after that when you begin filtering it, add elements to array with
      // $args['tax_query'][] = 'NEW ELEMENT';
      // example: 
      $args['tax_query'][] = array(
      	'taxonomy' => 'activite',
      	'field' => 'id',
      	'terms' => $_POST['activitefilter']
      );

      Bonus answer: No. And there is no short answer unfortunately.

      • Hello Misha,

        First of all, thank you very much for your answer.

        I read carefully again all the comments but didn’t see any solution.

        Just to be sure, I don’t have a lot of skills in developpement, what you gave me is kind of theory ?

        I have to complete much of the code ?

        I’ve tried a lot of things but I’m not sure to understand how to modify my previous code into your new one.

        Well I understand that you are not paid for all this help, that it takes time for you… if it’s too complicated to help me on this point, I will try to another solution :)

        But if I find a solution, I’ll post it here for everyone :)

        Thanks again.

      • MishaAuthor January 11, 2018 at 16:39

        Hello,

        Strange, in fact I gave you the ready code πŸ™ƒ
        If you still didn’t resolve your problem, you can contact me by email (via Contact page).

  • Sadly, pagination doesn’t work with this. It loads the original query instead of the AJAX query.

  • This is a great tutorial. Thank you so much. It works great. Wondering if you have any ideas on how to make a “clear filters” button, so the filters are reset to null and all the posts show.

    • MishaAuthor January 11, 2018 at 18:59

      Thank you! πŸ™ƒ

      Sorry I removed your comment with code because it seems very unclear for me.

      Here is step by step tip how to implement a “clear filters” button.

      Step 1. Create a Clear Filters button

      Let’s suppose that you would like to add it inside the <form> element. In this case you have to use <a> HTML tag as a button.

      <a href="" id="clear">Clear</a>

      Step 2. Trigger the Event

      It is about jQuery code. I used selectors and element IDs like in my tutorial. Add it inside jQuery(function($){ ... });

      $('#clear').click(function(){
       
      	// reset each field
      	// empty the values of fields with
      	// but you can set a default value in .val('') method
      	$('#my_field').val(''); // by ID selector
      	$('select[name="categoryfilter"]').val(''); // or by name selector
       
      	// optionally: let's sumbit the filter form
      	$('#filter').submit();
       
      	// do not refresh the page after the link is clicked
      	return false;
      });
  • Thank you for the great tutorial. I managed to get it working but when I filter my custom post type query the pagination doesn’t work. Instead all the navigation page links point to http://www.mysite.com/wp-admin/admin-ajax.php. Also, just to note that because

    wp_pagenavi( array( 'query' => $myquery ) );

    was not working (I use GeneratePress free theme) I has to install the Pagenavi plugin.
    Is there an easy way to fix the pagination issue or do I have to do mind-boggling code workarounds like rewriting permalinks and stuff like that. I’m on a tight deadline here and have tried everything I can think of.

    • I have the same issue, trying to use wp_pagenavi.
      Someone can help?

    • MishaAuthor January 17, 2018 at 00:30

      Hi,

      Because it is the AJAX filter, it is not supposed to be a pagination here.

      But if you really need it, I recommend you to look at the similar situation with pagination in this tutorial.

      • Misha I tried to use the code from the “Load More Posts Button + Numeric Pagination” tutorial for a query with a custom post type (inside a page template) with ajax filters but never managed to get it working even without the filters. Are you saying that is is possible to get a working pagination (with your custom pagination function) even after an ajax filter is clicked and the custom query has changed? Does the pagination have to be ajax based? I can’t see how the pagination links will work (www.mysite.com/pagetemplate/page/2) after an ajax filter has been applied meaning that the custom query will have changed.

  • Tran Trong Nhan January 17, 2018 at 10:49

    How to automatically paging auto loadmore after searching…combined with this article(https://rudrastyh.com/wordpress/load-more-posts-ajax.html). Please help me. Thank you very much!

    • MishaAuthor January 19, 2018 at 00:06

      Hi,

      Did you try this tutorial?

      • Tran Trong Nhan January 19, 2018 at 04:31

        I followed this tutorial: https://rudrastyh.com/wordpress/ajax-load-more-with-filters.html , but with custom post type (cuisines), everything looks OK, after searching the result is exactly what I want, but when paging is loading more to next page then load data is the data of the post (Post Type), not of the custom post type (cuisne type). Can not load next page’s data!

        This is the function I have changed:

        <?php
         
        function misha_script_and_styles() {
         
             // register our main script but do not enqueue it yet
             wp_register_script( 'misha_scripts', get_stylesheet_directory_uri() . '/js/myloadmore.js', array('jquery') );
         
             // now the most interesting part
             // we have to pass parameters to myloadmore.js script but we can get the parameters values only in PHP
             // you can define variables directly in your HTML but I decided that the most proper way is wp_localize_script()
             wp_localize_script( 'misha_scripts', 'misha_loadmore_params', array(
               $args = array(
                 'post_type' => 'cuisines',
                 'posts_per_page' => 8,
                 'orderby' => 'date',
                 'order' => 'DESC',
               ),
               'ajaxurl' => site_url() . '/wp-admin/admin-ajax.php', // WordPress AJAX
               'posts' => json_encode( $args ), // everything about your loop is here
               'current_page' => get_query_var( 'paged' ) ? get_query_var('paged') : 1,
               'max_page' => $wp_query->max_num_pages
             ) );
         
             wp_enqueue_script( 'misha_scripts' );
           }
         
           add_action( 'wp_enqueue_scripts', 'misha_script_and_styles');
         
         
           function misha_loadmore_ajax_handler(){
         
           // prepare our arguments for the query
             $params = json_decode( stripslashes( $_POST['query'] ), true ); // query_posts() takes care of the necessary sanitization 
             $params['paged'] = $_POST['page'] + 1; // we need next page to be loaded
             $params['post_status'] = 'publish';
         
             // it is always better to use WP_Query but not here
             query_posts( $params );
         
             if( have_posts() ) :
         
               // run the loop
               while( have_posts() ): the_post();
                 get_template_part( 'template-parts/cuisine/content', get_post_format() ); 
               endwhile;
         
             endif;
             die; // here we exit the script and even no wp_reset_query() required!
           }
         
         
         
           add_action('wp_ajax_loadmorebutton', 'misha_loadmore_ajax_handler');
           add_action('wp_ajax_nopriv_loadmorebutton', 'misha_loadmore_ajax_handler');
         
         
           function misha_filter_function(){
             $args = array(
               'post_type' => 'cuisines',
               'posts_per_page' => 8,
               'orderby' => 'date', // we will sort posts by date
               'order' => $_POST['date'] // ASC ΠΈΠ»ΠΈ DESC
             );
         
             // for taxonomies / cuisine_type
             if( isset( $_POST['cuisinetype'] ) || isset( $_POST['cuisinetag'] ) )
               $args['tax_query'] = array(
                 array(
                   'taxonomy' => 'cuisine_type',
                   'field' => 'id',
                   'terms' => $_POST['cuisinetype'],
                 ),
                 array(
                   'taxonomy' => 'cuisine_tag',
                   'field' => 'id',
                   'terms' => $_POST['cuisinetag'],
                 )
               );
             // if post thumbnail is set
             if( isset( $_POST['featured_image'] ) && $_POST['featured_image'] == 'on' )
               $args['meta_query'][] = array(
                 'key' => '_thumbnail_id',
                 'compare' => 'EXISTS'
               );
         
             query_posts( $args );
             global $wp_query;
             if( have_posts() ) :
               ob_start();
               while( have_posts() ): the_post(); 
                 get_template_part( 'template-parts/cuisine/content', get_post_format() ); 
               endwhile;
               $posts_html = ob_get_contents(); // we pass the posts to variable
               ob_end_clean(); // clear the buffer
             else :
               $posts_html = '<p>Nothing found for your criteria.</p>';
             endif;
             echo json_encode( array(
               'posts' => serialize( $wp_query->query_vars ),
               'max_page' => $wp_query->max_num_pages,
               'found_posts' => $wp_query->found_posts,
               'content' => $posts_html
             ) );
             die();
           }
         
           add_action('wp_ajax_mishafilter', 'misha_filter_function'); 
           add_action('wp_ajax_nopriv_mishafilter', 'misha_filter_function');

        Can you help me. Thanks very much!

Leave your question or feedback

phpjsHTMLCSSSQLCode
Please, enter a comment
Please, enter a name
Incorrect email