WooCommerce结账表单验证失败仍可提交问题求助
嘿,我来帮你搞定这个问题!你现在的情况是:出生日期字段能实时弹出验证错误提示,但即使错误提示还在,用户点“Place order”还是能提交订单——这是因为你只初始化了jQuery Validate插件,但没给字段绑定明确的验证规则,而且WooCommerce的下单按钮有自己的提交逻辑,默认会绕过验证直接提交。
你的原始问题与代码
我在WooCommerce结账页面实现了出生日期验证功能:当用户在出生日期字段输入日期大于31或月份大于12时,按键时会弹出提示信息“Please enter valid date (dd-mm-yyyy)”,该提示功能目前正常,但表单填写完成后,即使验证提示仍存在,订单仍能成功提交。
原始代码如下:
<script> jQuery(document).ready(function(){ jQuery.validator.addMethod( "dateUS", function(value, element) { var check = false; var re = /^\d{1,2}\-\d{1,2}\-\d{4}$/; if( re.test(value)){ var adata = value.split('-'); var dd = parseInt(adata[0],10); var mm = parseInt(adata[1],10); var yyyy = parseInt(adata[2],10); var xdata = new Date(yyyy,mm-1,dd); if ( ( xdata.getFullYear() == yyyy ) && ( xdata.getDate() == dd ) && ( xdata.getMonth () == mm - 1 ) ) check = true; else check = false; } else check = false; return this.optional(element) || check; }, "Please enter a valid date (dd-mm-yyyy)" ); // attach Validate plugin to form jQuery(".checkout").validate(); }); </script> <form name="checkout" method="post" class="checkout woocommerce-checkout" action="https://dev.clipcertification.com/checkout/" enctype="multipart/form-data" novalidate="novalidate"> <!--- other fields--> <input type="text" class="input-text dateUS error" name="billing_dateofbirth" id="billing_dateofbirth" placeholder="Birthdate * (dd-mm-yyyy)" value="02-55-1285" maxlength="10" aria-invalid="true"> <!--- other fields--> <input type="submit" class="button alt" name="woocommerce_checkout_place_order" id="place_order" value="Place order" data-value="Place order">
解决方案:绑定规则+拦截提交
咱们需要做两个关键修改,确保验证不通过时表单无法提交:
修改后的完整代码
<script> jQuery(document).ready(function(){ // 自定义日期验证方法(保留你的逻辑,重命名避免冲突) jQuery.validator.addMethod( "dateDDMMYYYY", function(value, element) { var check = false; var re = /^\d{1,2}\-\d{1,2}\-\d{4}$/; if( re.test(value)){ var adata = value.split('-'); var dd = parseInt(adata[0],10); var mm = parseInt(adata[1],10); var yyyy = parseInt(adata[2],10); var xdata = new Date(yyyy, mm - 1, dd); // 验证日期合法性(拦截无效日期如2月30日、13月等) if (xdata.getFullYear() === yyyy && xdata.getDate() === dd && xdata.getMonth() === mm - 1) { check = true; } else { check = false; } } else { check = false; } return this.optional(element) || check; }, "Please enter a valid date (dd-mm-yyyy)" ); // 初始化Validate插件,添加字段验证规则 jQuery(".checkout").validate({ rules: { // 给出生日期字段绑定规则:必填+符合自定义日期格式 billing_dateofbirth: { required: true, dateDDMMYYYY: true } }, // 错误提示位置(贴合WooCommerce布局) errorPlacement: function(error, element) { error.insertAfter(element); } }); // 拦截WooCommerce下单按钮的默认提交行为 jQuery('#place_order').on('click', function(e) { // 检查表单是否通过所有验证 if (!jQuery(".checkout").valid()) { e.preventDefault(); // 阻止表单提交 e.stopPropagation(); return false; } // 验证通过则正常提交 return true; }); }); </script> <form name="checkout" method="post" class="checkout woocommerce-checkout" action="https://dev.clipcertification.com/checkout/" enctype="multipart/form-data" novalidate="novalidate"> <!--- other fields--> <input type="text" class="input-text" name="billing_dateofbirth" id="billing_dateofbirth" placeholder="Birthdate * (dd-mm-yyyy)" value="" maxlength="10"> <!--- other fields--> <input type="submit" class="button alt" name="woocommerce_checkout_place_order" id="place_order" value="Place order" data-value="Place order">
关键修改说明
明确绑定验证规则:在
.validate()里添加rules配置,告诉插件要验证billing_dateofbirth字段,既要求必填,又要符合自定义的日期格式。另外把自定义方法名从dateUS改成dateDDMMYYYY,避免和jQuery Validate内置的美式日期规则(mm/dd/yyyy)混淆。拦截按钮提交行为:WooCommerce的下单按钮自带JS逻辑,会跳过前端验证直接提交,所以咱们监听它的点击事件,先调用
.valid()检查表单状态,验证不通过就阻止提交。清理字段类名:去掉了字段上手动添加的
error和dateUS类,这些类应该由Validate插件根据验证状态自动添加,手动添加会干扰插件的状态判断。
这样修改后,当用户输入无效日期或者未填写出生日期时,不仅会实时弹出提示,点击“Place order”也会被拦截,直到字段内容符合要求才能提交订单。
内容的提问来源于stack exchange,提问作者Neha Goyal

