Using ajax to create a filter selector for WooCommerce products

时间:2016-07-11 19:12:24

标签: php jquery ajax wordpress woocommerce

I want to create an ajax filter selector for WooCommerce products, without any plugins.

But I don't know how to approach this problem.

I have this list of product with the dropdown to select the kind of filter:

screenshot of shop page

I use this code to show the list:

<?php wc_get_template_part( 'list', 'product' ); ?>

I know that the <div> class that I have to replace is '.products', but I have to change the $post to change the attribute by low price , hight price or alphabetical orden, and I don't find any solution.

This is my function to change the div when I select a element when I change the dropdown

$('#filter_paradise').change ->
  valor = $('#filter_paradise option:selected').val()
  changepost(valor)
  return

when I change the dropdown I call changepost function with the select value, this function replace the div with the new value, but before that, call to filter_product function

changepost = (valor) ->
  value = valor
  request = $.ajax(
    url: ajax_object.ajax_url
    method: 'POST'
    data:
      opc: value
      action: 'filter_product'
      dataType: "json"
    success: (html, data) ->
      #$('.products').replaceWith(html); 
      console.log 'change'
      return
    error: (errorThrown) ->
      console.log errorThrown
      return
  )
  return 

This function is in function.php, in this function I have there values, the country, the category and the value select by the filter I need this values to create the query and order by low price, hight price or alphabetical

function filter_product(){
  $last_uri = explode('/', $_SERVER['HTTP_REFERER']);
  $country = $last_uri[6];
  $getcategoria = explode('=',$last_uri[7]);
  $categoria = $getcategoria[1];
    $args = null;
  echo json_encode($categoria);
  exit();

}

Before to $('.products').replaceWith(html); in changepost function

I have to change the $args in:

$wp_query = new WP_Query( $args );

The div that I have to replace is in <?php wc_get_template_part( 'list', 'product' ); ?> this partial is in archive-product.php this view is like this.

<?php woocommerce_product_loop_start(); ?>
<?php woocommerce_product_subcategories(); ?>

<?php while ( have_posts() ) : the_post(); ?>

  <div class="col-xs-12">
    <div class="elementos_lista">
      <ul>
        <li>
          <?php wc_get_template_part( 'list', 'product' ); ?>
        </li>
      </ul>
    </div>
  </div>
  <?php //wc_get_template_part( 'content', 'product' ); ?>
<?php endwhile; // end of the loop. ?>

<div class="map_paradise"></div>

and before to execute the loop I have to get a new $args to the query with the new parameters, order by price or alphabetical.

What I am doing wrong?
Is there an other way to do that?

Any idea to point me on the right direction is welcome.

Thanks.

1 个答案:

答案 0 :(得分:3)

最后我创建了一个Filter,这是我的解决方案

我创建了我的下拉列表

<div class="filter_paradise">
    <div class="col-xs-12">
      <select id="filter_paradise" class="form-control">
        <option value="0">Alphabetical</option>
        <option value="1">High Price</option>
        <option value="2">Low Price</option>
      </select>
    </div>
</div> 

当我的下拉列表发生变化时,我会调用此函数

$('#filter_paradise').change ->
  valor = $('#filter_paradise option:selected').val()
  changepost(valor)
  return

changepost = (valor) ->
  value = valor
  request = $.ajax(
    url: ajax_object.ajax_url
    method: 'POST'
    data:
      opc: value
      action: 'filter_product'
      dataType: "json"
    success: (html, data) ->
      $('.products').replaceWith(html); 
      console.log 'change'
      return
    error: (errorThrown) ->
      console.log errorThrown
      return
  )
  return 

最后我在function.php中调用函数filter_product来改变我的div

function filter_product(){
  $select_opc = $_POST['opc'];
  $last_uri = explode('/', $_SERVER['HTTP_REFERER']);
  $country = $last_uri[4];
  $getcategoria = explode('=',$last_uri[5]);
  $categoria = $getcategoria[1];
  // var_dump($last_uri);
  // var_dump($categoria);
  // var_dump($country);
  wp_reset_query();

  if (!empty($categoria)):
    switch ($select_opc) {
      case 0:
        $args = array( 
        'post_type'           => 'product',
        'post_status'         => 'publish',
        'posts_per_page'      =>  -1,
        'orderby'             => 'title',
        'order'               => 'ASC',
        'product_cat'         => $categoria,
        'tax_query'           => array(
            array(
            'taxonomy'        => 'pa_country',
            'terms'           => $country,
            'field'           => 'name',
            //'operator'        => 'IN'
            )
          )
        );
        break;
      case 1:
        $args = array( 
        'post_type'           => 'product',
        'post_status'         => 'publish',
        'posts_per_page'      =>  -1,
        'meta_key'            => '_price',
        'orderby'             => 'meta_value_num',
        'order'               => 'DESC',
        'product_cat'         => $categoria,
        'tax_query'           => array(
            array(
            'taxonomy'        => 'pa_country',
            'terms'           => $country,
            'field'           => 'name',
            //'operator'        => 'IN'
            )
          )
        );
        break;
      case 2:
        $args = array( 
        'post_type'           => 'product',
        'post_status'         => 'publish',
        'posts_per_page'      =>  -1,
        'meta_key'            => '_price',
        'orderby'             => 'meta_value_num',
        'order'               => 'ASC',
        'product_cat'         => $categoria,
        'tax_query'           => array(
            array(
            'taxonomy'        => 'pa_country',
            'terms'           => $country,
            'field'           => 'name',
            //'operator'        => 'IN'
            )
          )
        );
        break;
      default:
        # code...
        break;
    }
    else:
      switch ($select_opc) {
        case 0:
          $args = array( 
          'post_type'           => 'product',
          'post_status'         => 'publish',
          'posts_per_page'      =>  -1,
          'orderby'             => 'title',
          'order'               => 'ASC',
          'product_cat'         => $country
          );
          break;
        case 1:
          $args = array( 
          'post_type'           => 'product',
          'post_status'         => 'publish',
          'posts_per_page'      =>  -1,
          'meta_key'            => '_price',
          'orderby'             => 'meta_value_num',
          'order'               => 'DESC',
          'product_cat'         => $country
          );
          break;
        case 2:
          $args = array( 
          'post_type'           => 'product',
          'post_status'         => 'publish',
          'posts_per_page'      =>  -1,
          'meta_key'            => '_price',
          'orderby'             => 'meta_value_num',
          'order'               => 'ASC',
          'product_cat'         => $country
          );
          break;
        default:
          # code...
          break;
      }
    endif;
  $the_query = new WP_Query( $args );

  $salida = '<ul class="products">';
    $salida .= '<div class="col-xs-12">';
      $salida .= '<div class="elementos_lista">';
        $salida .= '<ul>';
        if ( $the_query->have_posts() ) :
          while ( $the_query->have_posts() ) : $the_query->the_post();
            $salida .= '<li>'; 
            $product_thumbnail_url = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'thumbnail');
            $url = get_permalink();
            $salida .='<a href="'. get_permalink() .'">';
            $salida .= '<div class="row list_product_paradise">';
            if ($product_thumbnail_url):
              $salida .= '<div class="col-xs-2 image_product_thumbnail">';
              $salida .= '<img src="'. $product_thumbnail_url[0] .'" class="img-responsive" alt="'.get_the_title() .'">';
              $salida .= '</div>';
              $salida .= '<div class="product_cat col-xs-7">';
              $salida .= get_the_title();
              $salida .=  '</div>';
            else:
              $salida .= '<div class="product_cat col-xs-9">';
              $salida .= get_the_title();
              $salida .=  '</div>';
            endif;
            $salida .='<div class="total_items col-xs-3">';
            $salida .=  get_post_meta( get_the_ID(), '_regular_price', true);
            $salida .=  '</div>';
            $salida .=  '</div>';
            $salida .=  '</a>';
            $salida .= '</li>'; 
          endwhile;
        endif;
        $salida .=  '</ul>';
      $salida .=  '</div>';
    $salida .=  '</div>';
  $salida .=  '</ul>';
  $salida .= '<div class="map_paradise"></div>';
  echo $salida;
  exit();

}

  add_action( 'wp_ajax_filter_product', 'filter_product' );    // If called from admin panel
  add_action( 'wp_ajax_nopriv_filter_product', 'filter_product' );    // If called from front end