Reputation: 45
I have been going in circles with this I have added an apply coupon field to mini-cart.php and am trying to get it to run without refreshing the whole page. Any suggestions would be amazing help.
functions:
function apply_coupon_code(){
$coupon_code = isset( $_POST["coupon_code"] ) ? $_POST["coupon_code"] : '';
WC()->cart->apply_coupon($coupon_code);
}
add_action( 'wp_ajax_apply_coupon_code', 'apply_coupon_code' );
add_action( 'wp_ajax_nopriv_apply_coupon_code', 'apply_coupon_code' );
Input:
<?php if (empty (WC()->cart->get_coupons())): ?>
<span id="coupon-form">
<?php if ( wc_coupons_enabled() ) { ?>
<form class="widget_shopping_cart_content" action="<?php echo $cart_url ?>" method="post">
<?php } else { ?>
<form id="apply-promo-code" class="widget_shopping_cart__coupon">
<?php } ?>
<label id="promo-code" for="coupon-code">Promo Code:</label>
<input id="minicart-coupon" class="input-text" type="text" value="" name="coupon_code"/>
<button type="submit" id="minicart-apply-button" class="button" name="apply_coupon" value="<?php esc_attr_e( 'Apply coupon', 'woocommerce' ); ?>"><?php esc_attr_e( 'Apply', 'woocommerce' ); ?></button>
<?php do_action( 'woocommerce_cart_coupon' ); ?>
<?php do_action( 'woocommerce_cart_actions' ); ?>
</form>
<?php endif; ?>
<?php foreach ( WC()->cart->get_coupons() as $code => $coupon ) : ?>
<span id="widget-shopping-cart-remove-coupon" class="mini_cart_coupon-<?php echo esc_attr( sanitize_title( $code ) ); ?>">
Promo Code: <?php echo esc_attr( sanitize_title( $code ) ); ?>
<?php $remove_url = $cart_url.'?remove_coupon='.$coupon->code; ?>
<?php wc_cart_totals_coupon_html( $coupon ); ?>
</span>
<?php endforeach; ?>
jQuery:
jQuery(document).on('click', 'button#minicart-apply-button', function() {
var coupon = jQuery( 'input#minicart-coupon' ).val();
var button = ( this );
var data = {
action: "apply_coupon_code",
coupon_code: "coupon"
};
jQuery.ajax({
type: 'POST',
dataType: 'json',
url: wc_add_to_cart_params.ajax_url,
data: data,
success: function (response) {
console.log(response);
},
error: function (errorThrown) {
console.log(errorThrown);
}
});
});
Upvotes: 2
Views: 2258
Reputation: 2823
You can get the new mini cart HTML inside your ajax callback on the server and then return that as a response to the jQuery ajax call then simply replace the whole mini cart HTML on the front-end with the updated HTML.
function apply_coupon_code(){
$coupon_code = isset( $_POST["coupon_code"] ) ? $_POST["coupon_code"] : '';
WC()->cart->apply_coupon($coupon_code);
ob_start();
woocommerce_mini_cart();
$cart_html = ob_get_clean();
return $cart_html;
}
add_action( 'wp_ajax_apply_coupon_code', 'apply_coupon_code' );
add_action( 'wp_ajax_nopriv_apply_coupon_code', 'apply_coupon_code' );
The output buffer is used here as woocommerce_mini_cart
uses wc_get_template
which just echoes out the content. The output buffer will allow you to capture this as a string.
Now you need to tell jQuery that you're expecting HTML back from the server...
jQuery(document).on('click', 'button#minicart-apply-button', function() {
var coupon = jQuery( 'input#minicart-coupon' ).val();
var button = ( this );
var data = {
action: "apply_coupon_code",
coupon_code: "coupon"
};
jQuery.ajax({
type: 'POST',
dataType: 'html',
url: wc_add_to_cart_params.ajax_url,
data: data,
success: function (response) {
console.log(response);
},
error: function (errorThrown) {
console.log(errorThrown);
}
});
});
Now response
will have the new HTML for the mini-cart, so you can replace it using jQuery's html()
function...
success: function (response) {
console.log(response);
jQuery('.mini-cart-wrapper').html(response);
},
Upvotes: 4