1

I have two drop down menus with the id validKeys1 and validKeys2, I'm trying to populate the drop downs from an array using the javascript code below, but it will only populate validKeys2. How do I use the same piece of javascript on multiple IDs?

var validKeys1 = document.getElementById("validKeys1");
var validKeys2 = document.getElementById("validKeys2");

for(var i = 0; i < validCoursesKeys.length; i++) {
    var opt = validCoursesKeys[i];
    var el = document.createElement("option");
    el.textContent = opt;
    el.value = opt;
    validKeys1.appendChild(el);
    validKeys2.appendChild(el);
}
Zakaria Acharki
  • 66,747
  • 15
  • 75
  • 101
stumpylumpy
  • 45
  • 1
  • 7
  • you have to create `option` for each "validKey", you can't use a single HTML element in two places (appendChild will "move" an element from it's current location to where you are appending it - this is why only validKeys2 ends up with options) – Jaromanda X Nov 20 '16 at 22:09

4 Answers4

2

appendChild() takes the element that is passed and moves it into the parent element. Meaning if it is already inside one element it is removed from there and placed into the other.

You can either make a whole new element or use cloneNode() to add to your second select

validKeys1.appendChild(el);
validKeys2.appendChild(el.cloneNode(true));
Patrick Evans
  • 41,991
  • 6
  • 74
  • 87
1

You could use general class instead and cloneNode to duplicate the node el every time you append it :

var validKeys = document.getElementsByClassName("validKeys");

for(var i = 0; i < validCoursesKeys.length; i++) {
    var opt = validCoursesKeys[i];
    var el = document.createElement("option");
    el.textContent = opt;
    el.value = opt;

    for(var j = 0; j < validKeys.length; j++) {
         validKeys[j].appendChild(el.cloneNode(true));
    }
}

Hope this helps.

var validCoursesKeys = ['opt 1','opt 2','opt 3','opt 4']
var validKeys = document.getElementsByClassName("validKeys");

for(var i = 0; i < validCoursesKeys.length; i++) {
  var opt = validCoursesKeys[i];
  var el = document.createElement("option");
  
  el.textContent = opt;
  el.value = opt;

  for(var j = 0; j < validKeys.length; j++) {
    validKeys[j].appendChild(el.cloneNode(true));
  }
}
<select class="validKeys"></select>
<select class="validKeys"></select>
<select class="validKeys"></select>
Zakaria Acharki
  • 66,747
  • 15
  • 75
  • 101
  • Thanks. I was originally trying to do it with `class` like this: https://jsfiddle.net/ndo1xrmk/ but it's obviously wrong.....how is the HTML supposed to look for this to work?? (Sorry, super new to HTML/JS. Been using for like three days) – stumpylumpy Nov 20 '16 at 22:16
  • using class isn't the solution - it's the `clone` that solves the problem – Jaromanda X Nov 20 '16 at 22:17
  • @JaromandaX is right the main idea is about cloning the node `el` so we can append it to multiple list, but IMO using class in this case is more efficient than ids. – Zakaria Acharki Nov 20 '16 at 22:18
  • @ZakariaAcharki we posted so close together I missed the snippet. Thanks! – stumpylumpy Nov 20 '16 at 22:21
1

Your code is actually appending the option element to validKeys1 and then changing its parent to validKeys2. This should work as you expected.

var validKeys1 = document.getElementById("validKeys1");
var validKeys2 = document.getElementById("validKeys2");

for(var i = 0; i < validCoursesKeys.length; i++) {
    var opt = validCoursesKeys[i];
    var el = document.createElement("option");
    el.textContent = opt;
    el.value = opt;
    validKeys1.appendChild(el);
    var el2 = el.cloneNode(false);
    validKeys2.appendChild(el2);
}
Gerrit0
  • 7,955
  • 3
  • 25
  • 32
1

this might be also useful, using the forEach method on array

var validKeys1 = document.getElementById("validKeys1");
var validKeys2 = document.getElementById("validKeys2");
[validKeys1, validKeys2].forEach((ids) => {
     validCoursesKeys.forEach((courses) => {
        var opt = courses
        var el = document.createElement('option');
        el.textConent = opt;
        el.value = opt;
        ids.appendChild(el)
   })
})
0.sh
  • 2,659
  • 16
  • 37