Zim
Zim

Reputation: 271

Dynamically Populating Drop down list from selection of another drop down value

My requirement is that for a selection in a 'meal' drop down list, a second drop down list 'category' should get dynamically populated with values related to the selection in first drop down list. Then depending on what is selected in the meal dropdown, the list should change in category. I have written the following Javascript function but the output I'm getting is not freshly populating the 2nd dropdown. On change of a selection, the new list is just getting appended to the old list.

function changecat() {
    var selectHTML = "";

    var A = ["Soup", "Juice", "Tea", "Others"];
    var B = ["Soup", "Juice", "Water", "Others"];
    var C = ["Soup", "Juice", "Coffee", "Tea", "Others"];

    if (document.getElementById("meal").value == "A") {
        var select = document.getElementById('category').options.length;

        for (var i = 0; i < select; i++) {
            document.getElementById('category').options.remove(i);
        }

        for (var i = 0; i < A.length; i++) {
            var newSelect = document.createElement('option');
            selectHTML = "<option value='" + A[i] + "'>" + A[i] + "</option>";
            newSelect.innerHTML = selectHTML;
            document.getElementById('category').add(newSelect);
        }
    }

    else if (document.getElementById("meal").value == "B") {
        var select = document.getElementById('category').options.length;

        for (var i = 0; i < select; i++) {
            document.getElementById('category').options.remove(i);
        }

        for (var i = 0; i < B.length; i++) {
            var newSelect = document.createElement('option');
            selectHTML = "<option value='" + B[i] + "'>" + B[i] + "</option>";
            newSelect.innerHTML = selectHTML;
            document.getElementById('category').add(newSelect);
        }
    }

    else if (document.getElementById("project").value == "C") {
        var select = document.getElementById('category').options.length;

        for (var i = 0; i < select; i++) {
            document.getElementById('category').options.remove(i);
        }

        for (var i = 0; i < C.length; i++) { 
            var newSelect = document.createElement('option');
            selectHTML = "<option value='" + C[i] + "'>" + C[i] + "</option>";
            newSelect.innerHTML = selectHTML;
            document.getElementById('category').add(newSelect);
        }
    }
}

HTML-  
<select name="meal" id="meal" onchange="changecat();">
    <option value="">Select</option>
    <option value="A">A</option>
    <option value="B">B</option>
    <option value="C">C</option>
</select>

<select name="category" id="category">
    <option value="">Select</option>
</select>

Upvotes: 21

Views: 113110

Answers (3)

divy3993
divy3993

Reputation: 5810

Hope this might help you.

JSFiddle : DEMO

HTML

<select name="meal" id="meal" onChange="changecat(this.value);">
    <option value="" disabled selected>Select</option>
    <option value="A">A</option>
    <option value="B">B</option>
    <option value="C">C</option>
</select>
<select name="category" id="category">
    <option value="" disabled selected>Select</option>
</select>

JS

var mealsByCategory = {
    A: ["Soup", "Juice", "Tea", "Others"],
    B: ["Soup", "Juice", "Water", "Others"],
    C: ["Soup", "Juice", "Coffee", "Tea", "Others"]
}

    function changecat(value) {
        if (value.length == 0) document.getElementById("category").innerHTML = "<option></option>";
        else {
            var catOptions = "";
            for (categoryId in mealsByCategory[value]) {
                catOptions += "<option>" + mealsByCategory[value][categoryId] + "</option>";
            }
            document.getElementById("category").innerHTML = catOptions;
        }
    }

There is a loop (for...in loop) in JavaScript, which would help you in this case

A for...in loop only iterates over enumerable properties. Objects created from built–in constructors like Array and Object have inherited non–enumerable properties from Object.prototype and String.prototype, such as String's indexOf() method or Object's toString() method. The loop will iterate over all enumerable properties of the object itself and those the object inherits from its constructor's prototype (properties closer to the object in the prototype chain override prototypes' properties).

In each iteration one property from object is assigned to variable-name and this loop continues till all the properties of the object are exhausted.

For more Link

Upvotes: 25

aditya kansal
aditya kansal

Reputation: 11

The reason why your code gets appended is because in the for loop for clearing the second drop down list, the update expression is not required as the list is itself being reduced in size and so in every iteration the length of the list decreases, and so you are unable to clear the whole list. Also the removal function should be outside the if conditions to avoid redundancy.`function changecat() { var selectHTML = "";

var A = ["Soup", "Juice", "Tea", "Others"];
var B = ["Soup", "Juice", "Water", "Others"];
var C = ["Soup", "Juice", "Coffee", "Tea", "Others"];
var select = document.getElementById('category').options.length;

    for (var i = 0; i < select; ) {
        document.getElementById('category').options.remove(i);
    }

if (document.getElementById("meal").value == "A") {


    for (var i = 0; i < A.length; i++) {
        var newSelect = document.createElement('option');
        selectHTML = "<option value='" + A[i] + "'>" + A[i] + "</option>";
        newSelect.innerHTML = selectHTML;
        document.getElementById('category').add(newSelect);
    }
}

else if (document.getElementById("meal").value == "B") {

    for (var i = 0; i < B.length; i++) {
        var newSelect = document.createElement('option');
        selectHTML = "<option value='" + B[i] + "'>" + B[i] + "</option>";
        newSelect.innerHTML = selectHTML;
        document.getElementById('category').add(newSelect);
    }
}

else if (document.getElementById("project").value == "C") {

    for (var i = 0; i < C.length; i++) { 
        var newSelect = document.createElement('option');
        selectHTML = "<option value='" + C[i] + "'>" + C[i] + "</option>";
        newSelect.innerHTML = selectHTML;
        document.getElementById('category').add(newSelect);
    }
}

}

Upvotes: 1

cнŝdk
cнŝdk

Reputation: 32145

You can use onchange event and use a switch statement with the selected value from the first dropdown and according to it append the options to the second list:

    var A= ["Soup", "Juice", "Tea","Others"];
    var B= ["Soup","Juice","Water", "Others"];
    var C= ["Soup","Juice","Coffee", "Tea","Others"];

var changeCat = function changeCat(firstList) {
    var newSel = document.getElementById("category");
    //if you want to remove this default option use newSel.innerHTML=""
    newSel.innerHTML="<option value=\"\">Select</option>"; // to reset the second list everytime
    var opt;

      //test according to the selected value
      switch (firstList.options[firstList.selectedIndex].value) {
          case "A":
              for (var i=0; len=A.length, i<len; i++) {
                    opt = document.createElement("option");
                    opt.value = A[i];
                    opt.text = A[i];
                    newSel.appendChild(opt);
              }
              break;
          case "B":
              for (var i=0; len=B.length, i<len; i++) {
                    opt = document.createElement("option");
                    opt.value = B[i];
                    opt.text = B[i];
                    newSel.appendChild(opt);
              }
              break;
          case "C":
              for (var i=0; len=C.length, i<len; i++) {
                    opt = document.createElement("option");
                    opt.value = C[i];
                    opt.text = C[i];
                    newSel.appendChild(opt);
              }
              break;
      }

}
<select name="meal" id="meal" onchange="changeCat(this);">
     <option value="">Select</option>
     <option value="A">A</option>
     <option value="B">B</option>
     <option value="C">C</option>
</select>

<select name="category" id="category" size="5">
     <option value="">Select</option>
</select>

I used size="5" with the second dropdown to see the live result changes for each selection.

Upvotes: 1

Related Questions