Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
473 views
in Technique[技术] by (71.8m points)

javascript - Custom plus and minus quantity buttons in Woocommerce 3

I’m building custom WordPress and WooCommerce theme and adding custom plus and minus buttons to Product page quantity field. The buttons do update quantity input's value and I also receive "Item has been added to your cart" notification (on Product page) when I submit Add to Cart. But the cart page doesn’t show any items, neither says the cart is empty.

I can not work out which WooCommerce JS function I’m suppose to hook into, neither how to hook into it. Could I ask for help please?! Thanks in advance!

My HTML layout:

<div class="quantity">
    <label class="quantity__label" for="<?php echo esc_attr( $input_id ); ?>"><?php esc_html_e( 'Quantity:', 'woocommerce' ); ?></label>
    <div class="quantity__wrapper">
        <input type="button" value="-" class="quantity__button quantity__remove js-qty-remove" />
        <input
            type="text"
            id="<?php echo esc_attr( $input_id ); ?>"
            class="input-text qty text quantity__input"
            step="<?php echo esc_attr( $step ); ?>"
            min="<?php echo esc_attr( $min_value ); ?>"
            max="<?php echo esc_attr( 0 < $max_value ? $max_value : '' ); ?>"
            name="<?php echo esc_attr( $input_name ); ?>"
            value="<?php echo esc_attr( $input_value ); ?>"
            title="<?php echo esc_attr_x( 'Qty', 'Product quantity input tooltip', 'woocommerce' ); ?>"
            size="4"
            pattern="<?php echo esc_attr( $pattern ); ?>"
            inputmode="<?php echo esc_attr( $inputmode ); ?>"
            aria-labelledby="<?php echo esc_attr( $labelledby ); ?>" />
        <input type="button" value="+" class="quantity__button quantity__add js-qty-add" />
    </div>
</div>

My custom jQuery function:

function quantityButtons() {
    var $qtyAdd = $('.js-qty-add'),
        $qtyRemove = $('.js-qty-remove'),
        $qtyInput = $('.quantity__input');

    $qtyAdd.on('click', addQty);
    $qtyRemove.on('click', removeQty);

    function addQty() {
        var $qtyInput = $('.quantity__input'),
        $qtyRemove = $('.js-qty-remove'),
        $i = $qtyInput.val();

        $i++;
        $qtyRemove.attr("disabled", !$i);
        $qtyInput.val($i);
    }

    function removeQty() {
        var $qtyInput = $('.quantity__input'),
        $qtyRemove = $('.js-qty-remove'),
        $i = $qtyInput.val();

        if ($i >= 1) {
            $i--;
            $qtyInput.val($i);
        } else {
            $qtyRemove.attr("disabled", true);
        }
    }

    $qtyRemove.attr("disabled", !$qtyInput.val());
}

quantityButtons();
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your First code part is made from a customization of global/quantity-input.php Woocommerce template code…

So for testing, I have changed partially that global/quantity-input.php template code with the following (very near to your code):

?>
<div class="quantity">
    <label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>"><?php esc_html_e( 'Quantity', 'woocommerce' ); ?></label>
    <input type="button" value="-" class="qty_button minus" />
    <input
        type="number"
        id="<?php echo esc_attr( $input_id ); ?>"
        class="input-text qty text"
        step="<?php echo esc_attr( $step ); ?>"
        min="<?php echo esc_attr( $min_value ); ?>"
        max="<?php echo esc_attr( 0 < $max_value ? $max_value : '' ); ?>"
        name="<?php echo esc_attr( $input_name ); ?>"
        value="<?php echo esc_attr( $input_value ); ?>"
        title="<?php echo esc_attr_x( 'Qty', 'Product quantity input tooltip', 'woocommerce' ); ?>"
        size="4"
        pattern="<?php echo esc_attr( $pattern ); ?>"
        inputmode="<?php echo esc_attr( $inputmode ); ?>"
        aria-labelledby="<?php echo esc_attr( $labelledby ); ?>" />
    <input type="button" value="+" class="qty_button plus" />
</div>
<?php

Now the necessary CSS and revisited jQuery code functions:

// Minimum CSS to remove +/- default buttons on input field type number
add_action( 'wp_head' , 'custom_quantity_fields_css' );
function custom_quantity_fields_css(){
    ?>
    <style>
    .quantity input::-webkit-outer-spin-button,
    .quantity input::-webkit-inner-spin-button {
        display: none;
        margin: 0;
    }
    .quantity input.qty {
        appearance: textfield;
        -webkit-appearance: none;
        -moz-appearance: textfield;
    }
    </style>
    <?php
}


add_action( 'wp_footer' , 'custom_quantity_fields_script' );
function custom_quantity_fields_script(){
    ?>
    <script type='text/javascript'>
    jQuery( function( $ ) {
        if ( ! String.prototype.getDecimals ) {
            String.prototype.getDecimals = function() {
                var num = this,
                    match = ('' + num).match(/(?:.(d+))?(?:[eE]([+-]?d+))?$/);
                if ( ! match ) {
                    return 0;
                }
                return Math.max( 0, ( match[1] ? match[1].length : 0 ) - ( match[2] ? +match[2] : 0 ) );
            }
        }
        // Quantity "plus" and "minus" buttons
        $( document.body ).on( 'click', '.plus, .minus', function() {
            var $qty        = $( this ).closest( '.quantity' ).find( '.qty'),
                currentVal  = parseFloat( $qty.val() ),
                max         = parseFloat( $qty.attr( 'max' ) ),
                min         = parseFloat( $qty.attr( 'min' ) ),
                step        = $qty.attr( 'step' );

            // Format values
            if ( ! currentVal || currentVal === '' || currentVal === 'NaN' ) currentVal = 0;
            if ( max === '' || max === 'NaN' ) max = '';
            if ( min === '' || min === 'NaN' ) min = 0;
            if ( step === 'any' || step === '' || step === undefined || parseFloat( step ) === 'NaN' ) step = 1;

            // Change the value
            if ( $( this ).is( '.plus' ) ) {
                if ( max && ( currentVal >= max ) ) {
                    $qty.val( max );
                } else {
                    $qty.val( ( currentVal + parseFloat( step )).toFixed( step.getDecimals() ) );
                }
            } else {
                if ( min && ( currentVal <= min ) ) {
                    $qty.val( min );
                } else if ( currentVal > 0 ) {
                    $qty.val( ( currentVal - parseFloat( step )).toFixed( step.getDecimals() ) );
                }
            }

            // Trigger change event
            $qty.trigger( 'change' );
        });
    });
    </script>
    <?php
}

Code goes in function.php file of your active child theme (or active theme). Tested and works.

The quantity buttons "plus" and "minus" work perfectly and are displayed this way:

enter image description here

Products are added to cart with the correct quantity:

enter image description here

if you change the quantity field value with plus and minus buttons, the "Update cart" button is activated when any quantity field change.

enter image description here

When you click on "Update cart", the quantities as correctly updated.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...