1

I have a multi-country website that I am building with Craft Pro Commerce. I have set up locales for 5 countries. So, for the New Shipping Address section, I would like to have the country options limited to match the current locale country, except if the locale is "en", which would be a catch-all to include a list of the rest of the country shipping options...

Out of the box, the logic for the country select field is as follows:

<select class="address-country u-full-width" name="{{ modelName }}[countryId]">
    {% for key, option in countries %}
        {% set optionValue = (model ? model.countryId : '') %}
            <option value="{{ key }}" {% if key == optionValue %} selected{% endif %}>{{ option }}</option>
    {% endfor %}
</select>

I've tried:

<select name="country-select"  id="country-select" class="form-control" onchange="location = this.value;" autocomplete="off">>
    {% set locales = craft.i18n.getSiteLocaleIds() %}
    {% set locale = craft.locale %}
        {% for loc in locales %}
            {# checking if current loop has active locale #}
            {% set isHome = (loc == locale) %}
            {% if isHome %}

                {% if loc == "en" %}
                    <option value="/" selected>Europe</option>   

                {% else %}
                    {% set subTags = locale|split('_') %}
                    {% set territory = subTags|length > 1 ? craft.i18n.getLocaleData(craft.locale).getTerritory(subTags|last) : '' %}  
                        <option value="{{ loc | replace({'en': ''}) | trim('_') }}" selected>{% if territory %}{{ territory }}{% endif %}</option>   
                {% endif %}

        {% else %}

        {% endif %}

    {% endfor %}
</select>

I've also tried of bunch of ideas from Stackoverflow, but couldn't get anything to work as needed...

Have the country in craft.commerce.countriesList default (too static, I need something dynamic)

Locale-specific country select menu (not really what I need... I need to set the country for the Shipping address. I can create a list of the countries whose locales I've selected in the CMS:

<li class="country-button">

    <form action="" name="dropdown">
        <select name="country-select"  id="country-select" class="form-control" onchange="location = this.value;" autocomplete="off">>
            {% set locales = craft.i18n.getSiteLocaleIds() %}
            {% set locale = craft.locale %}
            {% for loc in locales %}
                {# checking if current loop has active locale #}
                {% set isHome = (loc == locale) %}
                {% if isHome %}

                    {% if loc == "en" %}
                        <option value="{{ craft.config.originalUrl }}" selected>Europe</option>   

                    {% else %}
                        {% set subTags = locale|split('_') %}
                        {% set territory = subTags|length > 1 ? craft.i18n.getLocaleData(craft.locale).getTerritory(subTags|last) : '' %}  
                            <option value="{{ loc | replace({'en': ''}) | trim('_') }}" selected>{% if territory %}{{ territory }}{% endif %}</option>   
                    {% endif %}

                {% else %}

                    {% if loc == "en" %}
                        <option value="{{ craft.config.originalUrl }}">EU</option>   
                    {% else %}
                        <option value="{{ loc | replace({'en': ''}) | trim('_') }}">{{ loc | replace({'en': ''}) | trim('_') | upper }} </option>   
                    {% endif %}

                {% endif %}

            {% endfor %}
        </select>
    </form>

</li>

and I can get the users country using JS

function getCountry() {
    $.getJSON("http://freegeoip.net/json/", function (data) {
        var country = data.country_name;
        var country_code = data.country_code.toLowerCase();
        var country_code_url = country_code.toLowerCase();
        var ip = data.ip;
        var baseHrefSplash = baseHref + "/splash/";

        var s = baseHref
        search = '//'
        var n = 2

        var newBaseHref = baseHrefSplash.replace(RegExp("^(?:.*?//){" + n + "}"), function(x){return x.replace(RegExp(search + "$"), "/")})

        console.log("country: " + country);
        console.log("country code: " + country_code);

        // document.getElementById("test-country").innerHTML = country;
        // document.getElementById("test-country2").innerHTML = country_code_url;

        // if (country_code_url != urlEndingTrim ) {
        //     console.log("what url should i go to? " + newBaseHref)
        //     window.location = newBaseHref;
        // } else {
        //     console.log( urlEndingTrim + " is equal to " + country_code_url)
        // }

        $.cookie('the_cookie', country +  ", " + country_code_url);
        console.log($.cookie('the_cookie'));


        $("#address-country").val('country');

    }); 
}

I'm really stuck... I've set shipping zones in the CMS, ideally, it would be amazing to be able to use those when setting the shipping address country, but I'll settle for another option that is still dynamic, using the current country locale. Thank you so much!!!

Update What I have figured out so far is this:

I've essentially left the html alone, it's the original html from Craft Commerce plugin:

<select id="address-country" class="address-country u-full-width" name="{{ modelName }}[countryId]" autocomplete="off" placeholder="Country">
    {% for key, option in countries %}
        {% set optionValue = (model ? model.countryId : '') %}

        <option value="{{ key }}" {% if key == optionValue %} selected{% endif %}>{{ option }}</option>
    {% endfor %}
</select>

And in the js file, I have this:

function setShippingCountry() {
    $.getJSON("http://freegeoip.net/json/", function (data) {
        var country = data.country_name;
        var country_code = data.country_code.toLowerCase();
        var country_code_url = country_code.toLowerCase();
        var ip = data.ip;

        if (country == 'Australia') {
            var temp="13"; 
            $("#address-country").val(temp);
            $('#address-country option[value!="13"]').remove();

        } else if (country == 'New Zealand') {
            var temp="171"; 
            $("#address-country").val(temp);
            $('#address-country option[value!="171"]').remove();

        } else if (country == 'United States') {
            var temp="233"; 
            $("#address-country").val(temp);
            $('#address-country option[value!="233"]').remove();


        } else if (country == 'Canada') {
            var temp="38"; 
            $("#address-country").val(temp);
            $('#address-country option[value!="38"]').remove();            

        } else {
            $('#address-country option[value="13"], #address-country option[value="171"], #address-country option[value="233"], #address-country option[value="38"]').remove();                        

        }
    });
}
setShippingCountry();

This function is getting the user's location/country, setting that country name as the selected value, then, for certain countries, it's hiding all unselected options, and for the rest of the countries, it shows all of the countries except for AU, NZ, US, and CA. The only thing left now is to get the "States" select option to populate on page load for AU, US, and CA so that the user won't have to click the country select option since it's already been selected on page load...

A couple of resources that helped me work out this solution so far: https://stackoverflow.com/questions/19611557/how-to-set-default-value-for-html-select and http://jsfiddle.net/9dgV5/2/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.