2

I am trying to add the same list of names to 10 different select forms in html via javascript. While this code works, it adds the list of names to each box 10 times. However, if I don't have the q loop, then nothing gets added at all.

I don't really know what I'm doing wrong, but I just don't want the same list of names to be added 10 times. Any ideas?

Thanks!

for(i = 0; i < 10; i++){
  var names = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
  //window.alert(names[i])
  document.write('<tr>');
  document.write('<td>');
  document.write('Enter name '+ names[i]);
  document.write('</td>');
  document.write('<td>');
  document.write('<select name=' + i + ' id=' + names[i] + '></select>');     
  var textFile = "/names.txt";       
  jQuery.get(textFile, function(textFileData) { 
  var EachName= textFileData.split("\n");
  for (q = 0; q < 10; q++) { 
    var select = document.getElementById(names[q]);
    for (var j = 0, len = EachName.length; j < len; j++) {
       var option = document.createElement('option');
       option.text = option.value = EachName[j];
       select.add(option, 0);
    }
   }
});
document.write('</td>');
document.write('</tr>');
};
brso05
  • 13,142
  • 2
  • 21
  • 40
Drew
  • 197
  • 2
  • 6
  • 13

3 Answers3

3

Check this out:

 for (q = 0; q < 10; q++) { 
     var select = document.getElementById(names[i]); //q should be i here...

In fact you don't need the loop at all:

var EachName= textFileData.split("\n");
var select = document.getElementById(names[i]);
for (var j = 0, len = EachName.length; j < len; j++) {
   var option = document.createElement('option');
   option.text = option.value = EachName[j];
   select.add(option, 0);
}

The problem is your adding the names to all selects every iteration of your outer loop the one with i.

Try this update:

for(i = 0; i < 10; i++){
  var names = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
  //window.alert(names[i])
  document.write('<tr>');
  document.write('<td>');
  document.write('Enter name '+ names[i]);
  document.write('</td>');
  document.write('<td>');
  document.write('<select name=' + i + ' id=' + names[i] + '></select>');     
  var textFile = "/names.txt";       
  var closure = function(counter, namesArray) {
     return function(textFileData) {
         var EachName= textFileData.split("\n");
         var select = document.getElementById("" + namesArray[counter]);
         for (var j = 0, len = EachName.length; j < len; j++) {
             var option = document.createElement('option');
             option.text = option.value = EachName[j];
             select.add(option, 0);
         }
     };
  }
  jQuery.get(textFile, closure(i, names));
  document.write('</td>');
  document.write('</tr>');
};

I got the code from here

Community
  • 1
  • 1
brso05
  • 13,142
  • 2
  • 21
  • 40
  • I had tried this originally, but for whatever reason, the lists are not populated if I remove the loop. That just doesn't make much sense to me – Drew Apr 17 '15 at 13:43
  • @Drew an easy workaround would be to leave the loop but only do 1 iteration. I'll edit my answer to show... – brso05 Apr 17 '15 at 13:46
  • @Drew there I updated the answer also you don't need `;` at the end of your loops... – brso05 Apr 17 '15 at 13:48
  • thanks for your help. If I try to add `i` where the `q` is, then I get the same error 10 times: `TypeError: Cannot read property 'add' of null`. But how can it be null if its defined above? – Drew Apr 17 '15 at 13:51
  • @Drew just check your `EachName` variable using `console.log(EachName)` – Bla... Apr 17 '15 at 13:53
  • @Drew I think you are trying to access an element via the dom before it's been added. Instead of adding options via dom manipulation add the options the same way you are adding the selects html direct injection... – brso05 Apr 17 '15 at 13:55
  • @Drew there i updated my answer to create the options using html injection. – brso05 Apr 17 '15 at 14:00
  • @Drew another problem is that `jQuery.get` is an asynchronous call – brso05 Apr 17 '15 at 14:05
  • @brso05, thank you for all your help. Unfortunately, the lists are still not populated. I found that as soon as I enter the jQuery loop, the original `i` becomes undefined. Can I pass it in somehow? – Drew Apr 17 '15 at 14:25
  • @Drew I updated my answer using a closure check it out see if it works for you... – brso05 Apr 17 '15 at 14:44
  • @brso05, I just got it, check below. All that was needed was to end the `i` loop after 10 iterations and then start the jQuery – Drew Apr 17 '15 at 14:51
  • @Drew if you want to try my answer with the closure it would save you from looping twice but if not it shouldn't be much overhead either way. – brso05 Apr 17 '15 at 14:54
0

Theres a few things going on here that are causing you problems: You're q loop is running after only 1 iteration (and every iteration thereafter) of the i looop that contains it, so it's trying to select elements that haven't yet been created as well as selecting the first one 10 times in total :( Also declare names outside the loop as theres no reason to declare it 10 times.

I don't have your textFile so I created a fake array with some names in it to create a similar effect for a version I made quickly. [edit] substituted your jQuery bit back in where I previously used an array for demonstration purposes.

var names = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
for(i = 0; i < 10; i++){
  //window.alert(names[i])
  document.write('<tr>');
  document.write('<td>');
  document.write('Enter name '+ names[i]);
  document.write('</td>');
  document.write('<td>');
  document.write('<select name=' + i + ' id=' + names[i] + '></select>');
  document.write('</td>');
  document.write('</tr>');
}
var eachName;
jQuery.get(textFile, function(textFileData) { 
  eachName = textFileData.split("\n");
});
for (q = 0; q < 10; q++) {
  var select = document.getElementById(names[q]);
  for (var j = 0; j < eachName.length; j++) {
    var option = document.createElement('option');
    option.text = option.value = eachName[j];
    select.add(option, 0);
  }
}
  • Thanks for your input, but unfortunately, the list has about 500 different names so it would probably be best to keep it in a text file – Drew Apr 17 '15 at 14:25
  • Thats fine swap out my declaration of an array for your bit of jQuery. I'll edit the post so it should work. – Stuart Stobie Apr 17 '15 at 14:35
  • It was also a bad idea to include your bit of jQuery in one of the loops as it ran 10 times when it only needed to be done once. – Stuart Stobie Apr 17 '15 at 14:43
0

This ended up working. I needed to break out of the first for loop and then go through and then add the names to the list

            for(i = 0; i < 10; i++){
                var names = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
                document.write('<tr>');
                document.write('<td>');
                document.write('Enter name '+ names[i]);
                document.write('</td>');
                document.write('<td>');
                document.write('<select name=' + i + ' id=' + names[i] + '></select>'); 
                document.write('</td>');
                document.write('</tr>');    
            };

            var textFile = "/names.txt";       
            jQuery.get(textFile, function(textFileData) { 
                var EachName= textFileData.split("\n"); 
                for (q = 0; q < 10; q++){ 
                    var select = document.getElementById(names[q]);
                    for (var j = 0, len = EachName.length; j < len; j++) {
                    var option = document.createElement('option');
                    option.text = option.value = EachName[j];
                        select.add(option, 0);
                 };
                     };
             });   
Drew
  • 197
  • 2
  • 6
  • 13