Make Woocommerce checkout phone field optional based on shipping country

后端 未结 2 593
名媛妹妹
名媛妹妹 2020-12-06 03:53

In Woocommerce checkout, I am trying to make the phone field not required for specific shipping countries. Based on \"Make checkout phone field optional for specific cou

相关标签:
2条回答
  • 2020-12-06 04:00

    The following code will make billing phone field required only for specific "Shipping" countries.

    Since Woocommerce version 3.4+, things have changed a bit on Woocommerce form fields, so additional functions and code where required.

    Also I have extended the code to handle the phone field behavior in My Account > Edit Addresses, where customer can make changes to his account data.

    Here is the complete code (define your country codes in the first function):

    // SETTINGS: The countries codes (2 capital letters) in the array
    function defined_countries_for_phone_field(){
        return array( 'UK', 'BE', 'GE', 'IT', 'ES' );
    }
    
    // Remove "(optional)" from non required "Billing phone" field
    add_filter( 'woocommerce_form_field' , 'remove_checkout_optional_fields_label', 10, 4 );
    function remove_checkout_optional_fields_label( $field, $key, $args, $value ) {
    
        // Get the defined countries codes
        $countries = defined_countries_for_phone_field();
    
        // Get Customer shipping country
        $shipping_country = WC()->customer->get_shipping_country();
    
        // Only on checkout page and My account > Edit address for billing phone field
        if( 'billing_phone' === $key && ( ( is_wc_endpoint_url( 'edit-address' )
        && ! in_array($shipping_country, $countries) ) || is_checkout() ) ) {
            $optional = '&nbsp;<span class="optional">(' . esc_html__( 'optional', 'woocommerce' ) . ')</span>';
            $field = str_replace( $optional, '', $field );
        }
        return $field;
    }
    
    // Make the billing phone field optional (by default)
    add_filter( 'woocommerce_billing_fields', 'filter_billing_phone_field', 10, 1 );
    function filter_billing_phone_field( $fields ) {
    
        // Get the defined countries codes
        $countries = defined_countries_for_phone_field();
    
        // Get Customer shipping country
        $shipping_country = WC()->customer->get_shipping_country();
    
        // Only on checkout page and My account > Edit address
        if ( ( is_wc_endpoint_url( 'edit-address' )
        && ! in_array($shipping_country, $countries) ) || is_checkout() )
            $fields['billing_phone']['required'] = false;
    
        return $fields;
    }
    
    // Real time shipping country selection actions
    add_action( 'woocommerce_after_order_notes', 'custom_checkout_scripts_and_fields', 10, 1 );
    function custom_checkout_scripts_and_fields( $checkout ) {
        $required = esc_attr__( 'required', 'woocommerce' );
    
        // Get the defined countries codes
        $countries = defined_countries_for_phone_field();
    
        // Hidden field for the phone number validation
        echo '<input type="hidden"  name="billing_phone_check" id="billing_phone_check" value="0">';
        $countries_str = "'".implode( "', '", $countries )."'"; // Formatting countries for jQuery
        ?>
        <script type="text/javascript">
            (function($){
                var required = '<abbr class="required" title="<?php echo $required; ?>">*</abbr>',
                    countries = [<?php echo $countries_str; ?>],
                    location = $('#shipping_country option:selected').val(),
                    phoneCheck = 'input#billing_phone_check',
                    phoneField = '#billing_phone_field';
    
                function actionRequire( actionToDo='yes', selector='' ){
                    if ( actionToDo == 'yes' ) {
                        $(selector).addClass("validate-required");
                        $(selector+' label').append(required);
                    } else {
                        $(selector).removeClass("validate-required");
                        $(selector+' label > .required').remove();
                    }
                    $(selector).removeClass("woocommerce-validated");
                    $(selector).removeClass("woocommerce-invalid woocommerce-invalid-required-field");
                }
    
                // Default value Once DOM is loaded (with a 300 ms delay)
                setTimeout( function(){
                    actionRequire( 'no', phoneField );
                    if( $.inArray( location, countries ) >= 0  && $(phoneCheck).val() == '0' ){
                        actionRequire( 'yes',phoneField );
                        $(phoneCheck).val('1');
                    }
                }, 300 );
    
                // Live value
                $( 'form.checkout' ).on( 'change', '#shipping_country', function(){
                    var location = $('#shipping_country option:selected').val();
                    if ( $.inArray( location, countries ) >= 0 && $(phoneCheck).val() == 0 ) {
                        actionRequire( 'yes' ,phoneField );
                        $(phoneCheck).val('1');
                    } else if ( $(phoneCheck).val() == 1 ) {
                        actionRequire( 'no' ,phoneField );
                        $(phoneCheck).val('0');
                    }
                });
           })(jQuery);
            </script>
        <?php
    }
    
    // Phone number validation, when the field is required
    add_action('woocommerce_checkout_process', 'billing_phone_field_process');
    function billing_phone_field_process() {
        // Check if set, if its not set add an error.
        if ( ! $_POST['billing_phone'] && $_POST['billing_phone_check'] == '1' )
            wc_add_notice( __( 'Please enter a number phone.' ), 'error' );
    }
    

    Code goes in function.php file of your active child theme (or active theme). Tested and works in WooCommerce from version 3.4 and above.

    Related:

    • Make checkout phone field optional for specific countries in WooCommerce
    • Remove "(optional)" text from checkout fields in Woocommerce 3.4+
    0 讨论(0)
  • 2020-12-06 04:18

    Huge thanks to @LoicTheAztec for the original answer, however the solution now gives erratic results and just alternately switches the phone field between required and optional states (on / off).

    The original answer also does not take into account customers who are using the billing address only and have not entered a separate delivery or shipping address.

    Please see the updated version below for 2019

    // SETTINGS: The countries codes (2 capital letters) in the array
    function defined_countries_for_phone_field(){
        return array( 'GB', 'JE', 'GG', 'IM' );
    }
    
    // Remove "(optional)" from non required "Billing phone" field
    add_filter( 'woocommerce_form_field' , 'remove_checkout_optional_fields_label', 10, 4 );
    function remove_checkout_optional_fields_label( $field, $key, $args, $value ) {
    
        // Get the defined countries codes
        $countries = defined_countries_for_phone_field();
    
        // Get Customer shipping country
        $shipping_country = WC()->customer->get_shipping_country();
    
        // Only on checkout page and My account > Edit address for billing phone field
        if( 'billing_phone' === $key && ( ( is_wc_endpoint_url( 'edit-address' )
        && in_array($shipping_country, $countries) ) || is_checkout() ) ) {
            $optional = '&nbsp;<span class="optional">(' . esc_html__( 'optional', 'woocommerce' ) . ')</span>';
            $field = str_replace( $optional, '', $field );
        }
        return $field;
    }
    
    // Make the billing phone field optional (by default)
    add_filter( 'woocommerce_billing_fields', 'filter_billing_phone_field', 10, 1 );
    function filter_billing_phone_field( $fields ) {
    
        // Get the defined countries codes
        $countries = defined_countries_for_phone_field();
    
        // Get Customer shipping country
        $shipping_country = WC()->customer->get_shipping_country();
    
        // Only on checkout page and My account > Edit address
        if ( ( is_wc_endpoint_url( 'edit-address' )
        && in_array($shipping_country, $countries) ) || is_checkout() )
            $fields['billing_phone']['required'] = false;
    
        return $fields;
    }
    
    // Real time shipping country selection actions
    add_action( 'woocommerce_after_order_notes', 'custom_checkout_scripts_and_fields', 10, 1 );
    function custom_checkout_scripts_and_fields( $checkout ) {
        $required = esc_attr__( 'required', 'woocommerce' );
    
        // Get the defined countries codes
        $countries = defined_countries_for_phone_field();
    
        // Hidden field for the phone number validation
        echo '<input type="hidden"  name="billing_phone_check" id="billing_phone_check" value="0">';
        $countries_str = "'".implode( "', '", $countries )."'"; // Formatting countries for jQuery
        ?>
        <script type="text/javascript">
            (function($){
                var required = '<abbr class="required" title="<?php echo $required; ?>">*</abbr>';
                var countries = [<?php echo $countries_str; ?>];
                    if($('.shipping_address').is(':visible')) {
                        // ship to different country selected
                        var selectedcountry = $('#shipping_country option:selected').val();
                    } else {
                        var selectedcountry = $('#billing_country option:selected').val();
                    }
                 //var selectedcountry = $('#shipping_country option:selected').val();
                 var phoneCheck = 'input#billing_phone_check';
                 var phoneField = '#billing_phone_field';
    
                function actionRequire( actionToDo='yes', selector='' ){
                    if ( actionToDo == 'yes' ) {
                        $(selector).addClass("validate-required");
                        $(selector+' label > .required').remove();
                        $(selector+' label').append(required);
                    } else {
                        $(selector).removeClass("validate-required");
                        $(selector+' label > .required').remove();
                    }
                    $(selector).removeClass("woocommerce-validated");
                    $(selector).removeClass("woocommerce-invalid woocommerce-invalid-required-field");
                }
    
                // Default value Once DOM is loaded (with a 300 ms delay)
                setTimeout( function(){
                    if($('.shipping_address').is(':visible')) {
                        // ship to different country selected
                        var selectedcountry = $('#shipping_country option:selected').val();
                    } else {
                        var selectedcountry = $('#billing_country option:selected').val();
                    }
                    actionRequire( 'no', phoneField );
                    if( $.inArray( selectedcountry, countries ) == -1){
                        actionRequire( 'yes',phoneField );
                        $(phoneCheck).val('1');
                    }
                }, 300 );
    
                // Live value
                $( 'form.checkout' ).on( 'change', '#billing_country, #shipping_country, #ship-to-different-address-checkbox', function(){
                    setTimeout( function(){
                        if($('.shipping_address').is(':visible')) {
                            // ship to different country selected
                            var selectedcountry = $('#shipping_country option:selected').val();
                        } else {
                            var selectedcountry = $('#billing_country option:selected').val();
                        }
    
                        if ( $.inArray( selectedcountry, countries ) == -1) {
                            actionRequire( 'yes' ,phoneField );
                            $(phoneCheck).val('1');
                        } else {
                            actionRequire( 'no' ,phoneField );
                            $(phoneCheck).val('0');
                        }
                    }, 300 );
                });
           })(jQuery);
            </script>
        <?php
    }
    
    // Phone number validation, when the field is required
    add_action('woocommerce_checkout_process', 'billing_phone_field_process');
    function billing_phone_field_process() {
        // Check if set, if its not set add an error.
        if ( ! $_POST['billing_phone'] && $_POST['billing_phone_check'] == '1' )
            wc_add_notice( __( 'Please enter a number phone.' ), 'error' );
    }
    
    0 讨论(0)
提交回复
热议问题