Associative array State and City Combobox in Javascript

I'm trying to assemble this associative array, in the case of combobox for the state of São Paulo, it has to show 5 cities of São Paulo, if it is Rio de Janeiro, it shows the 5 cities of Rio de Janeiro.

HTML

<select id = "estados">
    <option></option>
</select>

<select id = "cidade">  
    <option></option>
</select>

Javascript

var select = document.getElementById("estados"); 
var cidade = document.getElementById("cidade"); 
var options = ["São Paulo", "Rio de Janeiro"]; 
var cidade1 = ["São Paulo", "Itápolis", "Araraquara", "Ribeirão Preto", "Jacareí"];
var cidade2 = ["Rio de Janeiro", "Niteroi", "Petropolis", "Belford Roxo", "Nova Iguaçu"];

In the following code it brings all the states, so far everything is fine.

for(var i = 0; i < options.length; i++) {
    var opt = options[i];
    var el = document.createElement("option");
    el.textContent = opt;
    el.value = opt;
    //console.log(el)
    select.appendChild(el);
}

Perfectly returning the states in the combobox. What I want now is that when I select the state it shows the cities in the other combobox, when it is the river it shows the cities of the river and when you select São Paulo show the cities of São Paulo. So I did this, but it doesn't return anything

Javascript

if(select){

    var t = document.getElementById("estados");
    var selectedText = t.options[t.selectedIndex].text;

    if(selectedText == 'São Paulo'){
        for(var j = 0; j < cidade1.length; j++) {
            var opt = cidade1[j];
            var el = document.createElement("option");
            el.textContent = opt;
            el.value = opt;
            cidade.appendChild(el);
        }   
    }

    if(selectedText == 'Rio de Janeiro'){
        for(var j = 0; j < cidade2.length; j++) {
            var opt = cidade2[j];
            var el = document.createElement("option");
            el.textContent = opt;
            el.value = opt;
            cidade.appendChild(el);
        }   
    }

}

I took advantage of the variable select, if it exists it enters the if, but the variable selectedText I made to receive the value of the combobox of the state it returns empty. Before I had leaving inside the for, ai repeated the empty field 5 times, I took it from inside the for it repeats once but still yes empty.

Since now I appreciate any help.

Author: Alison Paulo, 2017-05-15

3 answers

Two suggestions:

  • creates a function so you can reuse code
  • creates an object where the keys are the state names, so everything is organized and dependent on the JSON structure

So JSON can grow and have N states/cities without having to fiddle with the code any more.

var selectEstados = document.getElementById("estados");
var selectCidades = document.getElementById("cidade");
var cidades = {
  "São Paulo": ["São Paulo", "Itápolis", "Araraquara", "Ribeirão Preto", "Jacareí"],
  "Rio de Janeiro": ["Rio de Janeiro", "Niteroi", "Petropolis", "Belford Roxo", "Nova Iguaçu"],
  "Rio Grande do Sul": ["Porto Alegre", "Uruguaiana", "Passo Fundo"]
};

function adicionarOptions(select, options, chosen) {
  select.innerHTML = options.reduce((html, option) => {
    return html + `<option value="${option}">${option}</option>`;
  }, '<option disabled selected value>Escolha...</option>')
}

var estados = Object.keys(cidades);
const estadoInicial = estados[0];
adicionarOptions(selectEstados, estados, estadoInicial);
selectEstados.addEventListener('change', function() {
  adicionarOptions(selectCidades, cidades[this.value]);
});
<select id="estados">
  <option disabled selected value>Escolha...</option>
</select>

<select id="cidade">
  <option disabled selected value>Escolha...</option>
</select>
 6
Author: Sergio, 2019-05-28 05:08:25

Example

Javascript

var options = {
            "São Paulo" : ["São Paulo", "Itápolis", "Araraquara", "Ribeirão Preto", "Jacareí"], 
            "Rio de Janeiro":  ["Rio de Janeiro", "Niteroi", "Petropolis", "Belford Roxo", "Nova Iguaçu"]
        }; 

        var load= function(){
                var estados = document.getElementById("estados"); 
                var chaves = Object.keys(options);

                for(var i = 0; i < chaves.length; i++) {
                    var opt = chaves[i];
                    var el = document.createElement("option");
                    el.textContent = opt;
                    el.value = opt;
                    estados.appendChild(el);
                }
        }


        var setCidades = function (){
                var estados = document.getElementById("estados"); 
                var estado = estados.options[estados.selectedIndex].value;
                var cidades = options[estado];


                var cidade = document.getElementById("cidade");

                for(var i = 0; i < cidades.length; i++) {
                    var el = document.createElement("option");
                    el.textContent = cidades[i];
                    el.value =  cidades[i];
                    cidade.appendChild(el);
                }

        }

And in HTML:

<body onload="load();">
    estado
    <select id = "estados" onchange="setCidades(); return false;">
    </select>

    <br>

    cidade
    <select id = "cidade" >  
    </select>
</body>
 1
Author: Joe Torres, 2017-05-15 19:32:38

You need to associate the state change with an event. The way you're doing it is taking the first option (which is blank) and trying to load the cities, which will never work. If you want to see this, just take the empty options in the HTML:

<select id = "estados">

</select>

<select id = "cidade">  

</select>

Now, to solve your click-and-switch problem, you'll need a function that makes this change whenever the combo box changes, something like this:

In HTML add the onchange= " myFunction ()", which will call the function myfunction whenever any state is selected

<select id = "estados" onchange="myFunction()">
    <option></option>
</select>

<select id = "cidade">  
    <option></option>
</select>

In the function, put your code that was already ready:

myFunction  = function (){
    if(select){
      cidade.innerHTML = "";
      var t = document.getElementById("estados");
      var selectedText = t.options[t.selectedIndex].text;

      if(selectedText == 'São Paulo'){
          for(var j = 0; j < cidade1.length; j++) {
              var opt = cidade1[j];
              var el = document.createElement("option");
              el.textContent = opt;
              el.value = opt;
              cidade.appendChild(el);
          }   
      }

      if(selectedText == 'Rio de Janeiro'){
          for(var j = 0; j < cidade2.length; j++) {
              var opt = cidade2[j];
              var el = document.createElement("option");
              el.textContent = opt;
              el.value = opt;
              cidade.appendChild(el);
          }   
      }
  }
}

Here is the complete example https://jsfiddle.net/9kv5gyb3/3 /

 1
Author: Thiago de Campos, 2017-05-15 20:09:36