In order tracking in WooCommerce, track results are displayed as a whole new page when submitting the tracking form. However, what I wanted to see are the results in AJAX.
Here is the form in woocommerce/templates/order/form-tracking.php:
<form action="<?php echo esc_url( get_permalink( $post->ID ) ); ?>" method="post" class="woocommerce-form woocommerce-form-track-order track_order">
<p><?php esc_html_e( 'To track your order, please enter your Order ID and the email you used during checkout. You can find these in your receipt and confirmation email.', 'woocommerce' ); ?></p>
<p class="form-row form-row-first"><label for="orderid"><?php esc_html_e( 'Order ID', 'woocommerce' ); ?></label> <input class="input-text" type="text" name="orderid" id="orderid" value="<?php echo isset( $_REQUEST['orderid'] ) ? esc_attr( wp_unslash( $_REQUEST['orderid'] ) ) : ''; ?>" placeholder="<?php esc_attr_e( 'Found in your order confirmation email.', 'woocommerce' ); ?>" /></p><?php // @codingStandardsIgnoreLine ?>
<p class="form-row form-row-last"><label for="order_email"><?php esc_html_e( 'Billing email', 'woocommerce' ); ?></label> <input class="input-text" type="text" name="order_email" id="order_email" value="<?php echo isset( $_REQUEST['order_email'] ) ? esc_attr( wp_unslash( $_REQUEST['order_email'] ) ) : ''; ?>" placeholder="<?php esc_attr_e( 'Email you used during checkout.', 'woocommerce' ); ?>" /></p><?php // @codingStandardsIgnoreLine ?>
<div class="clear"></div>
<p class="form-row"><button type="submit" class="button" name="track" value="<?php esc_attr_e( 'Track', 'woocommerce' ); ?>"><?php esc_html_e( 'Track', 'woocommerce' ); ?></button></p>
<?php wp_nonce_field( 'woocommerce-order_tracking', 'woocommerce-order-tracking-nonce' ); ?>
</form>
I tried adding this in the same file right after the closing form tag and within the script tag:
var formData = new FormData();
formData.append('from_ajax', '1');// append this to your form.
$('.track_order').submit(function() { // catch the form's submit event
$.ajax({ // create an AJAX call...
data: formData, // get the form data
type: $(this).attr('method'), // GET or POST
url: $(this).attr('action'), // the file to call
success: function(response) { // on success..
$('.track-results').html(response); // update the DIV
}
});
return false; // cancel original event to prevent form submitting
});
if(isset($_POST['from_ajax']){
if($_POST['from_ajax'] == 1){
// do not load header or footer , just load required view to display.
}
}
I’ve found this jQuery from another question asked almost 5 years ago, but the jQuery doesn’t seem to make any change, the order track results still show as whole new page. I don’t know what else I should add or if anything is amiss. Should I add the jQuery in another file? Should I add more or make any more modifications in the jQuery?
Thank you all, I’m a total noob!
2
Answers
A couple of things are wrong. One tip is to check out any errors in the browser console first. There should be some in there.
First possible problem:
Returning false in the
submit()
handler could work to prevent the form from submitting, but only when there are no errors. A better way (also allowing you to keep seeing the browser console log easily) would be to useevent.preventDefault()
Second possible problem:
$
might not exist. In WordPress, you should probably usejQuery
in this code instead of the$
shorthand (unless you define$
). So first step would be to replace the$
by jQuery inside of the<script>
tags.Third possible problem:
Make sure you actually have a HTML element with class ‘track-results’ somewhere so the data can be displayed after loading through AJAX.
Fourth possible problem:
FormData
does not work together with jQuery’sajax()
method like that, because jQuery wants to stringify that, but it shouldn’t do that when the data is supplied as aFormData
object.Two possible solutions:
Solution 1 – Set
processData
andcontentType
tofalse
when doing theajax()
requestOR solution 2 – Simply use a plain JavaScript object instead of
FormData
instead of
Fifth possible problem:
This last part of your script is PHP and should not be in the JS script tags:
Instead, it should be in the PHP file mentioned in the
action
attribute of the form.Some extra information:
Don’t just go and edit core WordPress files either. You can probably do what you need to do using an AJAX action in WordPress. Although the documentation is not very beginner friendly in my opinion, here it is: https://developer.wordpress.org/plugins/javascript/ajax/
This older entry in the WP Codex might actually explain the basics in a simpler way: https://codex.wordpress.org/AJAX_in_Plugins
Full example:
I’m loading WP core here by including wp/wp-load.php so I can use the WP functions, and I have set the
action
attribute to be the test file itself. Just so I can give you a complete example contained in one file.I hope this helps you out!
and this is the tracking.php