CJSolo
CJSolo

Reputation: 25

How can I create more than one dynamic select box dependent on one selection?

I am trying to create a form that has multiple combo box selections. I want the selection of the first combo box to affect the choices in the following boxes. I have only been able to get a single pair to work. I duplicated the function and changed the IDs so that it would reflect in the arguments passed, but it still only worked for the one pair. The code below is what I started with through a tutorial I wanted to add additional boxes, for example Chevy has the colors white, black red, dodge has the colors blue, green and black. How would I make additional boxes dependent on the first one?

I tried copying the function and the html line and changing the id and name to have slct1, slct2, slct3. When I added the populate function, I passed s1,s3 as the new argument. I also tried including it all in the one function and added the additional arguments to be passed.

<!DOCTYPE html>
<html>
<head>
<script>
function populate(s1,s2){
    var s1 = document.getElementById(s1);
    var s2 = document.getElementById(s2);
    s2.innerHTML = "";
    if(s1.value == "Chevy"){
        var optionArray = ["|","camaro|Camaro","corvette|Corvette","impala|Impala"];
    } else if(s1.value == "Dodge"){
        var optionArray = ["|","avenger|Avenger","challenger|Challenger","charger|Charger"];
    } else if(s1.value == "Ford"){
        var optionArray = ["|","mustang|Mustang","shelby|Shelby"];
    }
    for(var option in optionArray){
        var pair = optionArray[option].split("|");
        var newOption = document.createElement("option");
        newOption.value = pair[0];
        newOption.innerHTML = pair[1];
        s2.options.add(newOption);
    }
}
</script>
</head>
<body>
<h2>Choose Your Car</h2>
<hr />
Choose Car Make:
<select id="slct1" name="slct1" onchange="populate(this.id,'slct2')">
    <option value=""></option>
    <option value="Chevy">Chevy</option>
    <option value="Dodge">Dodge</option>
<option value="Ford">Ford</option>
</select>
<hr />
Choose Car Model:
<select id="slct2" name="slct2"></select>
<hr />  
</body>
</html>

My expected results are that the user select a car (Chevy, Dodge, Ford, etc), then additional boxes populate with options based on that choice, model and color for example. I have only been able to get the primary box and the first dependent box to work.

Upvotes: 0

Views: 194

Answers (3)

Ricardo Ferreira
Ricardo Ferreira

Reputation: 616

I did some changes in your code:

Get the references just once

the selects are always the same only the options changes, so I moved the selection to another scope.

var form = document.querySelector('form');
var brandSelect = form.querySelector('#brand');
var modelSelect = form.querySelector('#model');
var colorSelect = form.querySelector('#color');

Clone elements

Clone objects instead request to the DOM create new all the time.

var optionElement = document.createElement('option');
...
var optionModel = optionElement.cloneNode(true);

Protect the scope

Wrap your code in a auto called function to avoid put your variable and function in the global scope. This avoid some possible conflicts between libraries.

(function(){...})();

Create a data reference

Data reference is more readable its easy to debug if something goes wrong also.

var brandOptions = {
  Chevy: {
    model: ['camaro', 'corvette', 'impala'],
    color: ['white', 'black', 'red'],
  },
  Dodge: {
    model: ['avenger', 'challenger', 'charger'],
    color: ['blue', 'green', 'black'],
  },
  Ford: {
    model: ['camaro', 'corvette', 'impala'],
    color: ['red', 'green', 'blue'],
  },
}

Full Example

(function(){
  var form = document.querySelector('form');
  var brandSelect = form.querySelector('#brand');
  var modelSelect = form.querySelector('#model');
  var colorSelect = form.querySelector('#color');
  var optionElement = document.createElement('option');
  
  var brandOptions = {
    Chevy: {
      model: ['camaro', 'corvette', 'impala'],
      color: ['white', 'black', 'red'],
    },
    Dodge: {
      model: ['avenger', 'challenger', 'charger'],
      color: ['blue', 'green', 'black'],
    },
    Ford: {
      model: ['camaro', 'corvette', 'impala'],
      color: ['red', 'green', 'blue'],
    },
  };
  
  function addOptionIntheSelect(options) {
    modelSelect.innerHTML = '';
    
    options.model.forEach(function(model) {
      var optionModel = optionElement.cloneNode(true);
      optionModel.value = model;
      optionModel.innerHTML = model;
      modelSelect.appendChild(optionModel);
    });
    
    colorSelect.innerHTML = '';
    
    options.color.forEach(function(color) {
      var optionColor = optionElement.cloneNode(true);
      optionColor.value = color;
      optionColor.innerHTML = color;
      colorSelect.appendChild(optionColor);
    });
  }
  
  function onSelectChange(event) {
    addOptionIntheSelect(brandOptions[event.target.value]);
  }
  
  brandSelect.onchange = onSelectChange;
})();
.container {
  width: 100%;
  max-width: 300px;
  margin: 0 auto;
}

label, select {
  display: block;
  width: 100%;
  box-sizing: borde-box;
}

select {
  text-transform: Capitalize;
}

label {
  margin-bottom: 8px;
}

form > div {
  padding: 8px 0;
}
<div class="container">
  <form>
    <div>
      <label for="">Choose Car Make:</label>
      <select id="brand" name="brand">
        <option value=""></option>
        <option value="Chevy">Chevy</option>
        <option value="Dodge">Dodge</option>
        <option value="Ford">Ford</option>
      </select>
    </div>

    <div>
      <label for="">Choose Car Model:</label>
      <select id="model" name="slct2"></select>
    </div>

    <div>
      <label for="">Choose Car Color:</label>
      <select id="color" name="slot3"></select>  
    </div>
  </form>  
</div>

Upvotes: 0

Ketzalkoatl Rosas A
Ketzalkoatl Rosas A

Reputation: 1

Here the code where I add only for the first option the colors Red, White and Black. The other options have no color Greeting

enter code here
<!DOCTYPE html>
<html>
<head>

<script>
function populate(s1,s2,slcolor){
    var s1 = document.getElementById(s1);
    var s2 = document.getElementById(s2);
    s2.innerHTML = "";
    slcolor.innerHTML= "";
    if(s1.value == "Chevy"){
        var optionArray = ["|","camaro|Camaro","corvette|Corvette","impala|Impala"];
        var optionColor = ["|","red|Red","white|White","black|Black"];
    } else if(s1.value == "Dodge"){
        var optionArray = ["|","avenger|Avenger","challenger|Challenger","charger|Charger"];
        var optionColor = ["|"];
    } else if(s1.value == "Ford"){
        var optionArray = ["|","mustang|Mustang","shelby|Shelby"];
        var optionColor = ["|"];
    }
    for(var option in optionArray) {
        var pair = optionArray[option].split("|");
        var newOption = document.createElement("option");
        newOption.value = pair[0];
        newOption.innerHTML = pair[1];
        s2.options.add(newOption);
    }

    for(var option in optionArray) {
        var pair = optionColor[option].split("|");
        var newOptionC = document.createElement("option");
        newOptionC.value = pair[0];
        newOptionC.innerHTML = pair[1];
        slcolor.options.add(newOptionC);
    }

}
</script>
</head>
<body>
<h2>Choose Your Car</h2>
<hr />
Choose Car Make:
<select id="slct1" name="slct1" onchange="populate(this.id,'slct2',slcolor)">
    <option value=""></option>
    <option value="Chevy">Chevy</option>
    <option value="Dodge">Dodge</option>
<option value="Ford">Ford</option>
</select>
<hr />
Choose Car Model:
<select id="slct2" name="slct2"></select>
<hr /> 

Choose Color:
<select id="slcolor" name="slcolor"></select>
<hr />  

</body>
</html>

Upvotes: 0

Chase Ingebritson
Chase Ingebritson

Reputation: 1579

Here's an example of how you would add on another <select> to the pattern you've established. There are probably cleaner ways to do this, but to adhere to the tutorial this will work.

function populate(s1) {
  var s1 = document.getElementById(s1);
  var s2 = document.getElementById('model');
  var s3 = document.getElementById('color');
  
  s2.innerHTML = "";
  s3.innerHTML = "";
  
  if (s1.value == "Chevy") {
    var modelArray = ["|", "camaro|Camaro", "corvette|Corvette", "impala|Impala"];
    var colorArray = ["|", "red|Red", "green|Green", "blue|Blue"];
  } else if (s1.value == "Dodge") {
    var modelArray = ["|", "avenger|Avenger", "challenger|Challenger", "charger|Charger"];
    var colorArray = ["|", "red|Red", "green|Green", "blue|Blue"];
  } else if (s1.value == "Ford") {
    var modelArray = ["|", "mustang|Mustang", "shelby|Shelby"];
    var colorArray = ["|", "red|Red", "green|Green", "blue|Blue"];
  }
  
  for (var option in modelArray) {
    var pair = modelArray[option].split("|");
    var newOption = document.createElement("option");
    newOption.value = pair[0];
    newOption.innerHTML = pair[1];
    s2.options.add(newOption);
  }
  
  for (var option in colorArray) {
    var pair = colorArray[option].split("|");
    var newOption = document.createElement("option");
    newOption.value = pair[0];
    newOption.innerHTML = pair[1];
    s3.options.add(newOption);
  }
}
<h2>Choose Your Car</h2>
<hr /> Choose Car Make:
<select id="slct1" name="slct1" onchange="populate(this.id)">
  <option value=""></option>
  <option value="Chevy">Chevy</option>
  <option value="Dodge">Dodge</option>
  <option value="Ford">Ford</option>
</select>
<hr /> Choose Car Model:
<select id="model" name="slct2"></select>
<hr /> Choose Car Color:
<select id="color" name="slot3"></select>
<hr />

Let me know if you have any questions!

Upvotes: 1

Related Questions