The bricks builder has a native side cart element (Mini Cart) for the WooCommerce site. In this tutorial, I shall show how we can add the quantity field with the ‘+’ and ‘-‘ buttons there. So the customer can easily update the cart item’s quantity from there without any page refresh.

Step 1: Adding the Quantity Input Field
Add the following PHP code to your site. You can use the Bricks Child theme’s function.php file or any 3rd party snippets plugin like WPCodex.[edd_restrict id=”12,14,2474,3068,96772,98850,98847,98844,98841″ message=”Customers of BricksUltimate addon can view this content after login to the site. Non-BricksUltimate addon’s users will buy this tutorial separately. See the BUY NOW button below.”]
/**
* Add quantity field to bricks mini cart element
*/
add_filter( 'woocommerce_widget_cart_item_quantity', 'buwoo_mini_cart_quantity', 10, 3 );
function buwoo_mini_cart_quantity( $price, $cart_item, $cart_item_key ) {
$product_price = apply_filters( 'woocommerce_cart_item_price', WC()->cart->get_product_price( $cart_item['data'] ), $cart_item, $cart_item_key );
if ( WC()->cart->display_prices_including_tax() ) {
$product_price = wc_get_price_including_tax( $cart_item['data'] );
} else {
$product_price = wc_get_price_excluding_tax( $cart_item['data'] );
}
/* WPC Product Bundles */
if ( ( isset( $cart_item['woosb_ids'], $cart_item['woosb_price'], $cart_item['woosb_fixed_price'] ) && ! $cart_item['woosb_fixed_price'] )
|| ( isset( $cart_item['woosb_parent_id'], $cart_item['woosb_price'], $cart_item['woosb_fixed_price'] ) && $cart_item['woosb_fixed_price'] ) ) {
$product_price = $cart_item['woosb_price'];
}
$product = $cart_item['data'];
$quantity = $cart_item['quantity'];
$args = array(
'input_id' => uniqid( 'quantity_' ),
'input_name' => 'quantity',
'input_value' => $quantity,
'classes' => apply_filters( 'woocommerce_quantity_input_classes', array( 'input-text', 'qty', 'text' ), $product ),
'max_value' => apply_filters( 'woocommerce_quantity_input_max', $product->get_max_purchase_quantity(), $product ),
'min_value' => apply_filters( 'woocommerce_quantity_input_min', $product->get_min_purchase_quantity(), $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() : '',
'placeholder' => apply_filters( 'woocommerce_quantity_input_placeholder', '', $product ),
'autocomplete' => apply_filters( 'woocommerce_quantity_input_autocomplete', 'off', $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'] : '';
// Max cannot be lower than min if defined.
if ( '' !== $args['max_value'] && $args['max_value'] < $args['min_value'] ) {
$args['max_value'] = $args['min_value'];
}
if( class_exists( 'Morningtrain\WooAdvancedQTY\Plugin\Controllers\InputArgsController' ) ) {
$advnargs = Morningtrain\WooAdvancedQTY\Plugin\Controllers\InputArgsController::applyArgs(array(), $cart_item['product_id'], true);
if( isset( $advnargs['min_value'] ) && $advnargs['min_value'] > $args['min_value'] )
$args['min_value'] = $advnargs['min_value'];
if( isset( $advnargs['max_value'] ) && $advnargs['max_value'] > $args['max_value'] )
$args['max_value'] = $advnargs['max_value'];
}
ob_start();
/* 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( $args['input_id'] ); ?>"><?php echo esc_attr( $label ); ?></label>
<input
type="number"
id="<?php echo esc_attr( $args['input_id'] ); ?>"
class="<?php echo esc_attr( join( ' ', (array) $args['classes'] ) ); ?>"
step="<?php echo esc_attr( $args['step'] ); ?>"
min="<?php echo esc_attr( $args['min_value'] ); ?>"
max="<?php echo esc_attr( 0 < $args['max_value'] ? $args['max_value'] : '' ); ?>"
name="<?php echo esc_attr( $args['input_name'] ); ?>"
value="<?php echo esc_attr( $args['input_value'] ); ?>"
title="<?php echo esc_attr_x( 'Qty', 'Product quantity input tooltip', 'woocommerce' ); ?>"
size="4"
placeholder="<?php echo esc_attr( $args['placeholder'] ); ?>"
inputmode="<?php echo esc_attr( $args['inputmode'] ); ?>"
autocomplete="<?php echo esc_attr( isset( $args['autocomplete'] ) ? $args['autocomplete'] : 'on' ); ?>"
/>
<?php do_action( 'woocommerce_after_quantity_input_field' ); ?>
</div>
<?php
$price .= sprintf(
'<div class="qty-price-wrap" data-product_id="%d" data-cart_item_key="%s">
%s
<div class="item-total-price">%s</div>
</div>',
$cart_item['product_id'],
$cart_item_key,
ob_get_clean(),
wc_price( $cart_item['quantity'] * $product_price )
);
return $price;
}
Step 2: CSS Code
Adding the following CSS code into the Bricks Child theme’s style.css file or any 3rd party plugin.
.qty-price-wrap {
--bricks-woo-input-height: 20px;
display: flex;
width: auto;
justify-content: space-between;
margin-top: 7px;
}
.brxe-woocommerce-mini-cart .cart-detail li .qty-price-wrap .quantity {
border-style: solid;
border-width: 1px;
display: flex;
height: 22px;
margin-bottom: 0;
overflow: hidden;
width: 77px;
border-color: var( --bricks-border-color );
}
.qty-price-wrap input::-webkit-outer-spin-button,
.qty-price-wrap input::-webkit-inner-spin-button{
-webkit-appearance: none;
margin: 0;
display: none;
}
.qty-price-wrap .quantity .qty {
-moz-appearance: textfield;
-webkit-appearance: textfield;
appearance: textfield;
background-color: transparent;
border: none;
flex: 1;
font-size: 10px;
line-height: 1;
padding: 0;
text-align: center;
width: 25px;
order: 1;
}
.qty-price-wrap .quantity svg {
fill: currentColor;
height: 13px;
width: 13px;
}
.qty-price-wrap .quantity .minus,
.qty-price-wrap .quantity .plus {
align-items: center;
cursor: pointer;
display: flex;
justify-content: center;
}
.qty-price-wrap .quantity .action {
width: 25px;
}
.qty-price-wrap .quantity .minus {
border-right: 1px solid var( --bricks-border-color );
order: 0;
}
.qty-price-wrap .quantity .plus {
border-left: 1px solid var( --bricks-border-color );
order: 2;
}
Step 3: AJAX Action
We shall update the quantity value with AJAX and avoid the page refresh. Drop the following PHP snippets.
add_action( 'wp_ajax_buwoo_update_cart_item_quantity', 'buwoo_update_cart_item_quantity' );
add_action( 'wp_ajax_nopriv_buwoo_update_cart_item_quantity', 'buwoo_update_cart_item_quantity' );
function buwoo_update_cart_item_quantity() {
check_ajax_referer( 'bricks-nonce', 'security' );
$cart_key = sanitize_text_field( $_POST['cart_key'] );
$new_qty = wc_stock_amount(absint( $_POST['qty'] ));
$cart_item_data = WC()->cart->get_cart_item( $cart_key );
$product_id = apply_filters('woocommerce_add_to_cart_product_id', absint($_POST['product_id']));
$passed_validation = apply_filters('woocommerce_add_to_cart_validation', true, $product_id, $new_qty);
if( $passed_validation && $cart_key && ! empty( $cart_item_data ) ) {
$updated = $new_qty == 0 ? WC()->cart->remove_cart_item( $cart_key ) : WC()->cart->set_quantity( $cart_key, $new_qty );
if( $updated ){
wc_clear_notices();
\WC_AJAX::get_refreshed_fragments();
}
} else {
$data = array(
'error' => __( 'Failed. Something went wrong', 'bricksultimate' ),
);
wp_send_json($data);
}
}
JS snippets:
You can add this JS code at Dashboard->Bricks->Settings->Custom Code->Body(Footer) scripts or any 3rd party plugin.
<script type="text/javascript">
jQuery(document).ready(function($){
let itemBaseQty = 1;
let updateTimer;
$(document.body).on( 'focusin', '.qty-price-wrap .qty', function (e) {
itemBaseQty = $(e.currentTarget).val();
});
$(document.body).on('pointerdown', '.qty-price-wrap .action', function (e) {
var $toggler = $(e.currentTarget),
$input = $toggler.siblings('.qty');
if( !$input.length ) return;
var baseQty = itemBaseQty = parseFloat( $input.val() ),
step = parseFloat( $input.attr('step') ),
min = parseFloat( $input.attr('min') ),
max = parseFloat( $input.attr('max') ),
newQty = $toggler.hasClass( 'plus' ) ? baseQty + step : baseQty - step;
$input.val(newQty).trigger('change');
});
$(document.body).on('change', '.qty-price-wrap .qty', function(e) {
if ( typeof wc_cart_fragments_params === 'undefined' ) {
return false;
}
e.preventDefault();
var $input = $(e.currentTarget),
newQty = parseFloat( $input.val() ),
step = parseFloat( $input.attr('step') ),
min = parseFloat( $input.attr('min') ),
max = parseFloat( $input.attr('max') ),
invalid = false;
if( isNaN( newQty ) || newQty < 0 || newQty < min ) {
invalid = true;
}
else if( newQty > max ){
invalid = true;
}
else if( ( newQty % step ) !== 0 ) {
invalid = true;
}
if( invalid ){
$input.val( itemBaseQty );
return;
}
clearTimeout(updateTimer);
updateTimer = setTimeout(function () {
$row = $input.closest( '.woocommerce-mini-cart-item' );
$row.block({
message: null,
overlayCSS: {
opacity: 0.6
}
});
$.ajax({
url: wc_cart_fragments_params.ajax_url.toString(),
type: 'POST',
data: {
"action": 'buwoo_update_cart_item_quantity',
"cart_key": $input.closest('.qty-price-wrap').attr('data-cart_item_key'),
"product_id": $input.closest('.qty-price-wrap').attr('data-product_id'),
"qty": newQty,
"security": bricksData.nonce
},
dataType: 'json',
success: function(response){
if (response.error) {
$input.val( itemBaseQty );
return;
} else {
$(document.body).trigger('wc_fragment_refresh', [response.fragments, response.cart_hash, $input]);
}
},
complete: function() {
$row.unblock();
$(document.body).trigger("wc_update_cart");
$( document.body ).trigger( 'update_checkout' );
}
});
}, 2000);
});
});
</script>
All are done here. Now go to your frontend and check the mini cart after adding a product.[/edd_restrict]