启用/禁用WooCommerce必填的结账字段,基于所选的付款方式。

huangapple go评论65阅读模式
英文:

Enable/disable a WooCommerce required checkout field based on selected payment method

问题

上面的问题的答案对我有帮助,但我仍然有一个问题:根据选择的付款方式显示/隐藏自定义WooCommerce结账字段

我希望当客户选择支票支付网关时,电话字段(必填字段)显示,如果选择其他支付网关,则不显示和禁用移动字段。

// 根据选择的付款方式条件显示/隐藏结账字段
add_action( 'wp_footer', 'conditionally_show_hide_billing_custom_field' );
function conditionally_show_hide_billing_custom_field(){
    // 仅在结账页面上执行
     if ( is_checkout() && ! is_wc_endpoint_url() ) :
    ?>
    <script>
        jQuery(function($){
            var a = 'input[name="payment_method"]',
                b = a + ':checked',
                c = '#billing_phone_field'; // 结账字段 <p> 容器选择器

            // 显示或隐藏结账字段的功能
            function showHide( selector = '', action = 'show' ){
                if( action == 'show' )
                    $(selector).show( 200, function(){
                        $(this).addClass("validate-required");
                    });
                else
                    $(selector).hide( 200, function(){
                        $(this).removeClass("validate-required");
                    });
                $(selector).removeClass("woocommerce-validated");
                $(selector).removeClass("woocommerce-invalid woocommerce-invalid-required-field");
            }

            // 初始化:如果选择的付款方式不是“支票”,则隐藏
            if( $(b).val() !== 'cheque' )
                showHide( c, 'hide' );
            else
                showHide( c );

            // 实时事件(付款方式更改时):根据“支票”显示或隐藏
            $( 'form.checkout' ).on( 'change', a, function() {
                if( $(b).val() !== 'cheque' )
                    showHide( c, 'hide' );
                else
                    showHide( c );
            });
        });
    </script>
    <?php
    endif;
}

问题是,当我选择除支票以外的其他支付网关时,即使电话字段被隐藏,它仍然被验证并显示错误(Billing Phone是必填字段) - 我不希望出现这种情况!

英文:

The answer to the above question helped me, but I still have a problem: Show hide custom Woocommerce checkout field based on selected payment method

I want the Phone field (a field is required) to be displayed when the customer selects the cheque payment gateway, and the mobile field is not displayed and disabled if he selects other payment gateways.

// Conditional Show hide checkout fields based on chosen payment methods
add_action( &#39;wp_footer&#39;, &#39;conditionally_show_hide_billing_custom_field&#39; );
function conditionally_show_hide_billing_custom_field(){
    // Only on checkout page
     if ( is_checkout() &amp;&amp; ! is_wc_endpoint_url() ) :
    ?&gt;
    &lt;script&gt;
        jQuery(function($){
            var a = &#39;input[name=&quot;payment_method&quot;]&#39;,
                b = a + &#39;:checked&#39;,
                c = &#39;#billing_phone_field&#39;; // The checkout field &lt;p&gt; container selector

            // Function that shows or hide checkout fields
            function showHide( selector = &#39;&#39;, action = &#39;show&#39; ){
                if( action == &#39;show&#39; )
                    $(selector).show( 200, function(){
                        $(this).addClass(&quot;validate-required&quot;);
                    });
                else
                    $(selector).hide( 200, function(){
                        $(this).removeClass(&quot;validate-required&quot;);
                    });
                $(selector).removeClass(&quot;woocommerce-validated&quot;);
                $(selector).removeClass(&quot;woocommerce-invalid woocommerce-invalid-required-field&quot;);
            }

            // Initialising: Hide if choosen payment method is &quot;cheque&quot;
            if( $(b).val() !== &#39;cheque&#39; )
                showHide( c, &#39;hide&#39; );
            else
                showHide( c );

            // Live event (When payment method is changed): Show or Hide based on &quot;cheque&quot;
            $( &#39;form.checkout&#39; ).on( &#39;change&#39;, a, function() {
                if( $(b).val() !== &#39;cheque&#39; )
                    showHide( c, &#39;hide&#39; );
                else
                    showHide( c );
            });
        });
    &lt;/script&gt;
    &lt;?php
    endif;
}

The problem is when I choose other payment gateways besides cheque, even though the Phone field is hidden, it is still validated and displays the error (Billing Phone is a required field) - and this field needs to be filled, I don't want this!

答案1

得分: 4

以下将完成任务,添加一个隐藏字段来处理结算电话验证,当结算电话字段可见时。当结算电话字段隐藏且为空时,将不会提示验证错误,允许静默下单:

// Your settings goes in here
function my_checkout_settings()
{
    return array(
        'payment_id'   => 'cheque', // 支付ID
        'field_key_id' => 'billing_phone', // 结算字段键ID
    );
}

// 添加一个用于电话验证的隐藏结算输入字段
add_action('woocommerce_billing_fields', 'add_an_hidden_billing_fields');
function add_an_hidden_billing_fields($billing_fields) {
    extract(my_checkout_settings()); // 加载您的设置

    // 添加一个隐藏输入字段
    $billing_fields[$field_key_id . '_is_valid'] = array(
        'type' => 'hidden',
        'required' => false,
        'default' => '',
    );

    return $billing_fields;
}

// 有条件地禁用结算电话验证
add_action('woocommerce_after_checkout_validation', 'disable_specific_checkout_field_validation_conditionally', 20, 2);
function disable_specific_checkout_field_validation_conditionally($data, $errors) {
    extract(my_checkout_settings()); // 加载您的设置

    $validation_key =  $field_key_id . '_is_valid'; // 隐藏字段的键ID

    if (empty($data[$field_key_id]) && isset($data[$validation_key]) && $data[$validation_key]) {
        $errors->remove($field_key_id . '_required'); // 移除此字段的不必要错误
    }
}

// 基于选择的付款方式有条件地显示/隐藏结算电话结账字段
add_action('woocommerce_checkout_init', 'enqueue_checkout_custom_script');
function enqueue_checkout_custom_script() {
    extract(my_checkout_settings()); // 加载您的设置

    wc_enqueue_js("const a = 'input[name=payment_method]',
        b = a + ':checked',
        c = '#{$field_key_id}',
        d = c + '_field',
        v = c + '_is_valid',
        p = '{$payment_id}';
    
    function triggerShowHide(b, d, p, v) {
        $(b).val() !== p ? $(d).show(200) : $(d).hide(200);
        $(b).val() !== p ? $(v).val('') : $(v).val('1');
    }
    
    // 在首次加载时触发
     triggerShowHide(b, d, p, v);
    
    // 在支付方式 'change' 的实时事件上
    $('form.checkout').on('change', a, function() {
        triggerShowHide(b, d, p, v);
    });");
}

代码放入您活动子主题的functions.php文件中(或者放入一个插件中)。经过测试,可以正常工作。

英文:

The following will do the job, adding a hidden field to handle the billing phone validation when the billing phone field is visible. When the billing phone field is hidden and empty, no validation error will be prompted, allowing placing the order silently:

// Your settings goes in here
function my_checkout_settings()
{
    return array(
        &#39;payment_id&#39;   =&gt; &#39;cheque&#39;, // The payment Id
        &#39;field_key_id&#39; =&gt; &#39;billing_phone&#39;, // The checkout field key ID
    );
}

// Add a hidden billing input field for phone validation purpose
add_action(&#39;woocommerce_billing_fields&#39;, &#39;add_an_hidden_billing_fields&#39;);
function add_an_hidden_billing_fields($billing_fields) {
    extract(my_checkout_settings()); // Load your settings

    // Add a hidden input field
    $billing_fields[$field_key_id . &#39;_is_valid&#39;] = array(
        &#39;type&#39; =&gt; &#39;hidden&#39;,
        &#39;required&#39; =&gt; false,
        &#39;default&#39; =&gt; &#39;&#39;,
    );

    return $billing_fields;
}

// Disabling conditionnally the Billing phone validation
add_action(&#39;woocommerce_after_checkout_validation&#39;, &#39;disable_specific_checkout_field_validation_conditionally&#39;, 20, 2);
function disable_specific_checkout_field_validation_conditionally($data, $errors) {
    extract(my_checkout_settings()); // Load your settings

    $validation_key =  $field_key_id . &#39;_is_valid&#39;; // The key Id of the hidden field

    if (empty($data[$field_key_id]) &amp;&amp; isset($data[$validation_key]) &amp;&amp; $data[$validation_key]) {
        $errors-&gt;remove($field_key_id . &#39;_required&#39;); // Remove unwanted error for this field
    }
}

// Conditional Show hide billing phone checkout fields based on chosen payment methods
add_action(&#39;woocommerce_checkout_init&#39;, &#39;enqueue_checkout_custom_script&#39;);
function enqueue_checkout_custom_script() {
    extract(my_checkout_settings()); // Load your settings

    wc_enqueue_js(&quot;const a = &#39;input[name=payment_method]&#39;,
        b = a + &#39;:checked&#39;,
        c = &#39;#{$field_key_id}&#39;,
        d = c + &#39;_field&#39;,
        v = c + &#39;_is_valid&#39;,
        p = &#39;{$payment_id}&#39;;
    
    function triggerShowHide(b, d, p, v) {
        $(b).val() !== p ? $(d).show(200) : $(d).hide(200);
        $(b).val() !== p ? $(v).val(&#39;&#39;) : $(v).val(&#39;1&#39;);
    }
    
    // On the first load
     triggerShowHide(b, d, p, v);
    
    // On payment method &#39;change&#39; live event
    $(&#39;form.checkout&#39;).on(&#39;change&#39;, a, function() {
        triggerShowHide(b, d, p, v);
    });&quot;);
}

Code goes in functions.php file of your active child theme (or in a plugin). Tested and works.

答案2

得分: 0

你可以使用 jQuery 的 .prop('disabled', true);.prop('disabled', false); 来操作输入选择器。尝试下面的代码。

add_action('wp_footer', 'conditionally_show_hide_billing_custom_field');
function conditionally_show_hide_billing_custom_field(){
    // 仅在结账页面上执行
    if (is_checkout() && !is_wc_endpoint_url()) :
    ?>
    <script>
        jQuery(function($){
            var a = 'input[name="payment_method"]',
                b = a + ':checked',
                c = '#billing_phone_field'; // 收货电话字段的 <p> 容器选择器

            // 显示或隐藏收货字段的函数
            function showHide( selector = '', action = 'show' ){
                if( action == 'show' ) {
                    $(selector).show(200, function(){
                        $(this).addClass("validate-required");
                    });
                    $(selector + ' input').prop('disabled', false);
                } else {
                    $(selector).hide(200, function(){
                        $(this).removeClass("validate-required");
                    });
                    $(selector + ' input').prop('disabled', true);
                }
                $(selector).removeClass("woocommerce-validated");
                $(selector).removeClass("woocommerce-invalid woocommerce-invalid-required-field");
            }

            // 初始化:如果选择的付款方式不是 "cheque",则隐藏
            if( $(b).val() !== 'cheque' )
                showHide( c, 'hide' );
            else
                showHide( c );

            // 实时事件(当付款方式更改时):基于 "cheque" 显示或隐藏
            $('form.checkout').on('change', a, function() {
                if( $(b).val() !== 'cheque' )
                    showHide( c, 'hide' );
                else
                    showHide( c );
            });
        });
    </script>
    <?php
    endif;
}

要在支付网关不是 "cheque" 时移除 "(Billing Phone is a required field)!",您可以使用 `woocommerce_checkout_fields` 钩子。

```php
add_filter('woocommerce_checkout_fields', 'conditionally_disable_phone_field_validation');
function conditionally_disable_phone_field_validation( $fields ) {
    // 仅在结账页面上执行
    if (is_checkout() && !is_wc_endpoint_url()) {
        $chosen_payment_method = WC()->session->get('chosen_payment_method');

        // 如果选择的付款方式不是 "cheque",则隐藏并禁用电话字段验证
        if ( $chosen_payment_method !== 'cheque' ) {
            $fields['billing']['billing_phone']['required'] = false;
            $fields['billing']['billing_phone']['validate'] = array();
        }
    }

    return $fields;
}
英文:

You can use jquery .prop(&#39;disabled&#39;, true); and .prop(&#39;disabled&#39;, false); to the input selector. Try below code.

add_action( &#39;wp_footer&#39;, &#39;conditionally_show_hide_billing_custom_field&#39; );
function conditionally_show_hide_billing_custom_field(){
// Only on checkout page
if ( is_checkout() &amp;&amp; ! is_wc_endpoint_url() ) :
?&gt;
&lt;script&gt;
jQuery(function($){
var a = &#39;input[name=&quot;payment_method&quot;]&#39;,
b = a + &#39;:checked&#39;,
c = &#39;#billing_phone_field&#39;; // The checkout field &lt;p&gt; container selector
// Function that shows or hides checkout fields
function showHide( selector = &#39;&#39;, action = &#39;show&#39; ){
if( action == &#39;show&#39; ) {
$(selector).show( 200, function(){
$(this).addClass(&quot;validate-required&quot;);
});
$(selector + &#39; input&#39;).prop(&#39;disabled&#39;, false);
} else {
$(selector).hide( 200, function(){
$(this).removeClass(&quot;validate-required&quot;);
});
$(selector + &#39; input&#39;).prop(&#39;disabled&#39;, true);
}
$(selector).removeClass(&quot;woocommerce-validated&quot;);
$(selector).removeClass(&quot;woocommerce-invalid woocommerce-invalid-required-field&quot;);
}
// Initialising: Hide if chosen payment method is not &quot;cheque&quot;
if( $(b).val() !== &#39;cheque&#39; )
showHide( c, &#39;hide&#39; );
else
showHide( c );
// Live event (When payment method is changed): Show or Hide based on &quot;cheque&quot;
$( &#39;form.checkout&#39; ).on( &#39;change&#39;, a, function() {
if( $(b).val() !== &#39;cheque&#39; )
showHide( c, &#39;hide&#39; );
else
showHide( c );
});
});
&lt;/script&gt;
&lt;?php
endif;
}

To remove (Billing Phone is a required field)! when the payment gateway is not cheque then You can use woocommerce_checkout_fields hook.

add_filter( &#39;woocommerce_checkout_fields&#39;, &#39;conditionally_disable_phone_field_validation&#39; );
function conditionally_disable_phone_field_validation( $fields ) {
// Only on checkout page
if ( is_checkout() &amp;&amp; ! is_wc_endpoint_url() ) {
$chosen_payment_method = WC()-&gt;session-&gt;get( &#39;chosen_payment_method&#39; );
// Hide and disable phone field if chosen payment method is not &quot;cheque&quot;
if ( $chosen_payment_method !== &#39;cheque&#39; ) {
$fields[&#39;billing&#39;][&#39;billing_phone&#39;][&#39;required&#39;] = false;
$fields[&#39;billing&#39;][&#39;billing_phone&#39;][&#39;validate&#39;] = array();
}
}
return $fields;
}

huangapple
  • 本文由 发表于 2023年7月24日 14:53:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76752037.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定