How to move the WooCommerce coupon

Posted on May 12, 2016

Posted by Henry Tam

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.

Show the coupon field at the bottom of the checkout page

Show the coupon field towards the bottom of 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);
Coupon code field hidden mode

Coupon code field hidden mode

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

Coupon code applied successfully graphic

Coupon code applied successfully graphic

Bad coupon code entered use case

Bad coupon code entered use case

Notes

  1. 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.
  2. Requires jQuery UI for the dialog functionality. Check here for all jQuery dialog options. jQuery dialog options
  3. All of the code has been tested using WordPress 4.5.2 and WooCommerce 2.5.5.
  4. Updated on May 16, 2016 to use the WordPress included jQuery UI Dialog library instead of loading an external javascript file.
How to move the WooCommerce coupon was last modified: May 16th, 2016 by Henry Tam

4 thoughts on “How to move the WooCommerce coupon

  1. Owais Alam

    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.

    Reply
  2. Rob - PressWizards.com

    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.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *