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">×</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 .= ' <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() . ' ';
} 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
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:
I added ID #sb-qty to the code:
The JS code first line was:
I changed to:
The dropdown working fine so far and only update when the quantity change.
Set Function follow me