skip to Main Content

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

2

Answers


  1. 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 WooCommerceTemplates
     * @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).

    Login or Signup to reply.
  2. The default WooCommerce Add to Cart “Quantity Input” is a simple input field where you can enter the number of items or click on the “+” and “-” to increase/reduce the quantity.

    To let the users choose the quantity from a drop-down instead of having to manually input the number. This can be done using woocommerce_quantity_input function. Simply add the following Snippet to your Functions.php.

    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 );
      
       
       $args['min_value'] = max( $args['min_value'], 0 );
       $args['max_value'] = 0 < $args['max_value'] ? $args['max_value'] : 20;
    
       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'] ) {
    
          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;
       }
      
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search