javascripthtmldhtml

Select list does not change selected item DHTML


I'm starting to develop websites (learning from 0). Of course, I apologize for my healthy ignorance (and my english level). I have 3 select in descending order: the 1st one contains a list of options that are loaded from a database (for now, I only load from HTML). Depending on the option selected, the 2nd select will be loaded with its options and so on until a 3rd select. The problem itself is solved, but when you want to select the options already loaded in the 2nd select, do not "click" on them. Only allows you to select the first one option. Here I leave the code to see if anyone can find any possible solution (and a lot of errors ^^).

var carsAndModels = {};
carsAndModels['Volvo'] = ['V70', 'XC60']; 
carsAndModels['Volkswagen'] = ['Golf', 'Polo']; 
carsAndModels['BMW'] = ['M6', 'X5'];
    
var speedsAndModels = {};
speedsAndModels['V70'] = ['150km/h', '180km/h']; 
speedsAndModels['XC60'] = ['160km/h', '190km/h'];
speedsAndModels['Golf'] = ['170km/h', '190km/h']; 
speedsAndModels['Polo'] = ['180km/h', '200km/h'];
speedsAndModels['M6'] = ['190km/h', '2000km/h']; 
speedsAndModels['X5'] = ['200km/h', '210km/h'];
    
function ChangeCarList() {
  var carList = document.getElementById('car');
  var modelList = document.getElementById('carmodel');
  var speedList = document.getElementById('speed');
  var selCar = carList.options[carList.selectedIndex].value;
  while (modelList.options.length) {
    modelList.remove(0);
    speedList.remove(0);
  }
  var cars = carsAndModels[selCar];
  if (cars) {
    for (i = 0; i < cars.length; i++) {
      var car = new Option(cars[i], i+1);
      modelList.options.add(car);
    }
  }
  ChangeModelList();
}
function ChangeModelList() {
  var modelListM = document.getElementById('carmodel');
  var speedListM = document.getElementById('speed');
  var indMod = modelListM.selectedIndex;
  var selMod = modelListM.options[indMod].text;
  while (speedListM.options.length) {
    speedListM.remove(0);
  }
  var speeds = speedsAndModels[selMod];
  if (speeds) {
    for (i = 0; i < speeds.length; i++) {
      var speed = new Option(speeds[i], i+1);
      speedListM.options.add(speed);
    }
  }
}
<div class="">
  <div class="">
	  <span>Select the brand</span><hr>
		<select id="car" onchange="ChangeCarList()">
		  <option value="">-- Select --</option> 
			<option value="Volvo">Volvo</option> 
			<option value="Volkswagen">Volkswagen</option> 
			<option value="BMW">BMW</option> 
		</select>
	</div>
	<div class="">
		<span>Select the model</span><hr>
		<select id="carmodel" onchange="ChangeCarList()"></select>
	</div>
	<div class="">
		<span>Select the speed control</span><hr>
		<select id="speed"></select>
	</div>
</div>

question: How to call the functions ("ChangeCarList" & "ChangeModelList") through the standard W3Schools in an external file? Thank you very much :).


Solution

  • The reason it is not working is because you are removing the options on selecting a different option. You need to remember the selected option in index like below. You may have to tidy up your solution even more but this solution will let select other options. Notice this added part in solution I propose.

    var index;
      if (value) {
        index = modelList.selectedIndex;
      }
    

    Here old index is being remembered. Here the option is selected based on remembered index, once you are done with adding options.

    modelList.selectedIndex = index;//<----This also is required
    

    var carsAndModels = {};
    carsAndModels['Volvo'] = ['V70', 'XC60'];
    carsAndModels['Volkswagen'] = ['Golf', 'Polo'];
    carsAndModels['BMW'] = ['M6', 'X5'];
    
    var speedsAndModels = {};
    speedsAndModels['V70'] = ['150km/h', '180km/h'];
    speedsAndModels['XC60'] = ['160km/h', '190km/h'];
    speedsAndModels['Golf'] = ['170km/h', '190km/h'];
    speedsAndModels['Polo'] = ['180km/h', '200km/h'];
    speedsAndModels['M6'] = ['190km/h', '2000km/h'];
    speedsAndModels['X5'] = ['200km/h', '210km/h'];
    
    function ChangeCarList(value) {
      var carList = document.getElementById('car');
      var modelList = document.getElementById('carmodel');
      var speedList = document.getElementById('speed');
      var selCar = carList.options[carList.selectedIndex].value;
      var index;
      if (value) {
        index = modelList.selectedIndex;
      }
      while (modelList.options.length) {
        modelList.remove(0);
        speedList.remove(0);
      }
      var cars = carsAndModels[selCar];
      if (cars) {
        for (i = 0; i < cars.length; i++) {
          var car = new Option(cars[i], i + 1);
          modelList.options.add(car);
        }
      }
      modelList.selectedIndex = index;
      ChangeModelList();
    }
    
    function ChangeModelList() {
      var modelListM = document.getElementById('carmodel');
      var speedListM = document.getElementById('speed');
      var indMod = modelListM.selectedIndex;
      var selMod = modelListM.options[indMod].text;
      while (speedListM.options.length) {
        speedListM.remove(0);
      }
      var speeds = speedsAndModels[selMod];
      if (speeds) {
        for (i = 0; i < speeds.length; i++) {
          var speed = new Option(speeds[i], i + 1);
          speedListM.options.add(speed);
        }
      }
    }
    <div class="">
      <div class="">
        <span>Select the brand</span>
        <hr>
        <select id="car" onchange="ChangeCarList()">
                <option value="">-- Select --</option> 
                <option value="Volvo">Volvo</option> 
                <option value="Volkswagen">Volkswagen</option> 
                <option value="BMW">BMW</option> 
            </select>
      </div>
      <div class="">
        <span>Select the model</span>
        <hr>
        <select id="carmodel" onchange="ChangeCarList(this.value)"></select>
      </div>
      <div class="">
        <span>Select the speed control</span>
        <hr>
        <select id="speed"></select>
      </div>
    </div>