Skip to content

Instantly share code, notes, and snippets.

@helgatheviking
Forked from kloon/functions.php
Last active November 9, 2021 23:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save helgatheviking/ff8792fbb12f5c5367c816b8a46c70ad to your computer and use it in GitHub Desktop.
Save helgatheviking/ff8792fbb12f5c5367c816b8a46c70ad to your computer and use it in GitHub Desktop.
WooCommerce Dropdown Product Quantity (not compatible with Mix and Match, Product Bundles, etc)
<?php
/**
* Change the quantity input to select.
*
* @param array $args Args for the input.
* @param WC_Product|null $product Product.
* @param boolean $echo Whether to return or echo|string.
*
* @return string
*/
function woocommerce_quantity_input( $args = array(), $product = null, $echo = true ) {
if ( is_null( $product ) ) {
$product = $GLOBALS['product'];
}
$defaults = array(
'input_id' => uniqid( 'quantity_' ),
'input_name' => 'quantity',
'input_value' => '1',
'classes' => apply_filters( 'woocommerce_quantity_input_classes', array( 'input-dropdown', 'qty' ), $product ),
'max_value' => apply_filters( 'woocommerce_quantity_input_max', -1, $product ),
'min_value' => apply_filters( 'woocommerce_quantity_input_min', 0, $product ),
'step' => apply_filters( 'woocommerce_quantity_input_step', 1, $product ),
'pattern' => apply_filters( 'woocommerce_quantity_input_pattern', has_filter( 'woocommerce_stock_amount', 'intval' ) ? '[0-9]*' : '' ),
'inputmode' => apply_filters( 'woocommerce_quantity_input_inputmode', has_filter( 'woocommerce_stock_amount', 'intval' ) ? 'numeric' : '' ),
'product_name' => $product ? $product->get_title() : '',
);
$args = apply_filters( 'woocommerce_quantity_input_args', wp_parse_args( $args, $defaults ), $product );
// Apply sanity to min/max args - min cannot be lower than 0.
$args['min_value'] = max( $args['min_value'], 0 );
$args['max_value'] = 0 < $args['max_value'] ? $args['max_value'] : 10;
// Max cannot be lower than min if defined.
if ( '' !== $args['max_value'] && $args['max_value'] < $args['min_value'] ) {
$args['max_value'] = $args['min_value'];
}
ob_start();
if ( $args['max_value'] && $args['min_value'] === $args['max_value'] ) {
echo '<div class="quantity hidden">
<input type="hidden" id="'. esc_attr( $args['input_id'] ) .'" class="qty" name="'. esc_attr( $args['input_name'] ) .'" value="'. esc_attr( $min_value ) .'" />
</div>';
} else {
/* translators: %s: Quantity. */
$label = ! empty( $args['product_name'] ) ? sprintf( esc_html__( '%s quantity', 'woocommerce' ), wp_strip_all_tags( $args['product_name'] ) ) : esc_html__( 'Quantity', 'woocommerce' );
echo '<div class="quantity">';
do_action( 'woocommerce_before_quantity_input_field' );
echo '<label class="screen-reader-text" for="'. esc_attr( $args['input_id'] ) .'">'. esc_attr( $label ) .'</label>';
$options = '';
for ( $count = $args['min_value']; $count <= $args['max_value']; $count = $count + $args['step'] ) {
$options .= '<option value="' . $count . '" '. selected( $args['input_value'], $count, false ) . '>' . $count . '</option>';
}
echo '<div class="quantity_select"><select name="' . esc_attr( $args['input_name'] ) . '" title="' . _x( 'Qty', 'Product quantity input tooltip', 'woocommerce' ) . '" class="qty">' . $options . '</select></div>';
do_action( 'woocommerce_after_quantity_input_field' );
echo '</div>';
}
if ( $echo ) {
echo ob_get_clean(); // WPCS: XSS ok.
} else {
return ob_get_clean();
}
}
@Allshookup4
Copy link

First I want to thank you for your hard work on this code. I did fine one issue and I was hoping that maybe someone would know how to fix it.
In Woocommerce Product / Inventory tab if you have selected "Enable this to only allow one of this item to be bought in a single order" it removes the quantity selector box by default. The issues is the code above causes the quantity selector box to reappear.

@helgatheviking
Copy link
Author

Hi @Allshookup4 I am glad you like the code snippet. i just dropped it into my site (it's been ages since i looked at it) and I cannot reproduce what you are describing. Line 42 should be true if the product is "sold individually" as the min quantity will be equal to the max quantity... ie: 1. I would check if you have any other themes/plugins/snippets impacting the max quantity.

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