Add a quantity field to Ajax add to cart button on WooCommerce shop page

后端 未结 3 517
Happy的楠姐
Happy的楠姐 2021-01-02 23:03

I am new to Woocommerce. I was trying to show the quantity box in the shop page. I have used the below code and it\'s working as expected:

add_action( \'woo         


        
相关标签:
3条回答
  • 2021-01-02 23:41

    Here is an alternative method which seems to work well in 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' );
    

    There may be several options for the jQuery, depending on what Ajax actions are on your page.

    0 讨论(0)
  • 2021-01-02 23:47

    Does everything as above, without the "quantity bug".

    The code:

    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;
    }
    

    References:

    @LoicTheAztec's entry above 11 Feb 2018.

    @braciawrite's and @andrewmclagan's GitHub entries on 11 Dec 2015 and 15 Mar 2018 respectively.

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

    Note:

    Code should perform the check when "add_to_cart" button is pressed, not on quantity change.

    I've commented out the if and endif statements under function "archives_quantity_fields_script" as I am running this code on a custom page with WooCommerce products.

    Hope this helps!

    0 讨论(0)
  • 2021-01-02 23:57

    Updated on May 2020

    For WooCommerce versions from 3.2 to 4+, Optimized jQuery code and Removed a quantity bug.


    The following custom function is hooked in woocommerce_loop_add_to_cart_link filter hook and adds a quantity input field to each product on WooCommerce archives pages and other product loops. We use here mostly the original WooCommerce code.

    A bit of jQuery code is necessary to update the data-quantity attribute on the add to cart button when customer changes the quantity. Some styling might be needed, depending on your client wishes (and on your theme).

    An additional section to hide the "View cart" button is located at the end.

    The code:

    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());
    
                    // (optional) Removing other previous "view cart" buttons
                    $(".added_to_cart").remove();
                });
            });
        </script>
        <?php
    }
    

    Code goes in functions.php file of your active child theme (active theme).
    Tested and works on WooCommerce version 4.1.1 and WordPress 4.5.1 on Storefront theme.


    Hiding "View cart" button (when using Ajax add to cart):

    1). You can add this CSS rule to the styles.css file located in your active theme:

    a.added_to_cart.wc-forward {
        display:none;
    }
    

    2). You can use the following hoocked function (first option is the best way):

    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;
    }
    

    Code goes in function.php file of your active child theme (active theme).

    0 讨论(0)
提交回复
热议问题