views:

44

answers:

4

This is weird, im trying to clear my select list and exactly half is being cleared, not everything. Its also every other item which is left behind. I havent included the data here, but just the setup of the select list. The data is 10 items and only 5 are deleted. UniList calls DeleteAll. The first alert prints out '10' and the second prints out '5'

DID is just document.getelementbyid()

function DeleteAll(string) {

       var i;
       var list = DID(string);

       alert(DID(string).options.length);

       for (i = 0; i<list.options.length; i++) {
           list[i] = null;
       }
       alert(list.options.length);
       alert("finished deleting");
}

<select size='12' name='UniList' id='UniList' style='width:180px;' onclick=changeuni('UniList','Uni')>
    <option value=''></option>
    <option value=''></option>
    <option value=''></option>
</select>
A: 

Try looping from the end of the select list to the beginning. UI suspect as you are deleting them it is reordering the array such that once you have deleted half your next index then is over the top. eg if you have 10 items then after deleting 5 it will try to delete item with index 6 but you only have a list length of 5 so that won't work...

So basically try:

   for (i = list.options.length-1 ; i>=0; i--) {
       list[i] = null;
   }

I think I got my indexes right there but adjust the loop accordingly in case I got it wrong.

Edit:

I realised that there is also a better way to delete. Just use list.options.length=0 will clear your list. I've put some examples into a jsFiddle so you can see them in action (and so I coudl test they worked).

http://jsfiddle.net/HUvA2/3/ - The first button runs your method (You'll see it deletes every other entry) and the second runs my modified loop which you can see gets rid of them all. The "best" button just sets the list length to 0. :)

Chris
+5  A: 

list.options is a HTMLOptionsCollection that is assumed to be live:

Note: Collections in the HTML DOM are assumed to be live meaning that they are automatically updated when the underlying document is changed.

So with every iteration one item is removed and the document is updated so that list.options and thus list.options.length is updated too. So instead of removing the first, second, third, etc. option of the list you actually remove the first, third, fifth, etc. option.

Use list.options[0] instead to always remove the first option:

while (list.options.length > 0) {
    list.options[0] = null;
}

Or remove the options from behind:

for (i = list.options.length-1; i>=0; i--) {
    list.options[i] = null;
}

By the way: The HTMLSelectElement has a remove method to remove an option by its index:

while (list.length > 0) {
    list.remove(0);
}
Gumbo
Hey thanks, the list[0] didnt work but the decrementing index did
Tom
@Tom: Um, shouldn’t it be `list.options[0]` since you want to remove the options?
Gumbo
+4  A: 

You could just replace your existing DeleteAll function with

function DeleteAll(listId) {
   var list = document.getElementById(listId);
   list.options.length=0;
}

or even

function DeleteAll(listId) {
   document.getElementById(listId).options.length=0;
}

If you still prefer to use DID() you can just swap it in

irishbuzz
+1  A: 

This might be an option as well

while ( list.options.length > 0 ) { list[0] = null; }

Fredrik Norlin