Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
337 views
in Technique[技术] by (71.8m points)

php - Make Woocommerce checkout phone field optional based on shipping country

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 countries in WooCommerce" answer code, which works fine, I have tried to make some changes to get this code working for the shipping country rather than billing country.

After a lot of tries, I wasn't able to figure out how to make it work.

Any help will be awesome and greatly appreciated.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...