Search code examples
ember.jsember-data

Ember 2.x How to do linked dropdowns with data sourced from server


I can't seem to find my first foothold on this. I found some older 1.x ways of kinda of doing what I want, but always from hard coded arrays.

Simply stated, I want a States drop down which gets its data from my server. When the user selects the state I need the Counties drop down to fetch the list of counties in that state from my server.

Pretty easy with straight Ajax and JS but learning the Ember 2.x way of doing it has proven elusive.

Are there any git projects, jsbins, twiddles or such that demonstrate the techniques needed to do this? Or someone adventurous enough to do a tutorial on it?


Solution

  • You can look at example from official guide of ember-power-select. The example fetches data from github repositories and its usage is pretty simple.

    Regarding the answer you have provided I would suggest the following changes:

    js file is:

    import Ember from 'ember';
    import config from '../../config/environment';
    
    export default Ember.Component.extend({
      company: null,
      router: Ember.inject.service('-routing'),
    
      ajax: Ember.inject.service(),
      countyNames: Ember.computed('company.state', function() {
        return this.get('ajax').request(config.host + '/api/counties/' + state).then((json) => json.map((county)=> {
          return county.name;
        });
      }),
    
      states: ['AK', 'AL', 'AR', 'AZ', 'CA', 'CO', 'CT', 'DC', 'DE', 'FL', 'GA', 'HI', 'IA', 'ID', 'IL', 'IN', 'KS', 'KY', 'LA', 'MA', 'MD', 'ME', 'MI', 'MN', 'MO', 'MS', 'MT', 'NC', 'ND', 'NE', 'NH', 'NJ', 'NM', 'NV', 'NY', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC', 'SD', 'TN', 'TX', 'UT', 'VA', 'VT', 'WA', 'WI', 'WV', 'WY'],
    
      actions: {
        // For dropdown handling
        chooseState(state) {
          this.set('company.state', state);
        },
    
        chooseCounty(countyName) {
          this.set('company.county', countyName);
        }
    });
    

    The template is:

      {{#power-select
        selected=company.state
        options=states
        onchange=(action "chooseState")
        as |name|
      }}
        {{name}}
      {{/power-select}}
    
      {{#power-select
        selected=company.county
        options=countyNames
        onchange=(action "chooseCounty")
        as |name|
      }}
        {{name}}
      {{/power-select}}
    

    The problem with the answer you have provided is that; you are providing a selected for county dropdown which is string (company.county); however your options for counties are json objects. Hence; the second dropdown is empty when you select it. Yet, in order the initial values for the second dropdown to appear you need to fetch the county names for the initial selected state. In order to overcome these two problems I defined countyNames computed property that will be the options for county dropdown. It depends on company.state; hence whenever the state of the company changes it will be recalculated. I also defined it to contain only the names of the counties so that selected value for dropdown will appear when you make a selection. Note that there should be some typos in code snippets I have provided because I did not try it; but I hope it will be enough for you to understand my point. Best regards.