Manipulate select, optgroup, option boxes

S

Stewart

Dear comp.lang.javascript,

I have more than once wanted to manipulate the contents of select boxes
dynamically, whilst the boxes contain <optgroup> tags.
Manipulation of a select box containing only <option> tags is fairly
easy and there is plenty of material on the net to assist with this.
However, I have searched long and found the material on the subject of
<optgroup> to be sparse, with a few posts here & there, but basically
you're on your own.

After much trial & error regarding techniques for this, I have a fairly
generic solution, which I decided to share, and the code is below. Two
different scenarios I have come across are (1) altering the contents of
one <select> dynamically depending upon another, and (2) being able
click 'up' and 'down' buttons to alter the sequence of the listing
(whilst keeping each <option> within its respective <optgroup>) I tried
various solutions for both of these which tended to either trash the
screen, alter which <optgroup> an <option> was under or trash the
<optgroup>s altogether.
Both these situations can be handled with the solution here. Basically
I keep the <optgroup>s and <option>s stored in an Array(), and then use
the Array() to reconstruct the <select>.
To use, just manipulate the Array() in memory - which I find very easy
- and then call the function to reconstruct.
I like to build the <select> <optgroup> <option> set using HTML as
normal and then create the Array() with <body onload=""> as this makes
it usable where javascript is unavailable, rather than have the Array()
as a hard-coded start point.

Reasonably tested on IE6, known to be buggy on Opera 8 - not sure why.

Constructive comments, insights, additions etc, are welcome.

Thank you,

Stewart


<html>
<head>
<script type="text/javascript">
var selectOptions = new Array(
new Array('Group One',
new Array('Option One', 21),
new Array('Option Two', 22),
new Array('Option Three', 23)),
new Array('Group Two',
new Array('Option Four', 24),
new Array('Option Five', 25),
new Array('Option Six', 26)),
new Array('Group Three',
new Array('Option Seven', 27),
new Array('Option Eight', 28),
new Array('Option Nine', 29)));

function constructArray(list)
{
selectOptions = new Array();
var optgroups = list.childNodes;
var m = 0;
for(i = 0 ; i < optgroups.length ; i++)
{
var n = 1;
if(optgroups.nodeName == 'OPTGROUP')
{
selectOptions[m] = new Array(optgroups.label);
var options = optgroups.childNodes;
for(j = 0 ; j < options.length ; j++)
{
if(options[j].nodeName == 'OPTION')
{
selectOptions[m][n++] =
new Array(options[j].text, options[j].value);
}
}
m++;
}
}
reConstructSelectBox(list);
}

function reConstructSelectBox(list)
{
// Javascript re-indexs after each null or removeChild()
// so we have to count backwards
for(i = list.options.length - 1 ; i >= 0 ; i--)
{
list.options = null;
}
var optgroups = list.childNodes;
for(i = optgroups.length - 1 ; i >= 0 ; i--)
{
list.removeChild(optgroups);
}
var k = 0;
for(i = 0 ; i < selectOptions.length ; i++)
{
var group = selectOptions;
var optgroup = document.createElement('optgroup');
optgroup.label = group[0];
list.appendChild(optgroup);
for(j = 1 ; j < group.length ; j++)
{
var option = new Option(group[j][0], group[j][1]);
list.options[k++] = option;
}
}
}
</script>
</head>
<body onload="constructArray(this.form.list);">
<form method="post" action="" name="form">
<select name="list" size="15" id="list">
<optgroup label="Group One">
<option value="21">Option One</option>
<option value="22">Option Two</option>
<option value="23">Option Three</option>
</optgroup>
<optgroup label="Group Two">
<option value="24">Option Four</option>
<option value="25">Option Five</option>
<option value="26">Option Six</option>
</optgroup>
<optgroup label="Group Three">
<option value="27">Option Seven</option>
<option value="28">Option Eight</option>
<option value="29">Option Nine</option>
</optgroup>
</select>
</body>
</html>
 
S

Stewart

VK said:
Cool but not stable.
A lot of things to learn yet.

A reply which arouses curiosity, but fails to enlighten!

Pray tell, where should I find these many things I have yet to learn?
 
S

Stewart

Reasonably tested on IE6, known to be buggy on Opera 8 - not sure why.

Found that the bit that doesn't work in Opera is the removeChild() call
in this section:
var optgroups = list.childNodes;
for(i = optgroups.length - 1 ; i >= 0 ; i--)
{
list.removeChild(optgroups);
}


Apparently others have come across this, see post entitled "select
element, optgroup and removeChild" by Lasse Reichstein Nielsen, Jul 21
2003, 11:26 pm, in group opera.beta
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,906
Latest member
SkinfixSkintag

Latest Threads

Top