wc_countries – states selection dropdown – woocommerce

I am struggling to set up a form with a default WooCommerce country and states selection dropdowns.

Basically, I want to show Country selection and then state selection based on the country selection. So if the user chooses UK, the new dropdown with states selection will show.

Read More

I got as far as this:

<?php
global $woocommerce;
$countries_obj   = new WC_Countries();
$countries   = $countries_obj->__get('countries');
$default_country = $countries_obj->get_base_country();
$default_county_states = $countries_obj->get_states( $default_country );

echo '<div id="ships_from_countries_field">' . __('Countries') . '';

    woocommerce_form_field('my_country_field', array(
           'type'       => 'select',
           'class'      => array( 'chzn-drop' ),
           'label'      => __('Item ships from - country'),
           'placeholder'    => __('Select a Country'),
           'options'    => $countries
            )
     );
 echo '</div>';

 echo '<div id="ships_from_state_field">' . __('States') . '';

     woocommerce_form_field('my_state_field', array(
            'type'       => 'select',
            'class'      => array( 'chzn-drop' ),
            'label'      => __('Item ships from - state'),
            'placeholder'    => __('Select a State'),
            'options'    => $default_county_states
             )
      );
  echo '</div>';
  ?>

Countries dropdown is displaying countries and states dropdown displaying states of the shop base – UK

But how do I make them work together and save the values?

Cannot find any info, anybody has any experience making this work?

Related posts

2 comments

  1. first of, there’s a type for country and state.. you don’t need to do much… it’s just like this…

    echo '<div id="ships_from_countries_field">' . __('Countries') . '';
    
        woocommerce_form_field('my_country_field', array(
           'type'       => 'country',
           'class'      => array( 'chzn-drop' ),
           'label'      => __('Item ships from - country'),
           'placeholder'    => __('Select a Country')
            )
        );
    echo '</div>';
    
    echo '<div id="ships_from_state_field">' . __('States') . '';
    
        woocommerce_form_field('my_state_field', array(
            'type'       => 'state',
            'class'      => array( 'chzn-drop' ),
            'label'      => __('Item ships from - state'),
            'placeholder'    => __('Select a State')
            )
        );
    echo '</div>';
    

    take note of their type… they’re not of type select.

    now on your problem..

    PHP

    you need to have localized script for country and state… I won’t go on how to use wp_localize_script(). Read the link if you need to. Here’s a part of it.

    $wc_country = array(
        'country' => json_encode( array_merge( WC()->countries->get_allowed_country_states(), WC()->countries->get_shipping_country_states() ) )
    );
    wp_localize_script( 'my-js', 'my_js', $wc_country );
    

    javascript

    with that, in your my-js script (a script file) you can read the state like this:

        var states_json = my_js.countries.replace( /&quot;/g, '"' ),
            states = $.parseJSON( states_json );
    

    you then have to add a change event on your country and repopulate state based on what country was selected…

    example: states["PH"] if country selected is Philippines

    00: "Metro Manila"
    ABR: "Abra"
    AGN: "Agusan del Norte"
    AGS: "Agusan del Sur"
    AKL: "Aklan"
    ALB: "Albay"
    ANT: "Antique"
    APA: "Apayao"
    AUR: "Aurora"
    BAN: "Bataan"
    BAS: "Basilan"
    BEN: "Benguet"
    BIL: "Biliran"
    .....
    WSA: "Samar"
    ZAN: "Zamboanga del Norte"
    ZAS: "Zamboanga del Sur"
    ZMB: "Zambales"
    ZSI: "Zamboanga Sibugay"
    

    you can then build your options like this using jQuery..

    var options = '',
        state = states[ country ]; // country can be: var country = $('country').val();
    
    for( var index in state ) {
        if ( state.hasOwnProperty( index ) ) {
            options = options + '<option value="' + index + '">' + state[ index ] + '</option>';
        }
    }
    
  2. I looked how woocommerce did it in checkout. Instead of making my own js I just included the js they already made and the included the data in the same format they use.

            $suffix  = ( defined('SCRIPT_DEBUG') && SCRIPT_DEBUG == 'TRUE' ) ? '' : '.min';
            // $version = Constants::get_constant( 'WC_VERSION' );
            $jsUrl = plugin_dir_url( 'woocommerce').'woocommerce/assets/js/frontend/country-select' . $suffix . '.js';
    
    
            //add in scripts to handle state dropdown on country selection
            $wc_country = array(
                    'countries' => json_encode( array_merge( WC()->countries->get_allowed_country_states(), WC()->countries->get_shipping_country_states() ) )
            );
            echo '<script type="text/javascript" id="wc-country-select-js-extra">';
            echo ' /* <![CDATA[ */';
            echo 'var wc_country_select_params = '.json_encode($wc_country).';';
            echo '/* ]]> */';
            echo '</script>';
            echo '<script type="text/javascript" src="'.$jsUrl.'"></script>';
    

Comments are closed.