Skip Navigation

[Resolved] Taxonomy Archives for Product Categories with AJAX – change posts per page

This support ticket is created 4 years, 2 months ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Sun Mon Tue Wed Thu Fri Sat
9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 - - 9:00 – 13:00
14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 - - 14:00 – 18:00

Supporter timezone: Africa/Casablanca (GMT+01:00)

This topic contains 18 replies, has 2 voices.

Last updated by umbertoZ 4 years, 1 month ago.

Assisted by: Jamal.

Author
Posts
#1790417

Hi, I've a Taxonomy Archives for Product Categories with AJAX custom search, pagination and sorting menu.

I've added buttons to change the pagination number of items per page. For example "Display 10 items per page", "Display 20 items per page", "Display 50 items per page". I've added a parameter to the href of the buttons like:

mydomain.com/category-prod/?pager=10
mydomain.com/category-prod/?pager=20
mydomain.com/category-prod/?pager=50

Then I added this Custom code:

add_filter('pre_get_posts','func_include_child_terms',999);
function func_include_child_terms( $query ) {

  if (isset($_GET['pager'])) {
    
    $pager = $_GET['pager'];
    
    if (!is_admin() && $query->is_main_query() and  $query->is_tax( 'product_cat' ) ) {
      log_me('product_cat');
      $query->set( 'posts_per_page', $pager );
    }
    
  }
  return $query;
}

It works fine, but when I select some search filter, I change the order or I click on pagination links, it doesn't lose the 'pager' parameter, but the php code doens't work.

If I turn off AJAX and I reload the page it works fine.

Is there a way to trigger the php code with AJAX?

I also tested with a simpler code without 'pager' parameter:

add_filter('pre_get_posts','func_include_child_terms',999);
function func_include_child_terms( $query ) {
    
    if (!is_admin() && $query->is_main_query() and  $query->is_tax( 'product_cat' ) ) {
      log_me('product_cat');
      $query->set( 'posts_per_page', 10 );
    }
    
  return $query;
}

But it still doesn't work with AJAX.

thanks
cheers

#1791179

Hello and thank you for contacting the Toolset support.

To better assist you with this issue, I prepared a test site on our platform, and I hope you would like to reproduce this issue on it.
To login, use this one-click-login URL hidden link

Please create a couple of posts and the Toolset archive, and add your custom code. I'll take it from there and check why is this code not working.

#1791279

Hi Jamal, I made a quick attempt to set up the environment on your platform, but I'd prefer you check my staging website, because there I'm working with WooCommerce and Views. I shoudl install both and setup products, etc. to create a similar environment.

Can I send you credentials in a private message?

thanks

#1793775

Hi Jamal, I hope you can take care of this issue soon. Please, open a private message so I can send you credentials.

cheers

#1793853

Sure! Your next reply will be private. ** Please make a database backup before sharing credentials. **

#1794587

I am not sure if I missed something, but it seems that the custom code is working on this category archive: /professional-video/professional-video-cameras/

Check the following screenshots, for every possible value(10,25,50) it returned the correct number of results:
- Pager=50: hidden link
- Pager=25: hidden link
- Pager=10: hidden link

I wonder if am I missing something?

#1794629

Yes, it works with pagination and page reload.

But if you activate AJAX and you also test sorting and search after you click Pager=25, you will see you lose the desired pagination.

cheers

#1794633

So, I choose pager=25, then I filtered by the brand name "Canon" which has 12 posts, using AJAX, but I could not notice the issue. Then I sorted by price, in both directions, and by brand name(just to trigger the AJAX reload) and I was not able to notice any issue. The pager remained at 25 posts per page.

Can you give step-by-step how I can reproduce the issue? Preferably in a way like:
1. I go to xxx
2. I do xxx, xxx, then xxx
3. I expect to have xxx
4. Instead I get xxx

#1794657
step5.PNG
step4.PNG
step3.PNG
step2.PNG
step1.PNG

Ok,

1. I go to /professional-video/professional-video-cameras/ (now I set the View pagination to 5 items per page and I also added [wpv-items-count]/[wpv-found-count] on the top of the sidebar - image step1.png I attach)
2. I click on display 10 items per page and I get the correct result (image step2.png).
3. Then I click on 3rd page of the pager (AJAX reload) and I get again 5 items per page instead of 10 (image step3.png).
4. If I repite step 2 and then change the sorting criteria, I get again 5 items per page instead of 10 (image step4.png).
5. If I repite step 2 and then I select a filter criteria, I get again 5 items per page instead of 10 (image step5.png).

#1795471

Thank you very much, that's clear enough and I can see the issue now.

It turns out that the custom code that you are using is not optimized for AJAX. It will work for page reloads, because the pager=10 will be available on the URL, and the code gets it from "$_GET['pager']".
But when the AJAX call is made, it is made using a POST request, instead of a GET request, hence "$_GET['pager']" will not be set. And the default pager will be used. So, you will need to rely on something else to get the pager number on AJAX calls.

- Either, you can rely on the "referer". Check this screenshot hidden link and check this online thread https://wordpress.stackexchange.com/questions/84430/get-url-parameters-from-referer
- Or you need to integrate into the AJAX call and add the pager value to the POST array, then rely on it on your custom code. Read more about the beforeSend callback on this page hidden link

I hope this makes sense. Let me know if you have any questions.

#1795813

Hi Jamal, thnaks for the suggestions. I tried this code to get the pager param:

add_filter('pre_get_posts','func_include_child_terms',999);
function func_include_child_terms( $query ) {
 
  $url = wp_get_referer();
  $path = parse_url($url, PHP_URL_QUERY);
  parse_str($path, $params);  
    
    
    $pager = $params['pager'];
    
    if (!is_admin() && $query->is_main_query() and  $query->is_tax( 'product_cat' ) ) {
      log_me('product_cat');
      $query->set( 'posts_per_page', $pager );
    }
    
  return $query;
}

I expect it works fine when I load the url /professional-video/professional-video-cameras/?pager=10 on my browser, but it doens't work and I get

Notice: Undefined index: pager in /home/proavgetseenonli/public_html/wp-content/toolset-customizations/toolset-custom-code.php on line 112

Can you help me with an example of how I should set up the cistom code? Or an example of the jquery.ajax?

thanks

#1795843

This last code does not handle the case of page reloads, it does handle the AJAX case though.

Try this code:

add_filter('pre_get_posts','func_include_child_terms',999);
function func_include_child_terms( $query ) {
  // this part will handle a full page reload
  if (isset($_GET['pager'])) {
     
    $pager = $_GET['pager'];
     
    if (!is_admin() && $query->is_main_query() and  $query->is_tax( 'product_cat' ) ) {
      log_me('product_cat');
      $query->set( 'posts_per_page', $pager );
    }
     
  } else { // This part will handle AJAX calls
  $url = wp_get_referer();
  $path = parse_url($url, PHP_URL_QUERY);
  parse_str($path, $params);  
     
    $pager = $params['pager'];
     
    if (!is_admin() && $query->is_main_query() and  $query->is_tax( 'product_cat' ) ) {
      log_me('product_cat');
      $query->set( 'posts_per_page', $pager );
    }
     }
  return $query;
}

Hopefully, there is no typo there that could break the code.

#1795847

Hi Jamal, thanks for the code, but it still doesn't work. I works on full page reload but not on AJAX call.

I've to say that, if it would be possible to trigger the AJAX call when I click on the display 10 items button, instead of a full page reload, it would be great. But first it is important it works fine with the current set up.

cheers

#1795919

I think that my code is not correct and will fail in some cases. I am sure, you will understand, that's not easy to produce code without testing 🙂

Please try this code:

add_filter('pre_get_posts','func_include_child_terms',999);
function func_include_child_terms( $query ) {
  // this part will handle the AJAX call
  if (isset($_POST['action'])) {
  $url = wp_get_referer();
  $path = parse_url($url, PHP_URL_QUERY);
  parse_str($path, $params);  
      
    $pager = isset($params['pager']) ? $params['pager'] : 5; // if no pager is provided, take the default one 5
      
    if (!is_admin() && $query->is_main_query() and  $query->is_tax( 'product_cat' ) ) {
      log_me('product_cat');
      $query->set( 'posts_per_page', $pager );
    }
  } elseif (isset($_GET['pager'])) {
    $pager = $_GET['pager'];
      
    if (!is_admin() && $query->is_main_query() and  $query->is_tax( 'product_cat' ) ) {
      log_me('product_cat');
      $query->set( 'posts_per_page', $pager );
    }
      
  }
  return $query;
}

Please note, that this code will assume that the default pager is 5, otherwise, you will need to update this line:

    $pager = isset($params['pager']) ? $params['pager'] : 5;

If this code does not work, I'll need to run tests. Let me know if that's possible.

I've to say that, if it would be possible to trigger the AJAX call when I click on the display 10 items button
This will need some Javascript code, that will prevent the page from reloading and trigger the AJAX reload.
We may work on this later, on a new ticket.

#1795953

Hi, I'm sorry but it still doesn't work.
I made a test. I haven't changed the View items per page settings (still 5) and I've changed this line to 6:

$pager = isset($params['pager']) ? $params['pager'] : 6;

When AJAX realoads I still get 5 items. It seems AJAX is not triggering the function.

cheers