Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change quantity input field to a Dropdown in WooCommerce

I'm using the following in function.php and it works great on a single product page. The issue I have is on the cart page when you choose a different quantity it doesn't automatically update the cart. Any ideas?

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-text', 'qty', 'text' ), $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 );
   // Change 6 to max quantity
   $args['max_value'] = 0 < $args['max_value'] ? $args['max_value'] : 6;
 
   // Max cannot be lower than min if defined.
   if ( '' !== $args['max_value'] && $args['max_value'] < $args['min_value'] ) {
      $args['max_value'] = $args['min_value'];
   }
  
   $options = '';
    
   for ( $count = $args['min_value']; $count <= $args['max_value']; $count = $count + $args['step'] ) {
 
      // Cart item quantity defined?
      if ( '' !== $args['input_value'] && $args['input_value'] >= 1 && $count == $args['input_value'] ) {
        $selected = 'selected';      
      } else $selected = '';
 
      $options .= '<option value="' . $count . '"' . $selected . '>' . $count . '</option>';
 
   }
     
   $string = '<div class="quantity"><span>Qty</span><select name="' . $args['input_name'] . '">' . $options . '</select></div>';
 
   if ( $echo ) {
      echo $string;
   } else {
      return $string;
   }
  
} 
like image 985
jmasked Avatar asked Dec 13 '25 03:12

jmasked


1 Answers

Caution: First you should never overwrite WooCommerce core files, for many reasons. So it's prohibited.

Instead as woocommerce_quantity_input() function call the template file global/quantity-input.php, you can override that template via your child theme.

To understand how to override templates, read carefully: Overriding templates via a theme in WooCommerce.

Now, remove all your related quantity changes and code from you web site (restore everything as before).

Then copy quantity-input.php file located inside WooCommerce plugin > templates > global, to your child theme into a "woocommerce" folder > "global" subfolder.

Once done, open / edit it, and replace the template content with:

<?php
/**
 * Product quantity inputs
 *
 * This template can be overridden by copying it to yourtheme/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/
 * @package WooCommerce\Templates
 * @version 4.0.0
 */

defined( 'ABSPATH' ) || exit;

if ( $max_value && $min_value === $max_value ) {
    ?>
    <div class="quantity hidden">
        <input type="hidden" id="<?php echo esc_attr( $input_id ); ?>" class="qty" name="<?php echo esc_attr( $input_name ); ?>" value="<?php echo esc_attr( $min_value ); ?>" />
    </div>
    <?php
} 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' );
    ?>
    <div class="quantity">
        <?php do_action( 'woocommerce_before_quantity_input_field' ); ?>
        <label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>"><?php echo esc_attr( $label ); ?></label>
        <?php
        if ( is_cart() ) :
        ?>
        <input
            type="hidden"
            id="<?php echo esc_attr( $input_id ); ?>"
            class="<?php echo esc_attr( join( ' ', (array) $classes ) ); ?>"
            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' );
        ?>" />
        <?php
        endif;

        $options = ''; // Initializing

        for ( $i = $min_value; $i <= $max_value; $i += $step ) :
            $selected = ( '' !== $input_value && $input_value >= 1 && $i == $input_value ) ? 'selected' : '';
            $options .= '<option value="' . $i . '"' . $selected . '>' . $i . '</option>';
        endfor;
        // Change input name on select field
        $attr_name = is_cart() ? 'data-name' : 'name';
        ?>
            <select <?php echo $attr_name; ?>="<?php echo $input_name; ?>"><?php echo $options; ?></select>
        <?php do_action( 'woocommerce_after_quantity_input_field' ); ?>
    </div>
    <?php
}

Now some jQuery code is required, to make things work on cart page.

// jQuery - cart jQuery script for quantity dropdown
add_action( 'woocommerce_after_cart', 'cart_quantity_dropdown_js' );
function cart_quantity_dropdown_js() {
    ?>
    <script type="text/javascript">
    jQuery( function($){
        $(document.body).on('change blur', 'form.woocommerce-cart-form .quantity select', function(e){
            var t = $(this), q = t.val(), p = t.parent();
            $(this).parent().find('input').val($(this).val());
            console.log($(this).parent().find('input').val());
        });
    });
    </script>
    <?php
}

This code goes in functions.php file of the active child theme (or active theme).


Now to restrict the max quantity to 6, add the following code:

// Restricting product max quantity to 6  
add_filter( 'woocommerce_quantity_input_args', 'woocommerce_quantity_input_args_callback', 10, 2 );
function woocommerce_quantity_input_args_callback( $args, $product ) {
    $args['max_value'] = 6;

    return $args;
}

// Restricting product variation max quantity to 6
add_filter( 'woocommerce_available_variation', 'filter_woocommerce_available_variation', 10, 3);
function filter_woocommerce_available_variation( $data, $product, $variation ) {
    $data['max_qty'] = 6;

    return $data;
}

This code goes in functions.php file of the active child theme (or active theme).

Now it works everywhere (tested on last WooCommerce version under Storefront theme).

like image 109
LoicTheAztec Avatar answered Dec 14 '25 19:12

LoicTheAztec