How to make a custom field required based on multi countries on WooCommerce checkout?

Viewed 32

I am working on multi countries for tax field. Below is my code in woocommerce but it seems not working. However, if i put single country, it works.

Below is the code.

// Add field
function filter_woocommerce_billing_fields( $fields ) {
    $fields['billing_vat'] = array(
      'label' => 'Tax ID',        
        'required'     => false,
        'type'         => 'text',
        'class'        => array( 'form-row-wide' ),
        'priority'     => 35,
    );

    return $fields;
}
add_filter( 'woocommerce_billing_fields', 'filter_woocommerce_billing_fields', 10, 1 );

Validate, i put multi countries here, am i doing wrong?

function action_woocommerce_after_checkout_validation( $data, $error ) {
    if ( $data['billing_country'] == 'TW','CN','IE' && empty( $data['billing_vat'] ) ) {
        $error->add( 'validation', 'Required based on country.' );
    }
}
add_action('woocommerce_after_checkout_validation', 'action_woocommerce_after_checkout_validation', 10, 2 );

// jQuery
function action_woocommerce_after_order_notes( $checkout ) {
    ?>
    <script>
        (function($) {
            $(document).ready(function () {
                required_or_optional(); //this calls it on load
                $( '#billing_country' ).change( required_or_optional );

// i put multi countries here with "or", am i doing wrong?

                function required_or_optional() {
                    if ( $( '#billing_country' ).val() ==  'TW' or 'CN' or 'IE' {
                        // Required
                        $( '#billing_vat' ).prop( 'required', true );
                        $( 'label[for="billing_vat"] .optional' ).remove();
                        $( 'label[for="billing_vat"]' ).append( '<abbr class="required" title="required">*</abbr>' );
                    } else {
                        $( '#billing_vat' ).removeProp( 'required' );
                        $( 'label[for="billing_vat"] .required' ).remove();

                        // Avoid append this multiple times
                        if ( $( 'label[for="billing_vat"] .optional' ).length == 0 ) {
                            $( 'label[for="billing_vat"]' ).append( '<span class="optional">(optional)</span>' );
                        }
                    }
                }
            });
        })(jQuery);
    </script>
    <?php
}
add_action( 'woocommerce_after_order_notes', 'action_woocommerce_after_order_notes', 10, 1 );

// Display on the order edit page (backend)
function action_woocommerce_admin_order_data_after_shipping_address( $order ) {
    if ( $value = $order->get_meta( '_billing_vat' ) ) {
        echo '<p><strong>' . __( 'Billing VAT', 'woocommerce' ) . ':</strong> ' . $value . '</p>';
    }
}
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'action_woocommerce_admin_order_data_after_shipping_address', 10, 1 );

Should i need to defined the countries in another array? Thx!

1 Answers

I think u overcomplicate it. Try with the following jquery script.

$(document ).on( 'updated_checkout', function() {
    add_remove_checkout_fields_conditionaly();
});

function add_remove_checkout_fields_conditionaly() {
    var country = $('#billing_country').val();
    var compare = ["US", "GB"];
    if($.inArray(country,compare)) {
        $('#billing_vat_field').addClass('validate-required');
        $('#billing_vat_field label span').hide();
        $('#billing_vat_field label').append('<abbr class="required" title="">*</abbr>');
    } else {
        $('#billing_vat_field').removeClass('validate-required');
        $('#billing_vat_field label span').show();
        $('#billing_vat_field label abbr').hide();
    }
}
Related