skip to Main Content

I have added code in child theme function.php to add a dropdown quantity in the checkout page so customers can change the product quantity and the price auto update each time they chose a number.

The problem is that when I change the quantity value in the checkout page the price does not update. https://ibb.co/6JNDWgj.

the code to add the dropdown to the checkout page is

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 );
   // Note: change 20 to whatever you like
   $args['max_value'] = 0 < $args['max_value'] ? $args['max_value'] : 15;
 
   // 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;
   }
  
}

the code to add a field in the checkout page:

* It will remove the selected quantity count from checkout page table.
*/
function webroom_remove_quantity_count( $cart_item, $cart_item_key ) {
   $product_quantity= '';
   return $product_quantity;
}

add_filter ('woocommerce_checkout_cart_item_quantity', 'webroom_remove_quantity_count', 10, 2 );

/*
 * It will add Delete button, Quanitity field on the checkout page Your Order Table.
 */
function webroom_add_delete_and_quantity_on_checkout( $product_title, $cart_item, $cart_item_key ) {

/* Checkout page check */
if (  is_checkout() ) {
    /* Get Cart of the user */
    $cart     = WC()->cart->get_cart();
        foreach ( $cart as $cart_key => $cart_value ){
           if ( $cart_key == $cart_item_key ){
                $product_id = $cart_item['product_id'];
                $_product   = $cart_item['data'] ;
                
                /* Step 1 : Add delete icon */
                $return_value = sprintf(
                  '<a href="%s" class="remove" title="%s" data-product_id="%s" data-product_sku="%s">&times;</a>',
                  esc_url( wc_get_cart_remove_url( $cart_key ) ),
                  __( 'Delete', 'woocommerce' ),
                  esc_attr( $product_id ),
                  esc_attr( $_product->get_sku() )
                );
                
                /* Step 2 : Add product name */
                $return_value .= '&nbsp; <span class = "product_name" >' . $product_title . '</span>' ;
                
                /* Step 3 : Add quantity selector */
                if ( $_product->is_sold_individually() ) {
                  $return_value .= sprintf( ' <input type="hidden" name="cart[%s][qty]" value="1" />', $cart_key );
                } else {
                  $return_value .= woocommerce_quantity_input( array(
                      'input_name'  => "cart[{$cart_key}][qty]",
                      'input_value' => $cart_item['quantity'],
                      'max_value'   => $_product->backorders_allowed() ? '' : $_product->get_stock_quantity(),
                      'min_value'   => '1'
                      ), $_product, false );
                }
                return $return_value;
            }
        }
}else{
    /*
     * It will return the product name on the cart page.
     * As the filter used on checkout and cart are same.
     */
    $_product   = $cart_item['data'] ;
    $product_permalink = $_product->is_visible() ? $_product->get_permalink( $cart_item ) : '';
    if ( ! $product_permalink ) {
        $return_value = $_product->get_title() . '&nbsp;';
    } else {
        $return_value = sprintf( '<a href="%s">%s</a>', esc_url( $product_permalink ), $_product->get_title());
    }
    return $return_value;
  }
}

add_filter ('woocommerce_cart_item_name', 'webroom_add_delete_and_quantity_on_checkout' , 10, 3 );


/* Add js at the footer */
function webroom_add_quanity_js(){
  if ( is_checkout() ) {
    wp_enqueue_script( 'checkout_script', get_stylesheet_directory_uri() . '/js/add_quantity.js', '', '', false );
    $localize_script = array(
      'ajax_url' => admin_url( 'admin-ajax.php' )
    );
    wp_localize_script( 'checkout_script', 'add_quantity', $localize_script );
  }
}
add_action( 'wp_footer', 'webroom_add_quanity_js', 10 );
function webroom_load_ajax() {
  if ( !is_user_logged_in() ){
      add_action( 'wp_ajax_nopriv_update_order_review', 'webroom_update_order_review' );
  } else{
      add_action( 'wp_ajax_update_order_review', 'webroom_update_order_review' );
  }
}
add_action( 'init', 'webroom_load_ajax' );
function webroom_update_order_review() {
  $values = array();
  parse_str($_POST['post_data'], $values);
  $cart = $values['cart'];
  foreach ( $cart as $cart_key => $cart_value ){
      WC()->cart->set_quantity( $cart_key, $cart_value['qty'], false );
      WC()->cart->calculate_totals();
      woocommerce_cart_totals();
  }
  wp_die();
}

the code inside the "/js/add_quantity.js":

jQuery(function( $ ) {
    $( "form.checkout" ).on( "click", "input.qty", function( e ) {
      var data = {
      action: 'update_order_review',
      security: wc_checkout_params.update_order_review_nonce,
      post_data: $( 'form.checkout' ).serialize()
    };

    jQuery.post( add_quantity.ajax_url, data, function( response )
    {
      $( 'body' ).trigger( 'update_checkout' );
    });
  });
});

I changed the line to above with .change

$( "form.checkout" ).change( function( e ) {

and I ended having an infinite loop. the order keep auto refresh each 2 seconds. How can I fix this issue where the price only update once when the quantity change?

2

Answers


  1. Chosen as BEST ANSWER

    I was able to achieve it by giving an ID to the div in the 1st code posted and a small change in the JS file.

    The code was:

    $string = '<div class="quantity"><span>Qty</span><select name="' . $args['input_name'] . '">' . $options . '</select></div>';
    

    I added ID #sb-qty to the code:

    $string = '<div id="sb-qty" class="quantity"><span>Qty</span><select name="' . $args['input_name'] . '">' . $options . '</select></div>';
    

    The JS code first line was:

    $( "form.checkout" ).on( "click", "input.qty", function( e ) {
    

    I changed to:

    $( "form.checkout" ).on('change', '#sb-qty', function( e ) {
    

    The dropdown working fine so far and only update when the quantity change.


  2. Set Function follow me

    function webroom_update_order_review() {
      parse_str($_POST['post_data'], $values);
      $cart = $values['cart'];
    global $woocommerce;
      foreach ( $cart  as $cart_key => $cart_value ){
                $woocommerce->cart->set_quantity( $cart_key, $cart_value['qty'], true );
            }
      exit();
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search