Soumya
Soumya

Reputation: 893

Dependent dropdowns to be added dynamically using javascript

I have a JSON object which contains categories and corresponding sub-categories.I have two dropdowns(as a row of a table), first dropdown contains the category list.When a particular category is selected, the second dropdown gets populated with the sub-catogories of the selected category. I have done this and is working fine.

Now, I have the requirement to add rows dynamically.Add row functionality is also working fine.

But I am not able to establish relation between the dropdowns in dynamically added rows.

I know the reason why - I am not able to assign id to the dynamically created dropdowns and hense am not able to establish any relationship between them.

Please suggest how to establish the required relationship.

<INPUT type="button" value="Add Row" onclick="addRow('dataTable')" />
<form id="myForm">
<TABLE id="dataTable" >
<TR><TD>
<select id="selectCategory" onchange="GetSelectedItem()">
<option>Choose a category</option>
</select>
</TD>
<TD>
<select id="selectSubCategory" >
<option>Choose a sub-category</option>
</select>
</TD></TR>
</TABLE>
</form>

Script:

    <script><!--
var jsonObj={"category1":["subcat 1"],"category2":["subcat 2.1","subcat 2.2"],"category3":["subcat 3.1","subcat 3.2","subcat 3.3"]};
var keys= Object.keys(jsonObj);
    var category_dropdown = document.getElementById("selectCategory"); 
for (var keys in jsonObj)    {              
    category_dropdown[category_dropdown.length] = new Option(keys,keys);        
    }
function GetSelectedItem()      {
            var e = document.getElementById("selectCategory");
            var selectedCategory = e.options[e.selectedIndex].value;

            var sub_category_dropdown = document.getElementById("selectSubCategory");   
            document.getElementById("selectSubCategory").options.length=0; //clearing previous values of the drop-down list
            for(var i=0;i<jsonObj[selectedCategory].length;i++)             {
                sub_category_dropdown[sub_category_dropdown.length] = new Option(jsonObj[selectedCategory][i],jsonObj[selectedCategory][i]);    
            }
    }
function addRow(tableID) 
    {

        var table = document.getElementById(tableID); 
        var rowCount = table.rows.length;
        var row = table.insertRow(rowCount);
         var colCount = table.rows[0].cells.length;

        for(var i=0; i<colCount; i++) {
            var newcell = row.insertCell(i);
             newcell.innerHTML = table.rows[0].cells[i].innerHTML;
             newcell.childNodes[0].selectedIndex = 0;

        }
    }
//--></script>  

Upvotes: 0

Views: 6007

Answers (1)

gmaliar
gmaliar

Reputation: 5489

The problem is that when you enter a dynamically created element you have to attach the events to it as well, with jquery you can delegate events, but because you don't use it so on the addRow function I added the eventListener.

But you are creating dynamic elements with the same ID, this is wrong, HTML specifies one ID per element. So you should change your IDs into class and have a specific ID for each row element. Because HTML works even if it's broken, I added a little check to the code to see if it's the initial row or a dynamically created one, so you can know to which one of the select boxes (with the same ID) to attach the event listener (getElementById returns the first it finds). So this will work but it's really bad practice.

I've added just a bit of jQuery into the mix but you can take it out, just for the event listeners.

This is the jsfiddle of it.

http://jsfiddle.net/C2xsj/5/

and here is the HTML

<INPUT type="button" value="Add Row" id="button"/>
<form id="myForm">
<TABLE id="dataTable" >
<TR><TD>
<select id="selectCategory">
<option>Choose a category</option>
</select>
</TD>
<TD>
<select id="selectSubCategory" >
<option>Choose a sub-category</option>
</select>
</TD></TR>
</TABLE>
</form>

and the code

$(function () {
    $('#selectCategory').change(function() {
        getSelectedItem(this, null);
    });

    $('#button').click(function() {
        addRow('dataTable');
    });

    var jsonObj = {"category1":["subcat 1"],"category2":["subcat 2.1","subcat 2.2"],"category3":["subcat 3.1","subcat 3.2","subcat 3.3"]};
var keys = Object.keys(jsonObj);
var category_dropdown = document.getElementById("selectCategory"); 

var getSelectedItem = function(element, row) {
    var e = element;
    var selectedCategory = e.options[e.selectedIndex].value;
    var sub_category_dropdown = (row != null ? row.getElementsByTagName("select")[1] : document.getElementById("selectSubCategory"));
    sub_category_dropdown.options.length=0;
    for (var i=0;i<jsonObj[selectedCategory].length;i++) {
        sub_category_dropdown[sub_category_dropdown.length] = new Option(jsonObj[selectedCategory][i],jsonObj[selectedCategory][i]);
    }
};

var addRow = function(tableID) {
        var table = document.getElementById(tableID); 
        var rowCount = table.rows.length;
        var row = table.insertRow(rowCount);
        var colCount = table.rows[0].cells.length;

       for (var i = 0; i<colCount; i++) {
             var newcell = row.insertCell(i);
             newcell.innerHTML = table.rows[0].cells[i].innerHTML;
             newcell.childNodes[0].selectedIndex = 0;
    }
    var selects = row.getElementsByTagName("select");
    selects[0].addEventListener('change', function() { getSelectedItem(this, row) }, false);
};

    for (var keys in jsonObj) {              
        category_dropdown[category_dropdown.length] = new Option(keys,keys);        
    }   
});

Upvotes: 1

Related Questions