Google Earth Engine – How to Create Multiple Dropdown Lists Based on User Selection

dropdownlistgoogle-earth-enginegoogle-earth-engine-javascript-apiuser interface

// Let's add a dropdown with the location names using aggregate_array()
var items = India.aggregate_array('NAME_1');
items.evaluate(function(List) {
  dropdown.items().reset(List),
  dropdown.setPlaceholder('Select Location');
});
var dropdown =ui.Select({
  placeholder: 'please wait...',
  onChange : function(key){
    var region = India.filter(ee.Filter.eq('NAME_1',key));
    Map.clear();
    Map.centerObject(region,7);
    Map.addLayer(region,{},key);
  }
});

//Main Panel
var panel = ui.Panel({
  widgets: [dropdown],
  style: {backgroundColor: 'white'},
  layout: ui.Panel.Layout.flow('vertical')
});

//displaying the main panel
ui.root.insert(1,panel);

Here India is the shapefile and NAME_1 is the column containing State names. I want to modify the code such that when the user selects a State, a new dropdown list with the Districts of that particular State is made available for selection. NAME_2 is the column name for Districts.

Best Answer

It's a matter of updating the second dropdown options when the first dropdown changes. Something like this:

var India = ee.FeatureCollection([ // You didn't provide your features - making up some dummy ones
  ee.Feature(null, {NAME_1: 'State 1', NAME_2: 'District 1.1'}),
  ee.Feature(null, {NAME_1: 'State 1', NAME_2: 'District 1.2'}),
  ee.Feature(null, {NAME_1: 'State 1', NAME_2: 'District 1.3'}),
  ee.Feature(null, {NAME_1: 'State 2', NAME_2: 'District 2.1'}),
  ee.Feature(null, {NAME_1: 'State 2', NAME_2: 'District 2.2'}),
  ee.Feature(null, {NAME_1: 'State 2', NAME_2: 'District 2.3'}),
  ee.Feature(null, {NAME_1: 'State 3', NAME_2: 'District 3.1'}),
  ee.Feature(null, {NAME_1: 'State 3', NAME_2: 'District 3.2'}),
  ee.Feature(null, {NAME_1: 'State 3', NAME_2: 'District 3.3'}),
])

var statesDropdown = ui.Select({
  placeholder: 'Loading states...',
  disabled: true,
  onChange: onStateChange
})
updateStates()

var districtsDropdown = ui.Select({
  placeholder: 'First select a state',
  disabled: true,
  onChange: onDistrictChange
})

var panel = ui.Panel({
  widgets: [statesDropdown, districtsDropdown],
  style: {
    backgroundColor: 'white'
  },
  layout: ui.Panel.Layout.flow('vertical')
})
ui.root.insert(1, panel)


function onStateChange(stateId) {
  var districts = India.filter(ee.Filter.eq('NAME_1', stateId))
  updateDistricts(stateId, districts)
  addStateLayer(stateId, districts)  
}

function onDistrictChange(districtId) {
    var district = India.filter(ee.Filter.eq('NAME_2', districtId))
      .first()
    print('selected district', district)
  }

function updateStates() {
  ee.List(India.aggregate_array('NAME_1'))
    .distinct()
    .evaluate(function(states) {
      statesDropdown.items().reset(states)
      statesDropdown.setPlaceholder('Select State')
      statesDropdown.setDisabled(false)
    })    
}

function updateDistricts(stateId, state) {
  // Before districts have loaded
  districtsDropdown.items().reset([])
  districtsDropdown.setPlaceholder('Loading districts...')
  districtsDropdown.setDisabled(true)
  
  state
    .aggregate_array('NAME_2')
    .evaluate(function(districts) {
      // After districts have loaded
      districtsDropdown.items().reset(districts)
      districtsDropdown.setPlaceholder('Select District')
      districtsDropdown.setDisabled(false)
    })  
}

function addStateLayer(stateId, districts) {
    Map.clear()
    Map.centerObject(districts, 7)
    Map.addLayer(districts, {}, stateId)  
}

https://code.earthengine.google.com/e474a44ca84553570e11cba1436664b8