在 WooCommerce 商店页面上向 Ajax 添加数量字段添加到购物车按钮

Posted

技术标签:

【中文标题】在 WooCommerce 商店页面上向 Ajax 添加数量字段添加到购物车按钮【英文标题】:Add a quantity field to Ajax add to cart button on WooCommerce shop page 【发布时间】:2018-07-21 04:31:56 【问题描述】:

我是 Woocommerce 的新手。我试图在商店页面中显示数量框。我使用了下面的代码,它按预期工作:

add_action( 'woocommerce_before_shop_loop', 'handsome_bearded_guy_select_variations' );

function handsome_bearded_guy_select_variations() 
remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10 );
add_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_single_add_to_cart', 30 );

但问题是 ajax 添加到购物车按钮已替换为默认按钮。

如何为 Woocommerce 档案页面启用带有数量字段的添加到购物车按钮上的 ajax 功能?

【问题讨论】:

【参考方案1】:

更新 2021年

对于从 3.2 到 5+ 的 WooCommerce 版本,优化了 jQuery 代码并删除了数量错误。添加到购物车后添加数量重置。


以下自定义函数挂在woocommerce_loop_add_to_cart_link 过滤器钩子中,并为 WooCommerce 档案页面和其他产品循环上的每个产品添加一个数量输入字段。我们在这里主要使用原始的 WooCommerce 代码。

当客户更改数量时,需要一些 jQuery 代码来更新添加到购物车按钮上的data-quantity 属性。可能需要一些样式,具体取决于您的客户希望(以及您的主题)

隐藏“查看购物车”按钮的附加部分位于末尾。

代码:

add_filter( 'woocommerce_loop_add_to_cart_link', 'quantity_inputs_for_loop_ajax_add_to_cart', 10, 2 );
function quantity_inputs_for_loop_ajax_add_to_cart( $html, $product ) 
    if ( $product && $product->is_type( 'simple' ) && $product->is_purchasable() && $product->is_in_stock() && ! $product->is_sold_individually() ) 
        // Get the necessary classes
        $class = implode( ' ', array_filter( array(
            'button',
            'product_type_' . $product->get_type(),
            $product->is_purchasable() && $product->is_in_stock() ? 'add_to_cart_button' : '',
            $product->supports( 'ajax_add_to_cart' ) ? 'ajax_add_to_cart' : '',
        ) ) );

        // Embedding the quantity field to Ajax add to cart button
        $html = sprintf( '%s<a rel="nofollow" href="%s" data-quantity="%s" data-product_id="%s" data-product_sku="%s" class="%s">%s</a>',
            woocommerce_quantity_input( array(), $product, false ),
            esc_url( $product->add_to_cart_url() ),
            esc_attr( isset( $quantity ) ? $quantity : 1 ),
            esc_attr( $product->get_id() ),
            esc_attr( $product->get_sku() ),
            esc_attr( isset( $class ) ? $class : 'button' ),
            esc_html( $product->add_to_cart_text() )
        );
    
    return $html;


add_action( 'wp_footer' , 'archives_quantity_fields_script' );
function archives_quantity_fields_script()
    ?>
    <script type='text/javascript'>
        jQuery(function($)
            // Update data-quantity
            $(document.body).on('click input', 'input.qty', function() 
                $(this).parent().parent().find('a.ajax_add_to_cart').attr('data-quantity', $(this).val());
                $(".added_to_cart").remove(); // Optional: Removing other previous "view cart" buttons
            ).on('click', '.add_to_cart_button', function()
                var button = $(this);
                setTimeout(function()
                    button.parent().find('.quantity > input.qty').val(1); // reset quantity to 1
                , 1000); // After 1 second

            );
        );
    </script>
    <?php

代码进入您的活动子主题(活动主题)的functions.php 文件中。 在店面主题的 WooCommerce 版本 4.1.1 和 WordPress 4.5.1 上测试并运行。


隐藏“查看购物车”按钮 (使用 Ajax 添加到购物车时)

1)。您可以将此 CSS 规则添加到位于活动主题中的 styles.css 文件中:

a.added_to_cart.wc-forward 
    display:none;

2)。您可以使用以下挂钩函数(第一个选项是最好的方法)

add_action( 'wp_head' , 'hide_ajax_view_cart_button' );
function hide_ajax_view_cart_button()
    if( is_shop() || is_product_category() || is_product_tag() ): ?>
    <style>
        a.added_to_cart.wc-forward 
            display:none;
        
    </style>
    <?php endif;

代码进入您的活动子主题(活动主题)的 function.php 文件中。

【讨论】:

也许有,但我找不到,所以您能否建议代码通过单击数量 +/- 来添加和删除产品,或者我可以尝试为此修改当前代码? 【参考方案2】:

一切都如上,没有“数量错误”。

代码:

add_filter( 'woocommerce_loop_add_to_cart_link', 'quantity_inputs_for_loop_ajax_add_to_cart', 10, 2 );
function quantity_inputs_for_loop_ajax_add_to_cart( $html, $product ) 
    if ( $product && $product->is_type( 'simple' ) && $product->is_purchasable() && $product->is_in_stock() && ! $product->is_sold_individually() ) 
        // Get the necessary classes
        $class = implode( ' ', array_filter( array(
            'button',
            'product_type_' . $product->get_type(),
            $product->is_purchasable() && $product->is_in_stock() ? 'add_to_cart_button' : '',
            $product->supports( 'ajax_add_to_cart' ) ? 'ajax_add_to_cart' : '',
        ) ) );

        // Adding embeding <form> tag and the quantity field
        $html = sprintf( '%s%s<a rel="nofollow" href="%s" data-quantity="%s" data-product_id="%s" data-product_sku="%s" class="%s">%s</a>%s',
        '<form class="cart">',
        woocommerce_quantity_input( array(), $product, false ),
        esc_url( $product->add_to_cart_url() ),
        esc_attr( isset( $quantity ) ? $quantity : 1 ),
        esc_attr( $product->get_id() ),
        esc_attr( $product->get_sku() ),
        esc_attr( isset( $class ) ? $class : 'button' ),
        esc_html( $product->add_to_cart_text() ),
        '</form>'
        );
    
    return $html;


add_action( 'wp_footer' , 'archives_quantity_fields_script' );
function archives_quantity_fields_script()
    //if( is_shop() || is_product_category() || is_product_tag() ): ?>
    <script type='text/javascript'>
        jQuery(function($)
            // Update quantity on 'a.button' in 'data-quantity' attribute (for ajax)
            $(".add_to_cart_button.product_type_simple").on('click', function()  var $button = $(this); $button.data('quantity', $button.parent().find('input.qty').val()); );        
            // remove old "view cart" text, only need latest one thanks!
            $(document.body).on("adding_to_cart", function() 
                $("a.added_to_cart").remove();
            );
        );
    </script>
    <?php //endif;

参考资料:

@LoicTheAztec 在 2018 年 2 月 11 日以上的条目。

@braciawrite 和 @andrewmclagan 的 GitHub 条目分别在 2015 年 12 月 11 日和 2018 年 3 月 15 日。

https://gist.github.com/webaware/6260326

注意:

代码应该在“add_to_cart”按钮被按下时执行检查,而不是数量变化。

当我在带有 WooCommerce 产品的自定义页面上运行此代码时,我已注释掉函数“archives_quantity_fields_script”下的 if 和 endif 语句。

希望这会有所帮助!

【讨论】:

此代码在 2019 年 7 月 27 日有效。接受的答案有语法错误 从 WooCommerce 4.0 开始,此解决方案似乎不再有效。 2020 年 10 月有人来帮我,但数量仍未更新 WordPress 5.5.1【参考方案3】:

这是一种似乎在 Woo 3+ 中运行良好的替代方法

<?php
/**
 * Add quantity field on the archive page.
 */
function custom_quantity_field_archive() 

    $product = wc_get_product( get_the_ID() );

    if ( ! $product->is_sold_individually() && 'variable' != $product->get_type() && $product->is_purchasable() ) 
    woocommerce_quantity_input( array( 'min_value' => 1, 'max_value' => $product->backorders_allowed() ? '' : $product->get_stock_quantity() ) );
    


add_action( 'woocommerce_after_shop_loop_item', 'custom_quantity_field_archive', 0, 9 );

/**
 * Enqueue the JavaScript.
 */
function custom_add_to_cart_quantity_handler() 

wc_enqueue_js( '
    jQuery( ".post-type-archive-product" ).on( "click", ".quantity input", function() 
        return false;
    );
    jQuery( ".post-type-archive-product" ).on( "change input", ".quantity .qty", function() 
        var add_to_cart_button = jQuery( this ).parents( ".product" ).find( ".add_to_cart_button" );
        
        // For AJAX add-to-cart actions
        add_to_cart_button.attr( "data-quantity", jQuery( this ).val() );

        // For non-AJAX add-to-cart actions
        add_to_cart_button.attr( "href", "?add-to-cart=" +   add_to_cart_button.attr( "data-product_id" ) + "&quantity=" + jQuery( this ).val() );
    );
' );


add_action( 'init', 'custom_add_to_cart_quantity_handler' );

jQuery 可能有多个选项,具体取决于页面上的 Ajax 操作。

【讨论】:

【参考方案4】:

我花了一整天的时间才完成这项工作 - 但这是对我有用的代码。添加到您的functions.php - 它改编自上面,我在WooCommerce 5.0.0

add_filter( 'woocommerce_loop_add_to_cart_link', 'quantity_inputs_for_loop_ajax_add_to_cart', 10, 2 );
function quantity_inputs_for_loop_ajax_add_to_cart( $html, $product ) 
    if ( $product && $product->is_type( 'simple' ) && $product->is_purchasable() && $product->is_in_stock() && ! $product->is_sold_individually() ) 
        // Get the necessary classes
        $class = implode( ' ', array_filter( array(
            'button',
            'product_type_' . $product->get_type(),
            $product->is_purchasable() && $product->is_in_stock() ? 'add_to_cart_button' : '',
            $product->supports( 'ajax_add_to_cart' ) ? 'ajax_add_to_cart' : '',
        ) ) );

        // Adding embeding <form> tag and the quantity field
        $html = sprintf( '%s%s<a rel="nofollow" href="%s" data-quantity="%s" data-product_id="%s" data-product_sku="%s" class="%s">%s</a>%s',
        '<form class="cart">',
        woocommerce_quantity_input( array(), $product, false ),
        esc_url( $product->add_to_cart_url() ),
        esc_attr( isset( $quantity ) ? $quantity : 1 ),
        esc_attr( $product->get_id() ),
        esc_attr( $product->get_sku() ),
        esc_attr( isset( $class ) ? $class : 'button' ),
        esc_html( $product->add_to_cart_text() ),
        '</form>'
        );
    
    return $html;


add_action( 'wp_footer' , 'archives_quantity_fields_script' );

function archives_quantity_fields_script()
    //if( is_shop() || is_product_category() || is_product_tag() ): ?>
    <script type='text/javascript'>
        jQuery( document ).ready( function( $ ) 
        $( document ).on( 'change', '.quantity .qty', function() 
            $( this ).parent( '.quantity' ).next( '.add_to_cart_button' ).attr( 'data-quantity', $( this ).val() );
            //alert("Changed");
        );
    );
        
        jQuery(function($) 
            // Update quantity on 'a.button' in 'data-quantity' attribute (for ajax) 
            $(".add_to_cart_button.product_type_simple").on('click', function() 
                var $button = $(this);
                $button.data('quantity', $button.parent().find('input.qty').val());
            );
            // remove old "view cart" text, only need latest one thanks!
            $(document.body).on("adding_to_cart", function() 
                $("a.added_to_cart").remove();
            );
        );
    </script>
    <?php //endif;

【讨论】:

以上是关于在 WooCommerce 商店页面上向 Ajax 添加数量字段添加到购物车按钮的主要内容,如果未能解决你的问题,请参考以下文章

Woocommerce:如何在应用/删除优惠券时禁用 AJAX?

为什么用于Woocommerce的高级AJAX产品过滤器更新页面?

在 Woocommerce 商店页面中仅显示特色产品

woocommerce-如何仅在商店页面上显示子类别?

如何删除 Woocommerce 商店页面上的简短描述

通过 Ajax (WooCommerce) 加载 single_product_content 时变体 Javascript 不起作用