<p>You would need to implement a front-end solution of some kind using jquery and ajax, that listens to the <code>.on('change')</code> event on the select fields and loads the corresponding data from a template (i.e. '_cityState.html') using the selected city or state as post parameters; and then repopulate the other select field's options dynamically by setting the html of the select field to the return results.</p>

<p>Have a look at jquery's <a href="http://api.jquery.com/on/" rel="nofollow">.on('change')</a> event and <a href="http://api.jquery.com/jQuery.ajax/" rel="nofollow">$.ajax()</a> and <a href="http://api.jquery.com/html/" rel="nofollow">.html()</a> methods for more information on the jQuery part.</p>

<p>In your ajax only '_cityState.html' template you would want something like this: (note: this assumes that cities and states have a 'code' field that will represent the drop-down option value, but modify as needed):</p>

<pre><code>{% if craft.request.isAjax %}

    {# retreive the passed city or state code #}
    {% set city = craft.request.getParam('city') %}
    {% set state = craft.request.getParam('state') %}

    {% if city or state %}

        {% if city %}

            {# get all states; set the selected state to parent of 'city' #}
            {% set entries = craft.categories.group('locationCategories').limit(null).level(1) %}
            {% set selected = craft.categories.group('locationCategories).code(city).first().parent %}

        {% else %}

            {# get all cities that are a decendent of 'state'; set selected to first city #}
            {% set entries = craft.categories.group('locationCategories').limit(null).code(state).first().decedents(1) %}
            {% set selected = entries.first() %}

        {% endif %}

        {# build the return html #}
        {% for entry in entries %}
            &lt;option value={{ entry.code }} label="{{ entry.title }}" {% if entry == selected %}selected{% endif %}/&gt; 
        {% endfor %}

    {% endif %}

{% endif %}
</code></pre>

<p>Not tested. But should be pretty close. If anyone sees any errors, please edit or leave a comment.</p>

CC BY-SA 3.0
2014-11-18T03:52:31.643Z
You're a machine, Douglas.
Brad Bell
CC BY-SA 3.0
2014-11-18T12:23:20.947Z
I really like your answers on Craft with ajax topics, Douglas. Thanks!
carlcs
CC BY-SA 3.0
2014-11-18T03:50:52.177Z
2014-11-18T03:50:52.177Z
Douglas McDonald
<p>I'm trying to set up a front end form where the user can choose their city and state, which are stored as categories. I have states set up as the parent category and individual cities as sub categories.</p>

<p>I'd like to have the two select fields tied together so that when the state is chosen, the other select field is narrowed down to the cities in that state and vice-versa, e.g. if a user chooses Chicago only the Illinois select field should be available.</p>

<p>Is this possible?</p>

<p>Example:</p>

<p>Choose San Francisco --> California is selected</p>

<p>Choose Colorado -- > Only Colorado cities are available</p>

<p>Here are the two select fields. I know that using .level('1') and .level('2') is the wrong way, but I'm not sure what the correct way would be.</p>

<pre><code>{% set userOptionIds = user.providerArea.limit(null).ids() %}

&lt;label for="locationCategories"&gt;Parent locationCategories:&lt;/label&gt;
{% set parentCategories = craft.categories.group('locationCategories').level('1') %}

    &lt;select id="providerArea" name="fields[providerArea][]"&gt;
    {% for category in parentCategories %}
        &lt;option id="locationCategories" name="fields[locationCategories]" {% if category.id in userOptionIds %}selected{% endif %} value="{{ category.id }}"&gt;{{ category.title }}&lt;/option&gt;
    {% endfor %}
    &lt;/select&gt;

&lt;label for="locationCategories"&gt;Child locationCategories:&lt;/label&gt;
{% set childCategories = craft.categories.group('locationCategories').level('2') %}

    &lt;select id="providerArea" name="fields[providerArea][]"&gt;
    {% for category in childCategories %}
       &lt;option id="locationCategories" name="fields[locationCategories]" {% if category.id in userOptionIds %}selected{% endif %} value="{{ category.id }}"&gt;{{ category.title }}&lt;/option&gt;
    {% endfor %}}
    &lt;/select&gt;
</code></pre>

<categories><form>
Tie two select fields together based on category and subcategory?
# Tie two select fields together based on category and subcategory?

(Asked by: username_0 on 2014-11-18)

I'm trying to set up a front end form where the user can choose their city and state, which are stored as categories. I have states set up as the parent category and individual cities as sub categories.
I'd like to have the two select fields tied together so that when the state is chosen, the other select field is narrowed down to the cities in that state and vice-versa, e.g. if a user chooses Chicago only the Illinois select field should be available.
Is this possible?
Example:
Choose San Francisco --> California is selected
Choose Colorado -- > Only Colorado cities are available
Here are the two select fields. I know that using .level('1') and .level('2') is the wrong way, but I'm not sure what the correct way would be.
{% set userOptionIds = user.providerArea.limit(null).ids() %}

Parent locationCategories:
{% set parentCategories = craft.categories.group('locationCategories').level('1') %}

    
    {% for category in parentCategories %}
        {{ category.title }}
    {% endfor %}
    

Child locationCategories:
{% set childCategories = craft.categories.group('locationCategories').level('2') %}

    
    {% for category in childCategories %}
       {{ category.title }}
    {% endfor %}}

**Tags:** categories, form


---

## 1 answers

### Answer by username_1 on 2014-11-18. Score: 2 | Accepted answer

You would need to implement a front-end solution of some kind using jquery and ajax, that listens to the .on('change') event on the select fields and loads the corresponding data from a template (i.e. '_cityState.html') using the selected city or state as post parameters; and then repopulate the other select field's options dynamically by setting the html of the select field to the return results.
Have a look at jquery's .on('change') event and $.ajax() and .html() methods for more information on the jQuery part.
In your ajax only '_cityState.html' template you would want something like this: (note: this assumes that cities and states have a 'code' field that will represent the drop-down option value, but modify as needed):
{% if craft.request.isAjax %}

    {# retreive the passed city or state code #}
    {% set city = craft.request.getParam('city') %}
    {% set state = craft.request.getParam('state') %}

    {% if city or state %}

        {% if city %}

            {# get all states; set the selected state to parent of 'city' #}
            {% set entries = craft.categories.group('locationCategories').limit(null).level(1) %}
            {% set selected = craft.categories.group('locationCategories).code(city).first().parent %}

        {% else %}

            {# get all cities that are a decendent of 'state'; set selected to first city #}
            {% set entries = craft.categories.group('locationCategories').limit(null).code(state).first().decedents(1) %}
            {% set selected = entries.first() %}

        {% endif %}

        {# build the return html #}
        {% for entry in entries %}
             
        {% endfor %}

    {% endif %}

{% endif %}

Not tested. But should be pretty close. If anyone sees any errors, please edit or leave a comment.

> **Comments:**
> **username_2**: You're a machine, Douglas.  
> **username_3**: I really like your answers on Craft with ajax topics, Douglas. Thanks!  

---

