State and City Combobox associative array in Javascript

Asked

Viewed 2,407 times

2

I’m trying to set up this associative array, in the case of the combobox is the state of São Paulo, it has to show 5 cities of São Paulo, if it is Rio de Janeiro, 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 states, so far so good.

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);
}

Returning perfectly the states in the combobox. What I want now is that when I select the state show the cities in the other combobox, when Rio show the cities of Rio and when Select São Paulo show the cities of São Paulo. So I did it, but nothing comes back

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 the variable select, if it exists enters if, but the variable selectedText I did to receive the value of the state’s combobox it returns empty. Before I had left inside the outdoors, then repeated the empty field 5 times, removed inside the for it repeats once but still empty.

From now on I appreciate any help.

3 answers

6


Two suggestions:

  • creates a role for you to reuse code
  • creates an object where keys are the names of the states, so everything is organized and dependent on the JSON structure

So JSON can grow and have N states/cities without needing to move the code further.

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>

1

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

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

<select id = "estados">

</select>

<select id = "cidade">  

</select>

Now, to solve your problem that is click and change, you will need to give a function that makes this change whenever the combo box changes, something like this:

NO HTML add onchange="myFunction()", which will call the myFunction function 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 full example https://jsfiddle.net/9kv5gyb3/3/

  • So there’s only one small problem when you do it this way, you need to remove the previous cities. Your I choose São Paulo will show all the cities of São Paulo, but if I move to Rio will show the cities of Rio but those of São Paulo, if I move again to São Paulo will show the cities of São Paulo, Rio and then São Paulo again, and so on. You have to find a way to reset the second combobox at the time of the change. But it really was what was missing in my code, but you need to make those changes that I told you about in your code, and I don’t think I know.

  • But my logic was correct just what you showed me was missing, but for your code to be perfect, that’s what I told you.

  • It is true, this detail was missing. To fix just clear the select before filling again, I will edit the code.

  • Now it’s gone, perfect !

Browser other questions tagged

You are not signed in. Login or sign up in order to post.