You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WooCommerce结账页仅显示一次自定义验证错误提示且不影响支付跳转的实现方案

WooCommerce结账页仅显示一次自定义验证错误提示且不影响支付跳转的实现方案

嗨,我来帮你搞定这个问题~ 你遇到的核心问题是循环内重复添加全局错误提示,同时移到循环外后破坏了WooCommerce默认的验证流程导致无法跳转。下面是调整后的完整实现方案,能完美解决这两个问题:


修改后的PHP代码

重点调整了custom_checkout_validations函数的逻辑,解决重复提示和跳转问题:

add_action( 'woocommerce_after_checkout_form', 'add_custom_validation_script', 20 );

function add_custom_validation_script() {
    wp_enqueue_script(
        'inline_validation_script',
        get_stylesheet_directory_uri() . '/js/inline-validation.js',
        ['jquery']
    );
}

/**
 * adds error message field element to get inline error messages working
 * 
 * @param array $fields
 * @param object $errors
 */
add_filter( 'woocommerce_form_field', 'add_inline_error_messages_element', 10, 4 );

function add_inline_error_messages_element( $field, $key, $args, $value ) {
    if ( strpos( $field, '</span>' ) !== false ) {
        $error = '<span class="js-custom-error-message" style="display:none"></span>';
        $field = substr_replace( $field, $error, strpos( $field, '</span>' ), 0);
    }
    return $field;
}

/**
 * process custom checkout validations
 *
 * @param array $data
 * @param object $errors
 */
add_action('woocommerce_after_checkout_validation', 'custom_checkout_validations', 10, 2);

function custom_checkout_validations($data, $errors){
    // 标记是否存在必填字段错误
    $has_required_error = false;
    
    // 遍历所有错误,处理必填字段的错误提示和字段映射
    foreach( $errors->errors as $original_key => $error ) {
        $field_key = $original_key;

        // 处理WooCommerce原生的必填字段错误
        if(strpos($original_key, '_required') !== false) {
            $has_required_error = true;
            $field_key = str_replace('_required','', $original_key);
            $error[0] = __('This is a required field', 'YourThemeName');
        }
        
        // 移除原错误,添加带data-error-for的新错误(保持字段级提示正常工作)
        $errors->remove($original_key);
        $errors->add($original_key, trim($error[0]), ['error-for' => $field_key . '_field']);
    }
    
    // 仅当存在必填字段错误时,添加一次全局提示
    if($has_required_error) {
        // 先检查是否已经添加过这个全局错误,避免重复
        if( !$errors->get_error_code('validation') ) {
            $errors->add( 
                'validation', 
                __('O o o p s, looks like some info is missing. Please fill in all *Required fields so we can complete your order.', 'YourThemeName') 
            );
        }
    }
}

JS代码(无需修改,直接沿用)

原有的JS逻辑已经能很好地处理inline提示和全局提示的显示,直接保留即可:

jQuery(function ($) {
    'use strict';

    addInlineMessages();

    // Implementation

    // Listen to js event
    $(document.body).on('updated_checkout', function() {
        addInlineMessages();
    });

    function addInlineMessages() {
        var woocommerceErrorsEl = $('.woocommerce-error');
        var woocommerceInlineErrorsEl = $('li[data-error-for]', woocommerceErrorsEl);
        var inlineErrorMessagesEl = $('.js-custom-error-message');

        // as we use ajax submitting hide old validation messages
        if(inlineErrorMessagesEl.length) {
            inlineErrorMessagesEl.hide();
        }

        if(woocommerceInlineErrorsEl.length) {
            woocommerceInlineErrorsEl.each(function () {
                var errorEl = $(this);
                var errorText = $.trim(errorEl.text());

                var targetFieldId = errorEl.data('error-for');

                if(errorText && targetFieldId) {
                    var targetFieldEl = $('#' + targetFieldId);
                    var errorMessageField = $('.js-custom-error-message', targetFieldEl);

                    if(targetFieldEl.length && errorMessageField.length) {
                        targetFieldEl.addClass('woocommerce-invalid');

                        errorMessageField.text(errorText);
                        errorMessageField.show();
                        errorEl.hide();
                    }
                }
            });

            if(woocommerceInlineErrorsEl.filter(':visible').length === 0) { 
                if(inlineErrorMessagesEl.filter(':visible').length > 0) {
                    scrollToElement(inlineErrorMessagesEl.filter(':visible').first());
                }
            } else {
                $('li:not([data-error-for])', woocommerceErrorsEl).hide();;
                scrollToElement(woocommerceErrorsEl);
            }
        }
    }

    function scrollToElement(el) {
        if(el.length) {
            $([document.documentElement, document.body]).animate({
                scrollTop: el.offset().top - 100
            }, 2000);
        }
    }

    // event listeners
    $(document.body).on('checkout_error', function (event) {
        jQuery('html, body').stop();

        addInlineMessages();
    });
});

核心修改说明

  1. 解决重复提示问题:

    • 新增$has_required_error变量,仅标记是否存在必填字段错误,不再循环内重复添加全局提示
    • 循环结束后统一判断,仅添加一次全局错误,彻底避免重复显示
  2. 保证支付跳转正常:

    • 完整保留WooCommerce原生的错误处理结构,没有破坏验证判断逻辑
    • 全局错误的添加时机放在所有字段错误处理完成后,不会干扰WooCommerce原生的流程判断,填完必填字段后可正常跳转支付页
  3. 保留字段级提示功能:

    • 原有的data-error-for字段映射逻辑完全保留,每个空必填字段下方仍会显示This is a required field的inline提示

备注:内容来源于stack exchange,提问作者Hamza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 08:48:02