skip to Main Content

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( 'wp_footer', 'conditionally_show_hide_billing_custom_field' );
function conditionally_show_hide_billing_custom_field(){
    // Only on checkout page
     if ( is_checkout() && ! is_wc_endpoint_url() ) :
    ?>
    <script>
        jQuery(function($){
            var a = 'input[name="payment_method"]',
                b = a + ':checked',
                c = '#billing_phone_field'; // The checkout field <p> container selector

            // Function that shows or hide checkout fields
            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");
            }

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

            // Live event (When payment method is changed): Show or Hide based on "cheque"
            $( 'form.checkout' ).on( 'change', a, function() {
                if( $(b).val() !== 'cheque' )
                    showHide( c, 'hide' );
                else
                    showHide( c );
            });
        });
    </script>
    <?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!

2

Answers


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

    add_action( 'wp_footer', 'conditionally_show_hide_billing_custom_field' );
    function conditionally_show_hide_billing_custom_field(){
        // Only on checkout page
        if ( is_checkout() && ! is_wc_endpoint_url() ) :
        ?>
        <script>
            jQuery(function($){
                var a = 'input[name="payment_method"]',
                    b = a + ':checked',
                    c = '#billing_phone_field'; // The checkout field <p> container selector
    
                // Function that shows or hides checkout fields
                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");
                }
    
                // Initialising: Hide if chosen payment method is not "cheque"
                if( $(b).val() !== 'cheque' )
                    showHide( c, 'hide' );
                else
                    showHide( c );
    
                // Live event (When payment method is changed): Show or Hide based on "cheque"
                $( 'form.checkout' ).on( 'change', a, function() {
                    if( $(b).val() !== 'cheque' )
                        showHide( c, 'hide' );
                    else
                        showHide( c );
                });
            });
        </script>
        <?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( 'woocommerce_checkout_fields', 'conditionally_disable_phone_field_validation' );
    function conditionally_disable_phone_field_validation( $fields ) {
        // Only on checkout page
        if ( is_checkout() && ! is_wc_endpoint_url() ) {
            $chosen_payment_method = WC()->session->get( 'chosen_payment_method' );
    
            // Hide and disable phone field if chosen payment method is not "cheque"
            if ( $chosen_payment_method !== 'cheque' ) {
                $fields['billing']['billing_phone']['required'] = false;
                $fields['billing']['billing_phone']['validate'] = array();
            }
        }
    
        return $fields;
    }
    
    Login or Signup to reply.
  2. 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(
            'payment_id'   => 'cheque', // The payment Id
            'field_key_id' => 'billing_phone', // The checkout field key ID
        );
    }
    
    // Add a hidden billing input field for phone validation purpose
    add_action('woocommerce_billing_fields', 'add_an_hidden_billing_fields');
    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 . '_is_valid'] = array(
            'type' => 'hidden',
            'required' => false,
            'default' => '',
        );
    
        return $billing_fields;
    }
    
    // Disabling conditionnally the Billing phone validation
    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()); // Load your settings
    
        $validation_key =  $field_key_id . '_is_valid'; // The key Id of the hidden field
    
        if (empty($data[$field_key_id]) && isset($data[$validation_key]) && $data[$validation_key]) {
            $errors->remove($field_key_id . '_required'); // Remove unwanted error for this field
        }
    }
    
    // Conditional Show hide billing phone checkout fields based on chosen payment methods
    add_action('woocommerce_checkout_init', 'enqueue_checkout_custom_script');
    function enqueue_checkout_custom_script() {
        extract(my_checkout_settings()); // Load your 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');
        }
        
        // On the first load
         triggerShowHide(b, d, p, v);
        
        // On payment method 'change' live event
        $('form.checkout').on('change', a, function() {
            triggerShowHide(b, d, p, v);
        });");
    }
    

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

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search