在WooCommerce中的订单跟踪中,在提交跟踪表单时,跟踪结果会显示为一个全新的页面。然而,我想看到的是AJAX中的结果。
以下是wooccommerce/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>
我试着在关闭表单标记之后的同一个文件中,在脚本标记中添加这个:
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.
}
}
我在大约5年前的另一个问题中发现了这个jQuery,但jQuery似乎没有做出任何改变,订单跟踪结果仍然显示为全新的页面。我不知道我还应该补充什么,也不知道是否有什么不对劲。我应该在另一个文件中添加jQuery吗?我应该在jQuery中添加更多还是进行更多修改?
谢谢大家,我真是个笨蛋!
有几件事是错误的。一个提示是首先检查浏览器控制台中的任何错误。里面应该有一些。
第一个可能的问题:
在submit()
处理程序中返回false可以阻止表单提交,但只有在没有错误的情况下。一个更好的方法(也允许您轻松地查看浏览器控制台日志(是使用event.preventDefault()
$('.track_order').submit(function(event) { // <-- add event as argument here
event.preventDefault(); // <-- better way to prevent form from submitting
// Rest of your script code
}
第二个可能的问题:
$
可能不存在。在Wordpress中,您可能应该在代码中使用jQuery
,而不是$
的简写(除非您定义了$
(。所以第一步是用<script>
标签内部的jQuery替换$
。
jQuery('.track_order').submit(function(event) { // <-- replace $ by jQuery
event.preventDefault();
jQuery.ajax({ // // <-- replace $ by jQuery
data: formData,
type: jQuery(this).attr('method'), // <-- replace $ by jQuery
url: jQuery(this).attr('action'), // <-- replace $ by jQuery
success: function(response) {
jQuery('.track-results').html(response); // <-- replace $ by jQuery
}
});
});
第三个可能的问题:
确保您在某个地方有一个带有类"track results"的HTML元素,这样数据就可以在通过AJAX加载后显示。
<div class="track-results"></div>
第四个可能的问题:
FormData
不能像那样与jQuery的ajax()
方法协同工作,因为jQuery想要字符串化,但当数据作为FormData
对象提供时,它不应该这样做。
两种可能的解决方案:
解决方案1-执行ajax()
请求时,将processData
和contentType
设置为false
jQuery.ajax({
processData: false,
contentType: false,
// All the other fields
});
OR解决方案2-只需使用简单的JavaScript对象而不是FormData
var formData = {
'from_ajax': '1'
}
而不是
var formData = new FormData();
formData.append('from_ajax', '1');
第五个可能的问题:
脚本的最后一部分是PHP,不应该出现在JS脚本标记中:
if(isset($_POST['from_ajax']){
if($_POST['from_ajax'] == 1){
// do not load header or footer , just load required view to display.
}
}
相反,它应该在表单.的action
属性中提到的PHP文件中
一些额外信息:
也不要只是去编辑Wordpress的核心文件。您可能可以使用Wordpress中的AJAX操作来做您需要做的事情。尽管在我看来,文档对初学者来说不是很友好,但它是:https://developer.wordpress.org/plugins/javascript/ajax/
WP Codex中的这个旧条目实际上可能会以更简单的方式解释基础:https://codex.wordpress.org/AJAX_in_Plugins
完整示例:
我在这里通过包括WP/WP-load.php来加载WP核心,这样我就可以使用WP函数,并且我已经将action
属性设置为测试文件本身。只是为了给你一个完整的例子,包含在一个文件中。
<?php
include 'wp/wp-load.php';
if (isset($_POST['from_ajax']) && $_POST['from_ajax'] == 1) {
die('tada! here is the example response ...');
}
?>
<form action="test.php" 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>
<div class="track-results">result will be shown here</div>
<script src="https://code.jquery.com/jquery-3.5.0.min.js"></script>
<script>
var formData = new FormData();
formData.append('from_ajax', '1');// append this to your form.
jQuery('.track_order').submit(function(event) { // catch the form's submit event
event.preventDefault(); // prevent form submit
jQuery.ajax({ // create an AJAX call...
data: formData, // get the form data
processData: false,
contentType: false,
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
}
});
});
</script>
我希望这能帮到你!
<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>
<script>
jQuery('.track_order').submit(function(event) {
event.preventDefault();
var formData = new FormData(this);
jQuery.ajax({
data: formData,
processData: false,
contentType: false,
type: jQuery(this).attr('method'),
url: 'tracking.php',
success: function(response) {
var orderInfo = jQuery(response).find('.woocommerce').html();
jQuery('.track_order').html(orderInfo); // update the DIV
}
});
});
</script>
这就是tracking.php
$notes = $order->get_customer_order_notes();
?>
<p class="order-info">
<?php
echo wp_kses_post(
apply_filters(
'woocommerce_order_tracking_status',
sprintf(
/* translators: 1: order number 2: order date 3: order status */
__( 'Order #%1$s was placed on %2$s and is currently %3$s.', 'woocommerce' ),
'<mark class="order-number">' . $order->get_order_number() . '</mark>',
'<mark class="order-date">' . wc_format_datetime( $order->get_date_created() ) . '</mark>',
'<mark class="order-status">' . wc_get_order_status_name( $order->get_status() ) . '</mark>'
)
)
);
?>
</p>
<?php if ( $notes ) : ?>
<h2><?php esc_html_e( 'Order updates', 'woocommerce' ); ?></h2>
<ol class="commentlist notes">
<?php foreach ( $notes as $note ) : ?>
<li class="comment note">
<div class="comment_container">
<div class="comment-text">
<p class="meta"><?php echo date_i18n( esc_html__( 'l jS of F Y, h:ia', 'woocommerce' ), strtotime( $note->comment_date ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></p>
<div class="description">
<?php echo wpautop( wptexturize( $note->comment_content ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</div>
<div class="clear"></div>
</div>
<div class="clear"></div>
</div>
</li>
<?php endforeach; ?>
</ol>
<?php endif; ?>
<?php do_action( 'woocommerce_view_order', $order->get_id() ); ?>