The WooCommerce coupon field at the top of the checkout page seems to be a common problem. Shop owners want it towards the bottom of the page around the payment details section. After not finding an ideal solution to this problem online, I came up with a way to move the coupon code field to almost anywhere in the checkout page.
Why is the coupon field at the top of the page?
By default, the coupon code field shipped with WooCommerce is placed at the top of the checkout page before and outside of the main checkout form. The reason for this is because the apply coupon functionality is a form itself and when nested inside the main checkout form, will lead to submitting the checkout form which is not what the user wants. The apply coupon form is an ajax call to the server and reloads the payment grid. The trick to moving the coupon code field inside the checkout form is to create a modal dialog window and put the coupon code html inside the modal dialog window. This modal dialog window acts independently of the checkout form. Thus, apply coupon works correctly instead of submitting the checkout form. In the remaining article, I will explore all the steps described to implement this behavior.
How to move the coupon field anywhere?
1. To implement this, we will use the jQuery UI Dialog library to help us with the dialog functionality. In your functions.php, add the code below if your site does not already include the jQuery UI Dialog library.
/** * Need the jQuery UI library for dialogs. **/ function ttp_scripts() { wp_enqueue_script('jquery-ui-dialog'); } add_action('wp_enqueue_scripts', 'ttp_scripts');
2. Next, instantiate a jQuery modal dialog with the contents of the coupon html code. Set the position of the modal dialog to anchor to a html element inside the checkout form. You can place the html element anywhere in the checkout form using existing WooCommerce actions or filters. When the user clicks on the link to reveal the coupon code field, the modal dialog will appear where you set the html element. In addition, you would also want to make the modal window transparent and disable user dragging. This will make the modal window blend into the rest of the form nicely.
In functions.php, add the code below.
/** * Processing before the checkout form to: * 1. Hide the existing Click here link at the top of the page. * 2. Instantiate the jQuery dialog with contents of * form.checkout_coupon which is in checkout/form-coupon.php. * 3. Bind the Click here link to toggle the dialog. **/ function ttp_wc_show_coupon_js() { /* Hide the Have a coupon? Click here to enter your code section * Note that this flashes when the page loads and then disappears. * Alternatively, you can add a filter on * woocommerce_checkout_coupon_message to remove the html. */ wc_enqueue_js('$("a.showcoupon").parent().hide();'); /* Use jQuery UI's dialog feature to load the coupon html code * into the anchor div. The width controls the width of the * modal dialog window. Check here for all the dialog options: * http://api.jqueryui.com/dialog/ */ wc_enqueue_js('dialog = $("form.checkout_coupon").dialog({ autoOpen: false, width: 500, minHeight: 0, modal: false, appendTo: "#coupon-anchor", position: { my: "left", at: "left", of: "#coupon-anchor"}, draggable: false, resizable: false, dialogClass: "coupon-special", closeText: "Close", buttons: {}});'); /* Bind the Click here to enter coupon link to load the * jQuery dialog with the coupon code. Note that this * implementation is a toggle. Click on the link again * and the coupon field will be hidden. This works in * conjunction with the hidden close button in the * optional CSS in style.css shown below. */ wc_enqueue_js('$("#show-coupon-form").click( function() { if (dialog.dialog("isOpen")) { $(".checkout_coupon").hide(); dialog.dialog( "close" ); } else { $(".checkout_coupon").show(); dialog.dialog( "open" ); } return false;});'); } add_action('woocommerce_before_checkout_form', 'ttp_wc_show_coupon_js', 10);
3. Finally, add the ‘Click here to enter your code’ link to show the coupon field. The code below adds the link after the customer details section and before the order details section. To explore other areas to put this link. Check the existing actions and filters on the checkout page. E.g., woocommerce_checkout_fields, woocommerce_before_checkout_billing_form. As a last resort, you can also override the WooCommerce checkout page templates and put the link anywhere you want on the checkout page.
/** * Show a coupon link above the order details section. * This is the 'coupon-anchor' div which the modal dialog * window will attach to. **/ function ttp_wc_show_coupon() { global $woocommerce; if ($woocommerce->cart->needs_payment()) { echo '<p style="padding-bottom: 5px;"> Have a coupon? <a href="#" id="show-coupon-form">Click here to enter your code</a>.</p><div id="coupon-anchor"></div>'; } } add_action('woocommerce_checkout_after_customer_details', 'ttp_wc_show_coupon', 10);
4. These are optional css styles to make the jQuery dialog behave correctly for most display devices. In style.css, add the code below.
/* Optional */ #checkout_cart input#coupon_code { width:auto; } /* Style to overcome jQuery dialog's inline styling on the coupon dialog (Optional) */ .ui-dialog.ui-widget.ui-widget-content.ui-corner-all.ui-front.coupon-special { position: relative; top: 0 !important; left: 0 !important; border: 0; } /* Remove the close coupon field button (Optional) */ .ui-widget-header { display:none; }
Relocated coupon field in action
Notes
- The idea for the show coupon link came from this article, sellwithwp Everything else relating to the modal dialog window and click here toggle button is copyright TAM’S TRADING POST.
- Requires jQuery UI for the dialog functionality. Check here for all jQuery dialog options. jQuery dialog options
- All of the code has been tested using WordPress 4.5.2 and WooCommerce 2.5.5.
- Updated on May 16, 2016 to use the WordPress included jQuery UI Dialog library instead of loading an external javascript file.
Epic solution! It was a great help for me.
Just wanted to point out that actually you don’t need to include jQuery-UI to use Dialog because it is in fact included in WordPress core https://github.com/WordPress/WordPress/blob/master/wp-includes/js/jquery/ui/dialog.min.js
Great and thanks. Even better.
Thank you for sharing this code, it works great.
Never really liked the position of WooCommerce coupon fields form the beginning, and this helped me change that.
Just found this great post, and it inspired me to create a form-checkout.php file in my theme’s woocommerce folder, and simply move the starting code to right after the `do_action( ‘woocommerce_checkout_before_customer_details’ );` line, then used these two lines to move the coupon form down to under the Order Review display, worked great:
remove_action( ‘woocommerce_before_checkout_form’, ‘woocommerce_checkout_coupon_form’, 10 );
add_action( ‘woocommerce_checkout_after_order_review’, ‘woocommerce_checkout_coupon_form’ );
Without moving the form code, it wouldn’t work due to the form within a form issue you mentioned, but once moved, works easily.
Hi, which file do I need to edit if i don’t want user to click the link to apply the coupon code?
In simple, I want no LINK to be clicked on.
I want the apply coupon appear below the text “Have a coupon?” so that user can ALWAYS see the section.
Thanks.
Check the WooCommerce template /checkout/form-coupon.php. I believe it is hidden using CSS by default. Then you’ll want to remove the Click here to enter your code link.
Thank you for your response. However, I tried this before many times but still didn’t come up with any result that I wanted. Its okay then, I just have to move on from this. Thanks for your time.