MaxelRus MaxelRus - 1 month ago 5
Javascript Question

Undefined is not an object in Dropdown

I want my code to show the menu by adding a

slactive
class and change the value of an input from
ddown
collection. I have some code, which isn't working as console says that on line 9 nor
ddown[i]
, nor
slitems[j]
are objects, as they're undefined. How to fix this?

var slitems = document.getElementsByClassName('slitem');
ddown = document.getElementsByClassName('ddown');
for(i=0; i<ddown.length; i++) {
ddown[i].addEventListener('click', function(){document.getElementById('sl'+i).classList.add('slactive');valueChange()});
}
function valueChange(){
for(j=0;j<slitems.length;j++){
slitems[j].addEventListener('click', function(){
ddown[i].value = slitems[j].value;
document.getElementById('sl'+i).classList.remove('slactive');
});
}
}


P.S.
slitems
is a collection of menu elements.

Answer

Look, what you are doing has at least two flaws:

1st: when doing this: for(i=0; i < ddown.length; i++) ... you are declaring a global variable named i that, at the end of loop will have the value ddown.length; so, in valueChange, it will always have the same value

2nd: i is set to ddown.length, that is a position that doesn´t exists in the array, hence the error you got.

To fix this, set i as a local variable using var, and pass it as an argument:

var slitems = document.getElementsByClassName('slitem');
    ddown = document.getElementsByClassName('ddown');
for(var i=0; i<ddown.length; i++) {
    ddown[i].setAttribute("data-index", i);
    ddown[i].addEventListener('click', function(e){
         var i = e.target.dataset.index;
         document.getElementById('sl'+i).classList.add('slactive');valueChange(i)
    });
}
function valueChange(i){
    for(var j=0;j<slitems.length;j++){
        slitems[j].setAttribute("data-index", j);
        slitems[j].setAttribute("data-index2", i);
        slitems[j].addEventListener('click', function(e){
            var j = e.target.dataset.index;
            var i = e.target.dataset.index2;
            ddown[i].value = slitems[j].value;
            document.getElementById('sl'+i).classList.remove('slactive');
        });
    }
}

EDIT

Changed the code to add the variables used in iterators as node attributes, what should fix the variable scope issue.