Skip to content

Instantly share code, notes, and snippets.

@helgatheviking
Created February 24, 2017 18:09
Show Gist options
  • Save helgatheviking/6abe7385c23ba4238710ba6d1ccc5181 to your computer and use it in GitHub Desktop.
Save helgatheviking/6abe7385c23ba4238710ba6d1ccc5181 to your computer and use it in GitHub Desktop.
Add plus and minus buttons to WooCommerce quantity inputs
<?php
/**
* Product quantity inputs with plus/minus buttons
*
* Save this template to your theme as woocommerce/global/quantity-input.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see https://docs.woocommerce.com/document/template-structure/
* @author WooThemes
* @package WooCommerce/Templates
* @version 2.5.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
if ( $max_value && $min_value === $max_value ) {
?>
<input type="hidden" name="<?php echo esc_attr( $input_name ); ?>" value="<?php echo esc_attr( $min_value ); ?>" />
<?php
} else {
?>
<div class="quantity">
<input class="minus" type="button" value="-">
<input type="number" 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' ) ?>" class="input-text qty text" size="4" pattern="<?php echo esc_attr( $pattern ); ?>" inputmode="<?php echo esc_attr( $inputmode ); ?>" />
<input class="plus" type="button" value="+">
</div>
<?php
}
@samholguin
Copy link

samholguin commented Apr 12, 2021

Vanilla for those that may need:

const DOM = {
    plusBtns: document.querySelectorAll('.plus'),
    minusBtns: document.querySelectorAll('.minus'),
};

const init = () => {
    if (DOM.plusBtns.length > 0) {
        DOM.plusBtns.forEach((btn) => {
            btn.addEventListener('click', (event) => {
                event.preventDefault();
                const input = btn.nextElementSibling;
                const val = Number(input.value);
                let step = input.getAttribute('step');
                step = (typeof(step) !== 'undefined' ? Number(step) : 1);
                input.value = val + step;
            });
        });
    }

    if (DOM.minusBtns.length > 0) {
        DOM.minusBtns.forEach((btn) => {
            btn.addEventListener('click', (event) => {
                event.preventDefault();
                const input = btn.previousElementSibling;
                const val = Number(input.value);
                let step = input.getAttribute('step');
                step = (typeof(step) !== 'undefined' ? Number(step) : 1);
                if (val > 0) {
                    input.value = val - step;
                }
            });
        });
    }
};

export default init;

@tradesouthwest
Copy link

Thanks for the Vanilla, @samholguin

@SamMed1
Copy link

SamMed1 commented May 17, 2022

@samholguin Thanks for the vanilla!

Based on the html structure above, the plusBtns forEach should have:

const input = btn.previousElementSibling;

and the minusBtns forEach should have:

const input = btn.nextElementSibling;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment