如何正确组合2个ajax请求(无需插件)?

问题描述 投票:0回答:1

我有 2 个独立的 ajax-es,

    • 无尽加载
  1. 产品过滤器 - 按尺寸、颜色、排序,并且可以与分页正确配合。
    但过滤后 loarmore 脚本无法正常工作。例如,过滤器给了我 2 个粉红色的产品,这是必须的,但是在滚动时,loadmore 脚本仍然有效,就像它根本没有过滤一样 - 它给了我一个标准的(未过滤的)循环的 2nd-3d 页。 过滤器 - php 部分
function muvre_show_products(){

  $query_data = $_GET;  

    $paged = (isset($query_data['paged']) ) ? intval($query_data['paged']) : 1;
    $pages = $wp_query->max_num_pages; 
    $orderby = 'menu_order';
    $orderby = $query_data['order'];
    $posts_per_page = get_option('woocommerce_catalog_columns') * get_option('woocommerce_catalog_rows');   

    //filter by category id
  $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_pa_color = ($pa_color) ? array( array(
        'taxonomy' => 'pa_color',
        'field' => 'id',
        'terms' => $pa_color
    ) ) : false;
    $tax_query_pa_size = ($pa_size) ? array( array(
        'taxonomy' => 'pa_size',
        'field' => 'id',
        'terms' => $pa_size
    ) ) : false;

    $args = array(
        'post_type' => ['product'],     
        'paged' => $paged,
       'posts_per_page' => $posts_per_page,  
       'total_pages' => $pages,
        'tax_query' => array(
        'relation' => 'AND',
        $tax_query_pa_color,
        $tax_query_pa_size,
    ),
        'meta_query' => array(
            array(
                'key' => '_price',
                'value' => array($query_data['min'], $query_data['max']),
                'compare' => 'BETWEEN',
                'type' => '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;
    }
    
    
    
    $loop = new WP_Query( $args);
    if ( $loop->have_posts() ) {?>
      <?php    
    
    woocommerce_product_loop_start();
        while ( $loop->have_posts() ) : $loop->the_post();
            wc_get_template_part( 'content', 'product' );
    endwhile;             
?>
    </div>
        <nav class="woocommerce-pagination">
            <?php if($loop->max_num_pages > 1){ ?>   
                        <?php     
                        $big = 999999999; // need an unlikely integer

                         $pages = paginate_links( array(
                            'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
                            'format' => '?paged=%#%',
                            'current' => max( 1, $paged ),
                            'prev_text'       => '&larr;',   
                             'next_text'       => '&rarr;',
                             'first_page_text' => '« ', 
                             'last_page_text'  => ' »', 
                            'total' => $loop->max_num_pages,
                             'type'  => 'array',
                  ) );
                  if( is_array( $pages ) ) {
                      $paged = ( $paged == 0 ) ? 1 : $paged;
                      echo '<ul class="ajax-page-numbers page-numbers">';
                      foreach ( $pages as $page ) {
                          echo "<li>$page</li>";
                      }
                      echo '</ul>';
                  };  ?>            
            <?php } ?>
        </nav>  
</div>
      

  <?php
    } else {?>
      <div class="mt-20 justify-content-center d-flex filter-not-found">
         <?php echo'no products found'; }?>
    </div>
    <?php   
    wp_reset_postdata();
    die();
} 
 
add_action('wp_ajax_muvre_filter', 'muvre_show_products');
add_action('wp_ajax_nopriv_muvre_filter', 'muvre_show_products');

过滤js部分

jQuery(function($) {     
        
    $('.categories.side-nav.log>.st-accordion>ul>li input, .muvre_sortby input').on('change',function(e){   
      
     jQuery(this).parent('div, li').toggleClass('attr-selected');    
        e.preventDefault();
        muvre_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('&paged='); //Split the string at the occurance of &paged=

        if(~url.indexOf('&paged=')){
            paged = url.split('&paged=');
        } else {
            paged = url.split('/page/');
        }
        muvre_get_posts(paged[1]); //Load Posts (feed in paged value)
        
    });

     function getColor()
    {
        var cats = []; //Setup empty array

        $(".muvre_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

        $(".muvre_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 muvre_order(){
        return $('.orderby option:selected').val();
    }

  $('.orderby').on('change', function(e){
        e.preventDefault();
        muvre_get_posts();
    });

 

//Get Exising Select Options    
jQuery('select.orderby').each(function(i, select){
    var $select = jQuery(select);
    $select.find('option').each(function(j, option){
        var $option = jQuery(option);
        // Create a radio:
        var $radio = jQuery('<input type="radio" />');
        // Set name and value:
        $radio.attr('name', $select.attr('name')).attr('id', $option.val());
        // Set checked if the option was selected
       if ($option.attr('selected')) $radio.attr('checked', 'checked');
        $radio.on('change', function() {    
            jQuery('select.orderby').val($option.val()).trigger('change');
        });
        
        // Insert radio before select box:
        $select.before($radio);
        // Insert a label:
        $select.before(
          jQuery("<label />").attr('for', $option.attr('value')).text($option.text()));        
        // Insert a <br />:       
    });
    $select.hide();
}); 
    
   
    function muvre_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; //Get ajax url (added through wp_localize_script)       
        jQuery.ajax({
            type: 'GET',  
            url : ajax_url,
            data: {
                action: 'muvre_filter',
                url : ajax_url,//yes, there are 2 of them,with one doesn't work!
                pa_color: getColor,
                pa_size: getSize,
                min: getPricesMin,
                max: getPriceMax,
                order: muvre_order,         
                paged: paged_value, //If paged value is being sent through with function call, store here               
            },           
            beforeSend: function ()
            {               
                jQuery('.main-products-wrapper').html('<div class="text-center search-filter" style="height:50vh;">Search...</div>'); 
                jQuery('aside#secondary').removeClass('opened');                
              
            },
            success: function(data)
            {   jQuery('.main-products-wrapper').html(data);                
                jQuery(".main-products-wrapper>.main-products-wrapper").unwrap();
                jQuery('.main-products-wrapper ul.products').addClass('row align-items-start');
                jQuery('.product').addClass('col-lg-3 col-6');  
                jQuery('.slider-archive').each(function() {
                      var slider = jQuery(this);
                      slider.slick({
                      infinite: false,
                      slidesToShow: 1,
                      slidesToScroll: 1,
                      driggable:false, 
                      dots: true,
                      arrows:false,  
                      focusOnSelect: true,  
                    });
                    });
                jQuery('.filter-toggle a.reset-filter').removeClass('d-none');
                jQuery('aside#secondary').removeClass('opened');             
            },  
                
            error: function()
            {
                //If an ajax error has occured, do something here...
                jQuery(".main-products-wrapper").html('<div class="text-center" style="height:50vh;">Error</div>');
            }
        })             
        
    }  
});

加载更多 php 部分

function misha_loadmore_ajax_handler(){
    

   global $woocommerce;
    
   $pages = $wp_query->max_num_pages; 
   $posts_per_page = get_option('woocommerce_catalog_columns') * get_option('woocommerce_catalog_rows');
   $query_data = $_GET;  
    
    $args = json_decode( stripslashes( $_GET['query'] ), true );
    $args['paged'] = $_GET['page'] + 1; // we need next page to be loaded
    $args['post_status'] = 'publish';
    $args['post_type'] = 'product';
    $args['posts_per_page'] =  $posts_per_page;

    $query = new WP_Query($args);

    if ($query->have_posts()) {
        while ($query->have_posts()) {
            $query->the_post();
            wc_get_template_part('content', 'product');  
        }
    }

    wp_reset_postdata();
    die;

}
 
add_action('wp_ajax_loadmore', 'misha_loadmore_ajax_handler'); // wp_ajax_{action}
add_action('wp_ajax_nopriv_loadmore', 'misha_loadmore_ajax_handler'); // wp_ajax_nopriv_{action}

加载更多js部分

jQuery(function ($) {
   var canBeLoaded = true, // this param allows to initiate the AJAX call only if necessary
      bottomOffset = 2000; // the distance (in px) from the page bottom when you want to load more posts

  $(window).scroll(function() {
      
      var data = {
         'action': 'loadmore',
         'query': misha_loadmore_params.posts,
         'page': misha_loadmore_params.current_page,         
      };
       if ($(document).scrollTop() > ($(document).height() - bottomOffset) && canBeLoaded == true) {
         $.ajax({
            url: misha_loadmore_params.ajaxurl,
            data: data,
            type: 'GET',
            beforeSend: function (xhr) {
               canBeLoaded = false;

            },
            success: function (data) {
               if (data) {
                  //console.log(data);
                  $('body.archive .slider-archive').slick('unslick');
                  $('body.archive div.products').find('.product.col-lg-3.col-6:last-of-type').after(data);
                  jQuery('body.archive .product').addClass('col-lg-3 col-6');
                  jQuery('.slider-archive').each(function () {
                     var slider = jQuery(this);
                     slider.slick({
                        infinite: false,
                        slidesToShow: 1,
                        slidesToScroll: 1,
                        driggable: false,
                        dots: true,
                        arrows: false,
                        focusOnSelect: true,
                     });
                  });
                  canBeLoaded = true; // the ajax is completed, now we can run it again
                 misha_loadmore_params.current_page++;                
               }
            }           
         });
      }
   });
});

我尝试将 loadmore 脚本复制到过滤器成功,但没有帮助。我需要提出一项请求吗?即使循环相似,它们也具有不同的 GET 参数。 我尝试将一些tax_query复制到loadmore - 也失败了,我认为其中一个的语法在另一个中是错误的。 在 $query_data = $_GET 中,但是如果要 print_r loadmore GET,它将看起来像一级数组

Array
(
    [action] => loadmore
    [query] => {\"post_type\":\"product\",\"lang\":\"en\",\"error\":\"\",\"m\":\"\",\"p\":0,\"post_parent\":\"\",\"subpost\":\"\",\"subpost_id\":\"\",\"attachment\":\"\",\"attachment_id\":0,\"name\":\"\",\"pagename\":\"\",\"page_id\":0,\"second\":\"\",\"minute\":\"\",\"hour\":\"\",\"day\":0,\"monthnum\":0,\"year\":0,\"w\":0,\"category_name\":\"\",\"tag\":\"\",\"cat\":\"\",\"tag_id\":\"\",\"author\":\"\",\"author_name\":\"\",\"feed\":\"\",\"tb\":\"\",\"paged\":0,\"meta_key\":\"\",\"meta_value\":\"\",\"preview\":\"\",\"s\":\"\",\"sentence\":\"\",\"title\":\"\",\"fields\":\"\",\"menu_order\":\"\",\"embed\":\"\",\"category__in\":[],\"category__not_in\":[],\"category__and\":[],\"post__in\":[],\"post__not_in\":[],\"post_name__in\":[],\"tag__in\":[],\"tag__not_in\":[],\"tag__and\":[],\"tag_slug__in\":[],\"tag_slug__and\":[],\"post_parent__in\":[],\"post_parent__not_in\":[],\"author__in\":[],\"author__not_in\":[],\"search_columns\":[],\"orderby\":\"menu_order title\",\"order\":\"ASC\",\"meta_query\":[],\"tax_query\":{\"relation\":\"AND\",\"0\":{\"taxonomy\":\"product_visibility\",\"field\":\"term_taxonomy_id\",\"terms\":[7],\"operator\":\"NOT IN\"}},\"wc_query\":\"product_query\",\"posts_per_page\":4,\"update_post_term_cache\":true,\"ignore_sticky_posts\":false,\"suppress_filters\":false,\"cache_results\":true,\"update_menu_item_cache\":false,\"lazy_load_term_meta\":true,\"update_post_meta_cache\":true,\"nopaging\":false,\"comments_per_page\":\"50\",\"no_found_rows\":false,\"taxonomy\":\"language\",\"term\":\"en\"}
    [page] => 1
)

如果从过滤器中 print_r GET ,它将看起来像 1 级数组

Array
(
    [action] => muvre_filter
    [url] => /wp-admin/admin-ajax.php
    [pa_color] => 90
    [pa_size] => 
    [min] => 620
    [max] => 2150
    [order] => menu_order
)

也许我必须触发自己的过滤器分页?

我想弄清楚已经很多天了。 确切地学习 - 对于我自己来说,不是安装 Rocket/yith/etc 插件和“快乐生活”,我需要理解逻辑。 也许有人自己也做了类似的东西。 加载脚本是来自那里,但过滤器不是来自该作者。 我该怎么做才能让他们一起工作?

jquery ajax woocommerce
1个回答
0
投票

您保存过滤器并在 loadmore php 中使用它,例如,当您选择一个过滤器并执行(过滤的)ajax 请求时,保存过滤器的参数

(pa_color, pa_size...)
并在之后通过
loadmore
请求发送,您还应该在
misha_loadmore_ajax_handler()
中使用与
muvre_show_products()
中使用的相同过滤系统。

总结:

let fileringParams = {};

function muvre_get_posts(paged)
{       
    ...

    jQuery.ajax({
        ...
        data: {
            ...
            pa_color: getColor,
            pa_size: getSize,
            ...          
        },
        success: function(data)
        {
            fileringParams = {
                ...
                pa_color: getColor,
                pa_size: getSize,
                ...
                //all filtering params..
            }
        },
        ...
    })             
    
}

之后在 loadmore 脚本中,将

filteringParams
与请求一起发送。

$(window).scroll(function() {
  
    var data = {
        'action': 'loadmore',
        'query': misha_loadmore_params.posts,
        'page': misha_loadmore_params.current_page,
        ...
        //add the filteringParams to get the results filtered.    
        'filteringParams': filteringParams
    };
    ...
    //the rest of ajax code
  }
});

现在,当您过滤第一页时,其余页面也会被过滤。

注意:在

loadmore
php代码中,您应该接收过滤参数并像在
muvre_show_products()
中过滤结果一样使用它,否则什么都不会改变。

我希望能回答你的问题。

© www.soinside.com 2019 - 2024. All rights reserved.