Forum Moderators: open

Message Too Old, No Replies

dynamic drop down and change hidden value

         

proper_bo

12:57 pm on Jul 17, 2005 (gmt 0)

10+ Year Member



I have had a look around and can't find anything close to what I need. As a javascript beginner I don't have the first clue about how to write the functions either so I was after a little help.

I need the following layout of form:

Dropdown menu that has options.
Each option changes the options avaiable in the second dropdown menu and also changes two hidden form values.

So the top dropdown has say

pink
blue

the next has

mandy
sindy
claire

for pink
and

matt
john
bob

for blue

and the hidden values change to
name=gender value=male
name=skirt value=no
for blue
and
name=gender value=female
name=skirt value=yes
for pink

the stuff is all made up for an example.

Clear as mud?
Good. I'll be gratefull for all help.

ORBiTrus

3:32 pm on Jul 17, 2005 (gmt 0)

10+ Year Member



First you need a data structure.

Say,
Struct Options {
String[] list
Options[] subOptions
}

Then you write code using OOP to do it!

Now THAT is clear as mud.

If you want to see some of the ideas, read my replies to webstylers post about selects. It's discussion 4030.

Now as for code, maybe I'll write some later (8-9 hours later). But feel free to experiment with that discussion... there's alot of code there regarding this subject.

proper_bo

6:32 pm on Jul 17, 2005 (gmt 0)

10+ Year Member



I had a good read through that thread and although I get some of it, most goes straight over my head.
I can write what I want in simple terms but don't know how to change it into javascript.

if select(1) = option(1)
select(2) show option(3), option(4) and option(5)
hiddenvalue(1) show value(1)
hiddenvalue(2) show value(2)

elseif select(1) = option(2)
select(2) show option(6), option(7) and option(8)
hiddenvalue(1) show value(3)
hiddenvalue(2) show value(4)

Thanks.

ORBiTrus

7:33 pm on Jul 17, 2005 (gmt 0)

10+ Year Member



/**
* Class Options
*/
function Options () {
this.name = Array();
this.suboptions = Array();

this.add = function (name, suboptions) {
this.name[this.name.length] = name;
this.suboptions[this.suboptions.length] = suboptions;
}
this.get = function (index) {
return Array(this.name[index], this.suboptions[index]);
}
this.getRecurs = funcion (indexes, offset) {
if (indexes.length == 0)
return this;

var retVal = null;
if (offset == null)
offset = 0;
var index = indexes[offset];
if (index!= null) {
var o = this.suboptions[index];
if (offset == indexes.length -1)
retVal = o;
else
retVal = o.getRecurs(indexes, offset+1);
}
return retVal;
}
this.size = function () {
return this.name.length;
}
}

/**
* Class SelectLister
*/
function SelectList (options) {
this.selects = Array();
this.options = options;

this.register = function (elm, num) {
this.selects[num] = elm;
}
this.build = function (index) {
var select = this.selects[index];
select.innerHTML = ""; // clean it up...

// Find chosen indices
var chosen = Array();
for (var i=0; i<index; i++)
chosen[chosen.length] = this.selects[i].selectedIndex;

// Show options...
var options = this.options.getRecurs(chosen, 0);
if (options!= null) {
var l = options.size();
for (var i=0; i<l; i++) {
var o = document.createElement("option");
o.innerHTML = options.name[i];
select.insertBefore(o, null);
}
}
}
}

var options, temp;
options = new Options();

temp = new Options();
temp.add("Mandy",null);
temp.add("Sindy",null);
temp.add("Clair",null);
options.add("Pink", temp);

var selectList = new SelectList(options);

and then having:

HTML:

<select id='a' onchange='change(1)>
</select>

<select id='b' onchange='change(2)>
</select>

JS:
selectList.register(document.getElementById('a'));
selectList.register(document.getElementById('b'));
selectList.build(0); // build first select

function change (depth) {
selectList.build(depth);

// Hidden field manipulation code goes here, as there
// is no simple OOP approach to extend the above, and
// I don't feel like writing a complicated one, and
// the above should be enough for you to try your hand
// at it.

// Note: the reason OOP is difficult here, is that you
// have Many fields to correspond to One select.
// Hard to code.

var hiddenA = document.getElementById('hiddenFieldId');
var hiddenB = document.getElementById('hiddenFieldId');
if (selectList.selects[0].selectedIndex == 0) {
hiddenA.value = 'value for option 1';
hiddenB.value = 'value for option 1';
} elseif (selectList.selects[1].selectedIndex == 1) {
hiddenA.value = 'value for option 2';
hiddenB.value = 'value for option 2';
}
}

proper_bo

8:43 pm on Jul 17, 2005 (gmt 0)

10+ Year Member



Thank you for your hard work.

I tried it but I was getting several errors.

A couple being small typo's and the rest being caused by me obviously not having a clue what I'm doing with the code.

ORBiTrus

8:51 pm on Jul 17, 2005 (gmt 0)

10+ Year Member



Well, I typed it in this textarea here, so no surprise.

I'll provide an html file soon enough... unless someone else wants to bugfix and integrate? Heh.

proper_bo

8:56 pm on Jul 17, 2005 (gmt 0)

10+ Year Member



it's main error is with the

select.innerHTML = "";

I will be forever gratefull.
Thank you for the time your spending on this.

ORBiTrus

9:03 pm on Jul 17, 2005 (gmt 0)

10+ Year Member



WRT that one, no surprise.

if you replace the innerHTML = "" with:

while (select.options.length > 0)
select.removeChild(select.options[0]);

it should have the same effect.

I'll test it out soon. Company coming over, and I'm doing work on a sunday. Whatever will the pastor say...

proper_bo

9:19 pm on Jul 17, 2005 (gmt 0)

10+ Year Member



Ha, I look forward to it.

ORBiTrus

10:46 pm on Jul 17, 2005 (gmt 0)

10+ Year Member



OK, here we go:

<script type='text/javascript'>
/**
* Class Options
*/
function Options () {
this.name = Array();
this.suboptions = Array();

this.add = function (name, suboptions) {
this.name[this.name.length] = name;
this.suboptions[this.suboptions.length] = suboptions;
}
this.get = function (index) {
return Array(this.name[index], this.suboptions[index]);
}
this.getRecurs = function (indexes, offset) {
if (indexes.length == 0)
return this;

var retVal = null;
if (offset == null)
offset = 0;
var index = indexes[offset];
if (index!= null) {
var o = this.suboptions[index];
if (offset == indexes.length -1)
retVal = o;
else
retVal = o.getRecurs(indexes, offset+1);
}
return retVal;
}
this.size = function () {
return this.name.length;
}
}

/**
* Class SelectLister
*/
function SelectList (options) {
this.selects = Array();
this.options = options;

this.register = function (elm, num) {
if (num == null)
num = this.selects.length;
this.selects[num] = elm;
}
this.build = function (index) {
var select = this.selects[index];
select.innerHTML = ""; // clean it up...

// Find chosen indices
var chosen = Array();
for (var i=0; i<index; i++)
chosen[chosen.length] = this.selects[i].selectedIndex;

// Show options...
var options = this.options.getRecurs(chosen, 0);
if (options!= null) {
var l = options.size();
for (var i=0; i<l; i++) {
var o = document.createElement("option");
o.innerHTML = options.name[i];
select.insertBefore(o, null);
}
}
}
}

var options, temp;
options = new Options();
options.add("---", null);

temp = new Options();
temp.add("---",null);
temp.add("Mandy",null);
temp.add("Sindy",null);
temp.add("Clair",null);
temp.add("Sandy Style",null);
options.add("Pink", temp);

temp = new Options();
temp.add("---",null);
temp.add("Jim",null);
temp.add("John",null);
temp.add("Jack",null);
options.add("Blue", temp);

var selectList = new SelectList(options);
</script>

<select id='selectA' onchange='change(1)'>
<option>---</option>
</select>

<select id='selectB' onchange='change(null)'>
<option>---</option>
</select>

<form>
Sex: <input name='sex' id='hiddenA' /><br />
Skirt: <input name='skirt' id='hiddenB' />
</form>

<script type='text/javascript'>
selectList.register(document.getElementById('selectA'));
selectList.register(document.getElementById('selectB'));
selectList.build(0); // build first select

function change (depth) {
if (depth)
selectList.build(depth);

// Hidden field manipulation code goes here, as there
// is no simple OOP approach to extend the above, and
// I don't feel like writing a complicated one, and
// the above should be enough for you to try your hand
// at it.

// Note: the reason OOP is difficult here, is that you
// have Many fields to correspond to One select.
// ... Hard to code.

var hiddenA = document.getElementById('hiddenA');
var hiddenB = document.getElementById('hiddenB');

switch (selectList.selects[0].selectedIndex) {
case 0:
hiddenA.value = '';
hiddenB.value = '';
break;
case 1:
if (selectList.selects[1].selectedIndex == 4) {
hiddenA.value = 'Yes please';
hiddenB.value = 'Hopefully none';
} else {
hiddenA.value = 'Sure, why not?';
hiddenB.value = 'Mini';
}
break;
case 2:
hiddenA.value = 'Nah, no thanks';
hiddenB.value = 'Kilt';
break;
default:
alert ("?");
}
}
</script>

proper_bo

7:42 am on Jul 18, 2005 (gmt 0)

10+ Year Member



Works perfectly. Thank you.

proper_bo

9:59 am on Jul 18, 2005 (gmt 0)

10+ Year Member



I have one further challenge if it is possible.

When the second drop down menu is changed I need the form to change like so:

<select name="aloEXAMPLE2"> //the alo is important
<option>EXAMPLE1</option>
<option>EXAMPLE2</option> (selected)
<option>EXAMPLE3</option>
</select>

So the select name="" changes to the same as the option selected.

Is this complicated? If so then I'll think of another way around it.

ORBiTrus

12:24 pm on Jul 18, 2005 (gmt 0)

10+ Year Member



Perhaps?

the change function would need to be modifies to always be called, and be called with the value of the CURRENT select (right now it's called with the value of the next).

insert this into change(depth) function, at the top (

var name = "alo" + selectList.selects[depth].options[selectList.selects[depth].selectedIndex];
selectList.selects[depth].name = name;
selectList.selects[depth].setAttribute('name', name);

)

modify the onchange="change(1)" on the first select to onchange="change(0)"
and the onchange="change(null)" on the second select to onchange="change(1)"

and then modify the change function from:

if (depth!= null)
selectList.build(depth);

to:

if (depth < selectList.selects.length-1)
selectList.build(depth+1);

_____

But I'm not sure. I've never had need to change a name, and given the way old Javascript stuff used the name attribute as such a be-all and end-all of element reference, I don't know how it would like it.

If it doesn't work, just remove the first addition, the rest can stay as is (and work nicely).

Good Luck!

proper_bo

1:20 pm on Jul 18, 2005 (gmt 0)

10+ Year Member



Thats great thanks.

I'm going to use a work around for this form by going via a middle page and using a bit of php to change a few things before a confirm button is clicked to do the search.

Thank you for all your help.

You are a javascript king.