K
K
Keit2652020-07-19 18:31:44
WordPress
Keit265, 2020-07-19 18:31:44

Filtering by multiple taxonomies and pagination?

Now I have custom programs displayed in functions as follows:

add_action('wp_ajax_myfilter', 'misha_filter_function'); // wp_ajax_{ACTION HERE} 
add_action('wp_ajax_nopriv_myfilter', 'misha_filter_function');
 
function misha_filter_function(){
  $args = array(
    'orderby' => 'date', // we will sort posts by date
    'order'	=> $_POST['date'] // ASC or DESC
  );
 
  // for taxonomies / categories
  if( isset( $_POST['level'] ) )
    $args['tax_query'] = array(
      array(
        'taxonomy' => 'level',
        'field' => 'id',
        'terms' => $_POST['level']
      )
    );
    
  
 
  // 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'
    );
  // if you want to use multiple checkboxed, just duplicate the above 5 lines for each checkbox
 
  $query = new WP_Query( $args );
 
  if( $query->have_posts() ) :
    while( $query->have_posts() ): $query->the_post(); ?>
      <div class="program-main">
        // Какой-то контент
      </div>
      <?php
    endwhile;
    wp_reset_postdata();
  else : ?>
    <div class="card-no-result">
      <h2>Нет подходящей программы?</h2>
      <p>Напишите нам об этом и мы придумаем для вас индивидуальное  решение.</p>
      <a class="btn popup-call" href="#modal">Получить решение</a>
    </div> 
    <?php
  endif;
 
 
  die();
}

The form (not all, because it will take up a lot of space, taxonomies are repeated there) with the help of which we select the desired taxonomy and after clicking, the code in functions is executed:
<form action="<?php echo site_url() ?>/wp-admin/admin-ajax.php" method="POST" id="filter">
  <div class="simple-filter_item button-group filters">
    <p class="rus">Уровень подготовки</p>
    <?php
    $categories = get_terms('level', 'orderby=name&hide_empty=0');
    if($categories){
      echo '<select name="level" id="level1"><option value="card-item">Любой</option>';
      foreach ($categories as $cat){
        echo "<option value='{$cat->term_id}'>{$cat->name}</option>";
      }
      echo '</select>';
    }
    ?>
  </div>
  <div class="simple-filter_item">
    <p>Направление образования</p>
    <?php
      $categories = get_terms('direction', 'orderby=name&hide_empty=0');
      if($categories){
        echo '<select name="direction" id="direction1"><option value="card-item">Любое</option>';
        foreach ($categories as $cat){
          echo "<option value='direction-{$cat->term_id}'>{$cat->name}</option>";
        }
        echo '</select>';
      }
    ?>
  </div>
  <div class="filter-button filter-disactive">
    <div class="simple-btn">
      <button class="btn_access func-during">Подобрать</button>
      <input type="hidden" name="action" value="myfilter">
    </div>
  </div>
</form>

Well, a script with which I can specify that after clicking on the button, the form should be processed and displayed in the required div with id = card-wrapper-first:
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("Подобрать"); // changing the button label back
        $("#card-wrapper-first").html(data); // insert data
      },
    });
    return false;
  });
});

Let's summarize everything: how can a function from functions.php be redone so that programs are filtered not using one taxonomy (level of training), but taking into account others too (I indicated only 2 here, but in fact there are 5 of them). And how can I make pagination so that they are not displayed all at once, because there can be more than 200, but only 30 on one page

. Many thanks in advance for your patience and help!

Answer the question

In order to leave comments, you need to log in

1 answer(s)
P
Pavel Chesnokov, 2020-07-20
@cesnokov

if( isset($_POST['level']) && isset($_POST['direction']) ) {
    $args['tax_query'][] = array(
        'relation' => 'AND'
    );
}

if( isset($_POST['level']) ) {
    $args['tax_query'][] = array(
        array(
            'taxonomy' => 'level',
            'field' => 'id',
            'terms' => $_POST['level']
        )
    );
}

if( isset($_POST['direction']) ) {
    $args['tax_query'][] = array(
        array(
            'taxonomy' => 'direction',
            'field' => 'id',
            'terms' => $_POST['direction']
        )
    );
}

Pagination:
$paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
$args = array(
    'orderby' => 'date', // we will sort posts by date
    'order' => $_POST['date'], // ASC or DESC
    'posts_per_page' => 30,
    'paged' => $paged
);

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question