Как заставить select правильно работать в фильтре таксономии ajax?

#ajax #wordpress #woocommerce #hook-woocommerce #woocommerce-theming

Вопрос:

Я использую ajax-фильтрацию таксономии. Я основал его давным — давно и изменил для себя-свой собственный html и стиль, заставил его работать со многими другими сценариями. Но теперь мне нужно сделать собственный заказ woocommerce, выбрав его часть. Я добавил его двумя способами — как функцию woocommerce_catalog_ordering(), а также как чистый html, но он отлично работает только на первой странице после фильтрации, на второй странице сортировка уже некорректна. Установка виджета

 function cosmetic_init_widgets() {  register_widget('cosmetic_Filter_Widget'); } add_action('widgets_init', 'cosmetic_init_widgets');  //Woo Filter function cosmetic_show_products(){   $query_data = $_GET;    $paged = (isset($query_data['paged']) ) ? intval($query_data['paged']) : 1;  $pages = $wp_query-gt;max_num_pages;   $orderby = 'date';  $orderby = $query_data['order'];  $posts_per_page = get_option('woocommerce_catalog_columns') * get_option('woocommerce_catalog_rows');   //filter by category id  $cats = ($query_data['category']) ? explode(',',$query_data['category']) : false;  $pa_color = ($query_data['pa_color']) ? explode(',',$query_data['pa_color']) : false;  $pa_size = ($query_data['pa_size']) ? explode(',',$query_data['pa_size']) : false;    $tax_query_cat = ($cats) ? array( array(  'taxonomy' =gt; 'product_cat',  'field' =gt; 'id',  'terms' =gt; $cats  ) ) : false;  $tax_query_pa_color = ($pa_color) ? array( array(  'taxonomy' =gt; 'pa_color',  'field' =gt; 'id',  'terms' =gt; $pa_color  ) ) : false;  $tax_query_pa_size = ($pa_size) ? array( array(  'taxonomy' =gt; 'pa_size',  'field' =gt; 'id',  'terms' =gt; $pa_size  ) ) : false;  $args = array(  'post_type' =gt; ['product_variation','product'],  'paged' =gt; $paged,  'posts_per_page' =gt; $posts_per_page,  'tax_query' =gt; array(  'relation' =gt; 'AND',  $tax_query_cat,  $tax_query_pa_color,  $tax_query_pa_size  ),  'meta_query' =gt; array(  array(  'key' =gt; '_price',  'value' =gt; array($query_data['min'], $query_data['max']),  'compare' =gt; 'BETWEEN',  'type' =gt; 'NUMERIC'  ),  ),  );    switch ( $orderby ) {  case 'date':  $args['orderby'] = 'date';  //$args['meta_key'] = 'date';  $args['order'] = 'desc';  break;  case 'price':  $args['orderby'] = 'meta_value_num';  $args['meta_key'] = '_price';  $args['order'] = 'asc';  break;  case 'price-desc':  $args['orderby'] = 'meta_value_num';  $args['meta_key'] = '_price';  $args['order'] = 'desc';  break;  case 'popularity':  $args['orderby'] = 'meta_value_num';  $args['meta_key'] = 'total_sales';  $args['order'] = 'desc';  break;  case 'rating':  $args['orderby'] = 'meta_value_num';  $args['meta_key'] = '_wc_average_rating';  $args['order'] = 'desc';  break;  }    $loop = new WP_Query( $args );  if ( $loop-gt;have_posts() ) {?gt;  lt;div class="mb-20 justify-content-center d-flex"gt;  lt;a href="lt;?php echo $filterreset; ?gt;" class="reset-filter"gt;lt;?php echo get_theme_mod('reset_filter_text');?gt;lt;/agt;  lt;/divgt;   lt;?php     woocommerce_product_loop_start();  while ( $loop-gt;have_posts() ) : $loop-gt;the_post();  wc_get_template_part( 'content', 'product' );  endwhile;   woocommerce_product_loop_end();  ?gt;  lt;div class="mt-20 justify-content-center d-flex d-lg-none"gt;  lt;a href="lt;?php echo $filterreset; ?gt;" class="reset-filter"gt;Сбросить фильтрlt;/agt;  lt;/divgt;    lt;nav class="woocommerce-pagination"gt;  lt;?php if($loop-gt;max_num_pages gt; 1){ ?gt;      lt;?php   //Pagination  $big = 999999999; // need an unlikely integer   $pages = paginate_links( array(  'base' =gt; str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),  'format' =gt; '?paged=%#%',  'current' =gt; max( 1, $paged ),  'prev_text' =gt; 'amp;larr;',   'next_text' =gt; 'amp;rarr;',  'first_page_text' =gt; '« ',   'last_page_text' =gt; ' »',   'total' =gt; $loop-gt;max_num_pages,  'type' =gt; 'array',  ) );  if( is_array( $pages ) ) {  $paged = ( $paged == 0 ) ? 1 : $paged;  echo 'lt;ul class="ajax-page-numbers"gt;';  foreach ( $pages as $page ) {  echo "lt;ligt;$pagelt;/ligt;";  }  echo 'lt;/ulgt;';  }  ;  ?gt;   lt;?php } ?gt;  lt;/navgt;  lt;div class="mt-20 justify-content-center d-flex d-lg-none"gt;  lt;a href="lt;?php echo $filterreset; ?gt;" class="reset-filter"gt;lt;?php echo get_theme_mod('reset_filter_text');?gt;lt;/agt;  lt;/divgt;  lt;?php  } else {?gt;  lt;div class="mt-20 justify-content-center d-flex filter-not-found"gt;  lt;?php   echo get_theme_mod('no_products_found') . 'lt;brgt;lt;a href="' . $filterreset .'" class="reset-filter" style="margin-top:20px;"gt;' . get_theme_mod('reset_filter_text') . 'lt;/agt;';  }?gt;  lt;/divgt;  lt;?php   wp_reset_postdata();   die(); }  add_action('wp_ajax_cosmetic_filter', 'cosmetic_show_products'); add_action('wp_ajax_nopriv_cosmetic_filter', 'cosmetic_show_products');  

Сам виджет

 lt;?php  class cosmetic_Filter_Widget extends WP_Widget { /**  * General Setup  */  public function __construct() {   /* Widget settings. */  $widget_ops = array(  'classname' =gt; 'cosmetic_filter_widget',  'description' =gt; 'Ajax Filter Widget'  );  /* Widget control settings. */  $control_ops = array(  'width' =gt; 500,  'height' =gt; 450,  'id_base' =gt; 'cosmetic_filter_widget'  );  /* Create the widget. */  parent::__construct( 'cosmetic_filter_widget', 'Ajax Фильтрация', $widget_ops, $control_ops );  }   /**  * Display Widget  * @param array $args  * @param array $instance  */  public function widget( $args, $instance )  {  extract( $args );   $title1 = $instance['title1'];  $title2 = $instance['title2'];   $prices = $this-gt;get_filtered_price();  $min = floor( $prices-gt;min_price );  $max = ceil( $prices-gt;max_price );  $step = ($min $max)/2;  $stepp = $step   $step/4;  $stept = $step   $step/8;  $stepr = $min   $min/4;   global $woocommerce;   // Display Widget  ?gt;    lt;div class="categories side-nav log"gt;  lt;h5 class="categories__title"gt;lt;?php echo get_theme_mod('filter_product_cat_heading') ?gt;lt;/h5gt;  lt;div id="st-accordion-cat" class="st-accordion"gt;   lt;ul class="st-accordion-cat-list"gt;  lt;?php   $categories = get_terms(  'product_cat',  array(  'orderby' =gt; 'menu_order',  'order' =gt; 'ask',  'hierarchical' =gt; true,  'hide_empty' =gt; 1,  'parent' =gt; 0  )  );   foreach($categories as $cat){ ?gt;  lt;li class="cosmetic_filter_check"gt;  lt;?php $temp_cat = get_terms(  'product_cat',  array(  'orderby' =gt; 'menu_order',  'order' =gt; 'ask',  'hierarchical' =gt; true,  'hide_empty' =gt; 1,  'parent' =gt; $cat-gt;term_id  )  );   $class='';  if($temp_cat) {$class='has_child';} else {$class='no_child';} ?gt;        lt;input id="term_lt;?php echo $cat-gt;term_id; ?gt;" type="checkbox" name="category" value="lt;?php echo $cat-gt;term_id; ?gt;"gt;  lt;label style="display:inline-block;" class="lt;?php echo $class; ?gt;"gt;lt;?php echo $cat-gt;name; ?gt;lt;/labelgt;    lt;?php    if($temp_cat){  echo 'lt;div class="st-content cat-list"gt;';   foreach($temp_cat as $temp){?gt;  lt;div class="log__group check" style="margin-left:10px; font-weight: 400;"gt;     lt;input id="term_lt;?php echo $temp-gt;term_id; ?gt;" type="checkbox" name="category" value="lt;?php echo $temp-gt;term_id; ?gt;"gt;  lt;label for="term_lt;?php echo $temp-gt;term_id; ?gt;"gt;lt;?php echo $temp-gt;name; ?gt;lt;/labelgt;  lt;/divgt;  lt;?php }   echo 'lt;/divgt;';  }?gt;  lt;/ligt;  lt;?php } ?gt;  lt;/ulgt;  lt;/divgt;  lt;/divgt;   lt;div class="categories side-nav log"gt;  lt;h5 class="categories__title"gt;lt;?php echo get_theme_mod('filter_pa_color_heading') ?gt;lt;/h5gt;  lt;div id="st-accordion-color" class="st-accordion"gt;   lt;ul class="st-accordion-color-list"gt;  lt;?php   $categories = get_terms(  'pa_color',  array(  'orderby' =gt; 'name',  'hierarchical' =gt; true,  'hide_empty' =gt; 1,  'parent' =gt; 0  )  );    foreach($categories as $cat){ ?gt;  lt;li class="cosmetic_filter_pa_color_check"gt;  lt;?php $temp_cat = get_terms(  'pa_color',  array(  'orderby' =gt; 'name',  'hierarchical' =gt; true,  'hide_empty' =gt; 1,  'parent' =gt; $cat-gt;term_id  )  );   $class='';  if($temp_cat) {$class='has_child';} else {$class='no_child';} ?gt;   lt;input id="term_lt;?php echo $cat-gt;term_id; ?gt;" type="checkbox" name="category" value="lt;?php echo $cat-gt;term_id; ?gt;"gt;  lt;label for="term_lt;?php echo $cat-gt;term_id; ?gt;"gt;  lt;div class="pa_color-bg" style=" border: 1px solid grey; margin-right: 5px; background: lt;?php echo get_term_meta( $cat-gt;term_id, 'cosmetic_pa_color', true ); ?gt; "gt;lt;a href="#" style="display:inline-block;" class="lt;?php echo $class; ?gt;"gt;lt;/agt;  lt;/divgt;  lt;div class="color-label"gt;lt;?php echo $cat-gt;name; ?gt;lt;/divgt;  lt;/labelgt;        lt;?php  if($temp_cat){  echo 'lt;div class="st-content cat-list"gt;';  foreach($temp_cat as $temp){?gt;  lt;div class="log__group check" style="margin-left:10px; font-weight: 400;"gt;  lt;input id="term_lt;?php echo $temp-gt;term_id; ?gt;" type="checkbox" name="category" value="lt;?php echo $temp-gt;term_id; ?gt;"gt;  lt;label for="term_lt;?php echo $temp-gt;term_id; ?gt;"gt;lt;?php echo $temp-gt;name; ?gt;lt;/labelgt;  lt;/divgt;  lt;?php }   echo 'lt;/divgt;';  } ?gt;  lt;/ligt;  lt;?php } ?gt;  lt;/ulgt;  lt;/divgt;  lt;/divgt;   lt;div class="categories side-nav log"gt;  lt;h5 class="categories__title"gt;lt;?php echo get_theme_mod('filter_pa_size_heading') ?gt;lt;/h5gt;  lt;div id="st-accordion-size" class="st-accordion"gt;   lt;ul class="st-accordion-size-list"gt;  lt;?php   $categories = get_terms(  'pa_size',  array(  'orderby' =gt; 'menu_order',  'order' =gt; 'ask',  'hierarchical' =gt; true,  'hide_empty' =gt; 1,  'parent' =gt; 0  )  );   foreach($categories as $cat){ ?gt;  lt;li class="cosmetic_filter_pa_size_check"gt;  lt;?php $temp_cat = get_terms(  'pa_size',  array(  'orderby' =gt; 'id',  'order' =gt; 'ask',  'hierarchical' =gt; true,  'hide_empty' =gt; 1,  'parent' =gt; $cat-gt;term_id  )  );   $class='';  if($temp_cat) {$class='has_child';} else {$class='no_child';} ?gt;   lt;input id="term_lt;?php echo $cat-gt;term_id; ?gt;" type="checkbox" name="category" value="lt;?php echo $cat-gt;term_id; ?gt;"gt;  lt;label for="term_lt;?php echo $cat-gt;term_id; ?gt;"gt; lt;a href="#" style="display:inline-block;" class="lt;?php echo $class; ?gt;"gt;lt;?php echo $cat-gt;name; ?gt;lt;/agt;lt;/labelgt;    lt;?php  if($temp_cat){  echo 'lt;div class="st-content cat-list"gt;';  foreach($temp_cat as $temp){?gt;  lt;div class="log__group check" style="margin-left:10px; font-weight: 400;"gt;     lt;input id="term_lt;?php echo $temp-gt;term_id; ?gt;" type="checkbox" name="category" value="lt;?php echo $temp-gt;term_id; ?gt;"gt;  lt;label for="term_lt;?php echo $temp-gt;term_id; ?gt;"gt;lt;?php echo $temp-gt;name; ?gt;lt;/labelgt;  lt;/divgt;  lt;?php }  echo 'lt;/divgt;';  } ?gt;  lt;/ligt;  lt;?php } ?gt;  lt;/ulgt;  lt;/divgt;  lt;/divgt;   lt;div class="sortby cosmetic_sortby" data-minprice="lt;?php echo $min; ?gt;" data-maxprice="lt;?php echo $max; ?gt;"gt;  lt;h5 class="sortby__title categories__title"gt;lt;?php echo get_theme_mod('filter_price_range_heading') ?gt;lt;/h5gt;    lt;p class="sortby__price"gt;  lt;label for="amount"gt;Price:lt;/labelgt;   lt;div class="price-slider"gt;lt;span class="field"gt;from   lt;input type="number" value="lt;?php echo $min; ?gt;" min="lt;?php echo $min; ?gt;" max="lt;?php echo $max; ?gt;" id="priceMin" class="min_price"/gt;lt;?php echo get_woocommerce_currency_symbol(); ?gt;lt;brgt; до   lt;input type="number" value="lt;?php echo $max; ?gt;" min="lt;?php echo $min; ?gt;" max="lt;?php echo $max; ?gt;" class="max_price" id="priceMax"/gt;lt;?php echo get_woocommerce_currency_symbol(); ?gt;lt;/spangt;  lt;div class="min-max-slider" data-legendnum="3"gt;  lt;label for="min"gt;Minimum pricelt;/labelgt;  lt;input id="min" class="min" name="min" type="range" step="1" min="lt;?php echo $min; ?gt;" max="lt;?php echo $max; ?gt;" /gt;  lt;label for="max"gt;Maximum pricelt;/labelgt;  lt;input id="max" class="max" name="max" type="range" step="1" min="lt;?php echo $min; ?gt;" max="lt;?php echo $max; ?gt;" /gt;  lt;/divgt;   lt;/divgt;  lt;/pgt;  lt;/divgt;   //!!!!!!!!!!!!!THERE IS THE SORTING HAS TO BE!!!!!!!!!!!!!!!!!!!!!!!//   lt;form class="woocommerce-ordering" method="get"gt;  lt;select name="orderby" class="orderby" aria-label="Shop order"gt;  lt;option value="menu_order" selected="selected"gt;Default sortinglt;/optiongt;  lt;option value="popularity"gt;Sort by popularitylt;/optiongt;  lt;option value="rating"gt;Sort by average ratinglt;/optiongt;  lt;option value="date"gt;Sort by latestlt;/optiongt;  lt;option value="price"gt;Sort by price: low to highlt;/optiongt;  lt;option value="price-desc"gt;Sort by price: high to lowlt;/optiongt;  lt;/selectgt;  lt;input type="hidden" name="paged" value="1"gt;  lt;/formgt;  lt;?php  }     protected function get_filtered_price() {  global $wpdb;   $args = wc()-gt;query-gt;get_main_query()-gt;query_vars;  $tax_query = isset( $args['tax_query'] ) ? $args['tax_query'] : array();  $meta_query = isset( $args['meta_query'] ) ? $args['meta_query'] : array();   if ( ! is_post_type_archive( 'product' ) amp;amp; ! empty( $args['taxonomy'] ) amp;amp; ! empty( $args['term'] ) ) {  $tax_query[] = array(  'taxonomy' =gt; $args['taxonomy'],  'terms' =gt; array( $args['term'] ),  'field' =gt; 'slug',  );  }   foreach ( $meta_query   $tax_query as $key =gt; $query ) {  if ( ! empty( $query['price_filter'] ) || ! empty( $query['rating_filter'] ) ) {  unset( $meta_query[ $key ] );  }  }   $meta_query = new WP_Meta_Query( $meta_query );  $tax_query = new WP_Tax_Query( $tax_query );   $meta_query_sql = $meta_query-gt;get_sql( 'post', $wpdb-gt;posts, 'ID' );  $tax_query_sql = $tax_query-gt;get_sql( $wpdb-gt;posts, 'ID' );   $sql = "SELECT min( FLOOR( price_meta.meta_value ) ) as min_price, max( CEILING( price_meta.meta_value ) ) as max_price FROM {$wpdb-gt;posts} ";  $sql .= " LEFT JOIN {$wpdb-gt;postmeta} as price_meta ON {$wpdb-gt;posts}.ID = price_meta.post_id " . $tax_query_sql['join'] . $meta_query_sql['join'];  $sql .= " WHERE {$wpdb-gt;posts}.post_type IN ('" . implode( "','", array_map( 'esc_sql', apply_filters( 'woocommerce_price_filter_post_type', array( 'product' ) ) ) ) . "')  AND {$wpdb-gt;posts}.post_status = 'publish'  AND price_meta.meta_key IN ('" . implode( "','", array_map( 'esc_sql', apply_filters( 'woocommerce_price_filter_meta_keys', array( '_price' ) ) ) ) . "')  AND price_meta.meta_value gt; '' ";  $sql .= $tax_query_sql['where'] . $meta_query_sql['where'];   $search = WC_Query::get_main_search_query_sql();  if ( $search ) {  $sql .= ' AND ' . $search;  }   return $wpdb-gt;get_row( $sql ); // WPCS: unprepared SQL ok.  }    /**  * Update Widget  * @param array $new_instance  * @param array $old_instance  * @return array  */  public function update( $new_instance, $old_instance )  {  $instance = $old_instance;   $instance['title1'] = strip_tags( $new_instance['title1'] );  $instance['title2'] = strip_tags( $new_instance['title2'] );   return $instance;  }   /**  * Widget Settings  * @param array $instance  */  public function form( $instance )  {  //default widget settings.  $defaults = array(  'title1' =gt; 'Сортировать по цене',  'title2' =gt; 'Категории товаров',  );  $instance = wp_parse_args( (array) $instance, $defaults );   ?gt;  lt;pgt;  lt;label for="lt;?php echo $this-gt;get_field_id( 'title1' ); ?gt;"gt;The filtration headinglt;/labelgt;  lt;input type="text" class="widefat" id="lt;?php echo $this-gt;get_field_id( 'title1' ); ?gt;" name="lt;?php echo $this-gt;get_field_name( 'title1' ); ?gt;" value="lt;?php echo $instance['title1']; ?gt;" /gt;  lt;/pgt;  lt;pgt;  lt;label for="lt;?php echo $this-gt;get_field_id( 'title2' ); ?gt;"gt;The filtration headinglt;/labelgt;  lt;input type="text" class="widefat" id="lt;?php echo $this-gt;get_field_id( 'title2' ); ?gt;" name="lt;?php echo $this-gt;get_field_name( 'title2' ); ?gt;" value="lt;?php echo $instance['title2']; ?gt;" /gt;  lt;/pgt;   lt;?php  } }  

Js part

 jQuery(function($) { $('.categories.side-nav.loggt;.st-accordiongt;ulgt;li input, .cosmetic_sortby input, select.orderby').on('change',function(e){   e.preventDefault();   cosmetic_get_posts();  jQuery('html, body').animate({scrollTop:0}, 1);  });    $(document).on("click",".ajax-page-numbers .page-numbers",function(e){  e.preventDefault();   var url = $(this).attr('href'); //Grab the URL destination as a string  var paged = url.split('amp;paged='); //Split the string at the occurance of amp;paged=   if(~url.indexOf('amp;paged=')){  paged = url.split('amp;paged=');  } else {  paged = url.split('/page/');  }  cosmetic_get_posts(paged[1]); //Load Posts (feed in paged value)  });   function getCats()  {  var cats = []; //Setup empty array   $(".cosmetic_filter_check input:checked").each(function() {  var val = $(this).val();  cats.push(val); //Push value onto array  });  return cats; //Return all of the selected genres in an array  }  function getColor()  {  var cats = []; //Setup empty array   $(".cosmetic_filter_pa_color_check input:checked").each(function() {  var val = $(this).val();  cats.push(val); //Push value onto array  });   return cats; //Return all of the selected genres in an array  }  function getSize()  {  var cats = []; //Setup empty array   $(".cosmetic_filter_pa_size_check input:checked").each(function() {  var val = $(this).val();  cats.push(val); //Push value onto array  });   return cats; //Return all of the selected genres in an array  }   function getPricesMin(){  return $('#priceMin').val();  }  function getPriceMax(){  return $('#priceMax').val();  }  function cosmetic_order(){  return $('.orderby option:selected').val();  }    function cosmetic_get_posts(paged)  {  var paged_value = paged; //Store the paged value if it's being sent through when the function is called  var ajax_url = woocommerce_params.ajax_url;    jQuery.ajax({  type: 'GET',  url: ajax_url,  data: {  action: 'cosmetic_filter',  category: getCats,  pa_color: getColor,  pa_size: getSize,  min: getPricesMin,  max: getPriceMax,  order: cosmetic_order,  paged: paged_value //If paged value is being sent through with function call, store here  },  beforeSend: function ()  {  jQuery('.main-products-wrapper').html('lt;div class="text-center" style="height:50vh;"gt;Searching...lt;/divgt;');  },  success: function(data)  {  //Hide loader here  jQuery('.main-products-wrapper').html(data);  jQuery('.main-products-wrapper ul.products').addClass('row align-items-start');  jQuery('.product').addClass('col-lg-4 col-6');   },  error: function()  {  //If an ajax error has occured, do something here...  jQuery(".main-products-wrapper").html('lt;div class="text-center" style="height:50vh;"gt;Something is wronglt;/divgt;');  }  });   }  });  

Я знаю, что это очень долго, но, может быть, кому-то это пригодится. Я просто хочу выяснить, как заставить выбор по умолчанию правильно работать внутри фильтра. Обычно ли сортировка по умолчанию работает с ajax?