Dynamic SELECT boxes with <OPTGROUP>s

C

cedawe

I have two select boxes. When the user picks a value in the first one it
completely re-populates the second one. It works fine, but only generates a
standard OPTIONS list and I now want to group the options using OPTGROUPs.


<select name="Selector1" size="1"
onchange="reload2(this.options.selectedIndex, document.Form1.Selector2)">
<option .....
</select>

<script type="text/javascript">
function reload2(Index1, Selector2)
{
// Do not bother blanking '0', as it will always be re-written.
for (x1=Selector2.options.length-1; x1>0; x1--)
{
Selector2.options[x1]=null;
}

switch (Index1)
{
case 0: // Disclaimer
Selector2.options[0]=new Option("Disclaimer",
"disclaimer.html");
break;

case 1: // Chapter 1
Selector2.options[0]=new Option("Chapter 1 Title",
"chapter1.html");
Selector2.options[1]=new Option("Section 1.1",
"chapter1.html#1.1");
Selector2.options[2]=new Option("Section 1.2",
"chapter1.html#1.2");
Selector2.options[3]=new Option("Section 1.3",
"chapter1.html#1.3");
break;

....

case 99: // Chapter 99 - Stockists
Selector2.options[0]=new Option("Chapter 99 - Stockists",
"stockists.html");
Selector2.options[1]=new Option("USA - Arizona",
"stockists.html#USA-AZ");
Selector2.options[2]=new Option("USA - California",
"stockists.html#USA-CA");
Selector2.options[3]=new Option("USA - Colorado",
"stockists.html#USA-CO");
Selector2.options[4]=new Option("USA - Texas",
"stockists.html#USA-TX");
Selector2.options[5]=new Option("Belgium", "stockists.html#be");
Selector2.options[6]=new Option("France", "stockists.html#fr");
Selector2.options[7]=new Option("Germany", "stockists.html#de");
break;

default: // Unrecognised chapter.
alert("Chapter " + x + " is not available.");
Selector2.options[0]=new Option("Unknown", "unknown.html");
break;
}
Selector2.options[0].selected=true;
return true;
}
</script>

This works fine, and for chapter 99 it creates an options list like this:
<option selected value="stockists.html">Chapter 99 - Stockists</option>
<option value="stockists.html#USA-AZ">USA - Arizona</option>
<option value="stockists.html#USA-CA">USA - California</option>
<option value="stockists.html#USA-CO">USA - Colorado</option>
<option value="stockists.html#USA-TX">USA - Texas</option>
<option value="stockists.html#be">Belgium</option>
<option value="stockists.html#fr">France</option>
<option value="stockists.html#ge">Germany</option>

But as the list has grown, I want to group the items, like this:

<option selected value="stockists.html">Chapter 99 - Stockists</option>
<optgroup label="USA">
<option value="stockists.html#USA-AZ">Arizona</option>
<option value="stockists.html#USA-CA">California</option>
<option value="stockists.html#USA-CO">Colorado</option>
<option value="stockists.html#USA-TX">Texas</option>
</optgroup>
<optgroup label="Europe">
<option value="stockists.html#be">Belgium</option>
<option value="stockists.html#fr">France</option>
<option value="stockists.html#ge">Germany</option>
</optgroup>

Does anyone know how I can do this dynamically (client-side) ?
 
T

Thomas 'PointedEars' Lahn

cedawe said:
I have two select boxes. When the user picks a value in the first one it
completely re-populates the second one. It works fine, but only generates a
standard OPTIONS list and I now want to group the options using OPTGROUPs.
[...]
Does anyone know how I can do this dynamically (client-side) ?

Using the W3C-DOM, it should be easy:

// create new option group
var oGroup = document.createElement('optgroup');
oGroup.value = "...";

// create new option (maybe you can/must use the Option(...) constructor)
var oOption = document.createElement('option');
oOption.value = "...";
oOption.text = "...";
...

// append the option to the option group
oGroup.appendChild(oOption);

// get a reference to the `select' element
var oSelect = document.forms[...].elements[...];

// append the option group
oSelect.appendChild(oGroup);

Untested, HTH.


PointedEars
 
G

Grant Wagner

mscir said:
A. Nonymous said:
I realize this is 6 months after the fact but...
This should read as
var oGroup = document.createElement('OPTGROUP');
oGroup.label = "..."; <===== Use ".label"
var oOption = document.createElement('OPTION');
oOption.value = "...";
oOption.innerText = "..."; <==== Use ".innerText"
oGroup.appendChild(blah!);
oSelect.appendChile(blah!);
...blah, blah!
I have only verified this behaviour on IE6.
Did anyone verify on Opera or NN?

My Netscape 7.1 didn't like innerText, but it does like innerHTML, if
you change that line it works on my IE6, Netscape 7.1, Firefox 0.8.
Here's how I tested it:

<script type="text/javascript">
function populate() {
// create new option group
var oGroup = document.createElement('optgroup');
// get reference to the `select' element
var oSelect = document.getElementById('select1');
//document.forms['form1'].elements['select1'];
oGroup.label = 'group1';
for (var i=0; i<5; i++) {
// create new options
var oOption = document.createElement('option');
oOption.value = 'b'+i;
oOption.innerHTML = 'b'+i;

oOption.appendChild(document.createTextNode('b'+i));

In cases like these, where the content is not too complicated (and not likely to
become complicated), I prefer document.createTextNode() to setting .innerHTML.
Any standards compliant browser that understands document.createElement() is
more likely to understand document.createTextNode() then .innerHTML. Making this
minor change removes any dependancy on proprietary attributes from your script.

That said, if I'm attempting to display extremely complicated, dynamically
created content, I typically use .innerHTML since it is such a huge pain to
construct complicated HTML using the standard methods. It also lets me write
code that can usually work on Netscape 4, since the same string can be output
using document.write().
// append the option to the option group
oGroup.appendChild(oOption);
// append the option group
oSelect.appendChild(oGroup);
}
}
function show(oSelect,oSelectIndex){
alert('You selected '+oSelect[oSelectIndex].value);
}
</script>

<form name="form1" id="form1">
<select name="select1" id="select1" onclick="show(this,this.selectedIndex)">
<option value='a0'>a0</option>
<option value='a1'>a1</option>
<option value='a2'>a2</option>
<option value='a3'>a3</option>
<option value='a4'>a4</option>
</select>
<p>
<input type="button" onclick="populate()" value="Add Select Options">
</form>

Mike

--
| Grant Wagner <[email protected]>

* Client-side Javascript and Netscape 4 DOM Reference available at:
*
http://devedge.netscape.com/library/manuals/2000/javascript/1.3/reference/frames.html

* Internet Explorer DOM Reference available at:
*
http://msdn.microsoft.com/workshop/author/dhtml/reference/dhtml_reference_entry.asp

* Netscape 6/7 DOM Reference available at:
* http://www.mozilla.org/docs/dom/domref/
* Tips for upgrading JavaScript for Netscape 7 / Mozilla
* http://www.mozilla.org/docs/web-developer/upgrade_2.html
 
T

Thomas 'PointedEars' Lahn

A. Nonymous said:
This should read as

var oGroup = document.createElement('OPTGROUP');
oGroup.label = "..."; <===== Use ".label"

Correct.

<http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-38450247>
and ...

var oOption = document.createElement('OPTION');
oOption.value = "...";
oOption.innerText = "..."; <==== Use ".innerText"

No, the proper property identifier as defined in DOM Level 0 (IE3+, NN3+) is
indeed "text". "innerText" is possible in IE, but in no way cross-browser.

<http://devedge.netscape.com/library/manuals/2000/javascript/1.3/reference/option.html>

Please do not top-post, see the FAQ.


PointedEars
 

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,995
Messages
2,570,228
Members
46,817
Latest member
AdalbertoT

Latest Threads

Top