【问题标题】:Woocommerce: Any way to bypass and replace checkout form validation?Woocommerce:有什么方法可以绕过和替换结帐表单验证?
【发布时间】:2018-04-01 20:02:54
【问题描述】:

默认情况下,Woocommerce 会在结帐页面上的字段模糊后立即对其进行验证。因此,如果有人错误地点击了某个字段然后点击了出去,即使没有提交任何内容,该字段也会显示为“无效”。我们发现这种做法很烦人,并且可能会给用户带来压力。

我们想做的是更改验证,使其仅在单击“下订单”按钮(或一般提交表单)时启动。但是,我们不能完全删除 checkout.min.js,因为我们可能希望保留其他与字段验证无关的脚本。

我已经尝试过这种 hacky 方法来删​​除默认验证: jQuery(document.body).on('init_checkout', function (event) { setTimeout(function () { jQuery('.validate-required').removeClass('validate-required woocommerce-invalid woocommerce-invalid-required-field'); }, 1000); });

虽然这可以防止字段在模糊时变为红色,但页面仍会滚动到顶部并在单击“下订单”时显示错误,因此验证必须有其他内容。顶部的错误仅涉及信用卡字段,但...我们使用的是 Woocommerce Authorize.NET AIM 插件,因此可能与它有关。

有没有人做过类似的事情并且运气不错?

【问题讨论】:

    标签: jquery wordpress validation woocommerce authorize.net


    【解决方案1】:

    好的,我想出了一个很好的方法,以供将来参考。

    首先,将 checkout.js 从 WooCommerce javascript 文件夹复制到主题的 js 文件夹。

    然后将此添加到您主题的functions.php,取消注册默认脚本并将其替换为您的自定义版本:

    add_action( 'wp_enqueue_scripts', 'kg_replace_wc_scripts', 99 );
    function kg_replace_wc_scripts(){
        if( is_checkout() ){
            $path = get_template_directory_uri() . '/js/checkout.js';
            $time = filemtime($path);
            wp_deregister_script('wc-checkout');
            wp_register_script('wc-checkout', $path, 
            array( 'jquery', 'woocommerce', 'wc-country-select', 'wc-address-i18n' ), $time, TRUE);
            wp_enqueue_script('wc-checkout');
        }
    }
    

    (可选择使用 WC 版本作为版本字符串,但我喜欢使用 filemtime,因此每次修改文件时它都会在实时站点上更新,而无需清除缓存)

    然后在您的新checkout.js 中,注释掉或删除此行(此版本中的第 35 行):

    this.$checkout_form.on( 'input blur change', '.input-text, select, input:checkbox', this.validate_field );
    

    这将使用户休息一下,并在他们完成填写之前阻止字段验证。

    现在您需要向wc_checkout_form 添加一个新函数来一次处理所有字段的验证,这是我的:

    validate_all_fields: function() {
                var any_invalid = false;
                var ship_to_diff = $('#ship-to-different-address input').is(':checked');
    
                $('.kg-invalid-msg').fadeOut(500, function() {
                    $(this).remove();
                });
    
                $('.woocommerce-invalid').removeClass('woocommerce-invalid woocommerce-invalid-required-field');
    
                $('.validate-required').each(function() {
                    var $this             = $(this).find('input[type=checkbox],select,.input-text'),
                        $parent           = $this.closest( '.form-row' ),
                        validated         = true,
                        validate_required = $parent.is( '.validate-required' ),
                        validate_email    = $parent.is( '.validate-email' );
    
                    if (!ship_to_diff && $this.parents('.woocommerce-shipping-fields').length) {
                        return true;
                    }
    
                    if ( validate_required ) {
                        if ( 'checkbox' === $this.attr( 'type' ) && ! $this.is( ':checked' ) ) {
                            $parent.removeClass( 'woocommerce-validated' ).addClass( 'woocommerce-invalid woocommerce-invalid-required-field' );
                            validated = false;
                            any_invalid = true;
                        } else if ( $this.val() === '' ) {
                            $parent.removeClass( 'woocommerce-validated' ).addClass( 'woocommerce-invalid woocommerce-invalid-required-field' );
                            validated = false;
                            any_invalid = true;
                        }
                    }
    
                    if ( validate_email ) {
                        if ( $this.val() ) {
                            /* https://stackoverflow.com/questions/2855865/jquery-validate-e-mail-address-regex */
                            var pattern = new RegExp(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i);
    
                            if ( ! pattern.test( $this.val()  ) ) {
                                $parent.removeClass( 'woocommerce-validated' ).addClass( 'woocommerce-invalid woocommerce-invalid-email' );
                                validated = false;
                                any_invalid = true;
                            }
                        }
                    }
    
                    if ( validated ) {
                        $parent.removeClass( 'woocommerce-invalid woocommerce-invalid-required-field woocommerce-invalid-email' ).addClass( 'woocommerce-validated' );
                    }
                });
    
                if (any_invalid) {
                    // Scroll to first invalid input
                    var $first_invalid = $('.woocommerce-invalid:first');
    
                    var $msg = $('<div class="kg-invalid-msg">Please check your info</div>').appendTo($first_invalid);
                    $('html,body').animate({
                        scrollTop: $first_invalid.offset().top - 70
                    }, 1000);
    
                    $first_invalid.find('input,select').on('input change', function() {
                        $msg.fadeOut(500, function() {
                            $msg.remove();
                        });
                    });
    
                    $('.woocommerce-invalid').find('input,select').on('input change', function() {
                        $(this).closest('.form-row').removeClass('woocommerce-invalid woocommerce-invalid-required-field');
                    });
                }
            }
    

    当表单验证失败时,这将滚动到第一个无效输入(而不是一直到顶部),并在第一个无效输入上添加注释,同时将所有无效输入着色为红色。你可以很容易地修改它,让它按照你想要的方式工作。

    最后你只需要通过在wc_checkout_formsubmit函数中添加这一行来触发这个函数:

    wc_checkout_form.validate_all_fields();
    

    现在结帐字段将让您一个人呆着,直到您单击“下订单”,然后验证将开始。

    【讨论】:

    • get_template_directory_uri 仅返回父主题的路径,如果您将脚本添加到子主题文件夹,这是错误的路径。将函数调用更改为 get_stylesheet_directory_uri() 以获取活动(子)主题路径。感谢@tim-malone wordpress.stackexchange.com/questions/230085/…
    【解决方案2】:

    对于其他有同样问题的人,我在不编辑 checkout.js 的情况下解决了这个问题:

    在 showErrors 类出现之前隐藏错误:

    .woocommerce form .form-row.woocommerce-invalid:not(.showErrors) .select2-container, 
    .woocommerce form .form-row.woocommerce-invalid:not(.showErrors) input.input-text, 
    .woocommerce form .form-row.woocommerce-invalid:not(.showErrors) select {
        border: 1px solid #FFF !important;
    }
    

    然后在结帐错误时添加showErrors:

    $(document.body).on('checkout_error', function () {
        $('.woocommerce-invalid-required-field').addClass('showErrors');
      });
    

    【讨论】:

      猜你喜欢
      • 2011-08-02
      • 1970-01-01
      • 2022-06-15
      • 2018-05-12
      • 2016-09-30
      • 2019-01-20
      • 1970-01-01
      • 2011-08-20
      • 1970-01-01
      相关资源
      最近更新 更多