...

View Full Version : Dependent drop-down with selections in an array



Wyrdathru
09-12-2011, 04:11 PM
Hullo again, CF.com,

So, now I have a curious question on arrays, selections, options and the like. My current project is available for perusal in order to assist me at:

http://www.projectvoid.co.uk/

As you can see, I make it so that once the product type is selected, you can then select a wattage. This dependent drop-down works, however I want it so that when I select a value in the left-hand side (wattage), then the one on the right will offer a pre-defined value that replaces the wattage I have.

For example, a GU-10 in 'Type of Lamp' offers a 50, 35 and 20 watt bulb in 'Current Lighting Products'. In 'Energy Efficient Products', it offers 5 and 3. I wish to make a statement somewhere so that if they select 50 on the left, it selects 5 on the right. If they select 35 on the left, it select 3 on the right.

I would also like it to do multiple offers, so that if they select say, a 35 of the MR-16, I want the right hand side to offer both 5 and 3.

The only way I can think of doing this is via a lot of 'IF' statements. Is there a quicker way to do this?

Please assist and, if it's not too much to ask, could you comment the code?

Thank you!

Old Pedant
09-12-2011, 08:38 PM
Couldn't reach your URL.

If you can't make it public, then post a bit of code instead.

Wyrdathru
09-13-2011, 05:53 PM
Hey there,

The URL seems to work fine, though I went ahead and chmod'd it up so you should get in with no worries.

Thanks!

Old Pedant
09-13-2011, 09:08 PM
Okay, makes sense. Will try to get back with an idea or two later. Busy today.

Wyrdathru
09-15-2011, 01:30 PM
Cheers, I look forward to your assistance!

Old Pedant
09-17-2011, 05:42 AM
I wish to make a statement somewhere so that if they select 50 on the left, it selects 5 on the right. If they select 35 on the left, it select 3 on the right. Okay, this is easy.

But....

if they select say, a 35 of the MR-16, I want the right hand side to offer both 5 and 3.
So how am I supposed to know which left-side values get only one selection on the right (at which point it's no longer really a selection, so why even show it as a dropdown??) vs. those that have 2 or more choices?

Are you going to supply a table of correspondences?

If so, it's pretty easy.

The table would look something like this:


var correspondences = {
"MR16" : { 50 : 5, 35 : [3,5], 20 : 3 },
"Candle" : { 40 : 4, 25 : 3, 20: 2.2 },
...
};

You see it? An object is indexed by the names.
And then each name is related to another object, which is indexed by the left side wattage. The value for each left side wattage is related to either a single value (50 matches 5) or an array for multiple values (35 matches 3 and 5).

You create that set of correspondences for me and I'll write the code.

Old Pedant
09-18-2011, 09:58 PM
Here. Decided not to wait for you.

Is this what you are after? (Abbreviated version of your <form>s shown, of course.)


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>CREED Energy LTD - Lighting Efficiency Calculator</title>
<script type="text/javascript">
var lamps = {
"MR16" : { 50 : 5, 35 : [3,5], 20 : 3 },
"Candle" : { 40 : 4, 25 : 3, 20: 2.2 },
"Panel" : { 180: 72, 100: [72,36] , 80: 36 }
};

function addLamps(toWhat)
{
for ( var name in lamps )
{
var foo = lamps[name];
toWhat.options[toWhat.options.length] = new Option(name,name);
}
}

function initialize( )
{
addLamps(document.left.product_type);
// addLamps(document.right.product_type);
}

function changeProduct()
{
var fleft = document.left;
var fright = document.right;
fleft.wattage.options.length = 0;
fright.wattage.options.length = 0;

if ( fleft.product_type.selectedIndex == 0 )
{
fright.product_type.value = "";
return;
}
var ptype = fleft.product_type.value;
fright.product_type.value = ptype;
var lamp = lamps[ptype];
fleft.wattage.options[0] = new Option("Select Wattage","");
for ( var w in lamp )
{
fleft.wattage.options[fleft.wattage.options.length] =
new Option( w, w );
}
}

function changeWattage()
{
var fleft = document.left;
var fright = document.right;
fright.wattage.options.length = 0;
if ( fleft.wattage.selectedIndex == 0 ) return;

var ptype = fleft.product_type.value;
var wleft = fleft.wattage.value;
var lamp = lamps[ptype];
var watts = lamp[wleft];
if ( watts.length )
{
fright.wattage.options[0] = new Option("Select Wattage","");
for ( var w = 0; w < watts.length; ++w )
{
fright.wattage.options[fright.wattage.options.length] =
new Option( watts[w], watts[w] );
}
} else {
fright.wattage.options[0] = new Option(watts,watts);
}
}


window.onload = initialize;
</script>
</head>
<body>
<table width="70%" border="0.1" cellspacing="0" cellpadding="2">
<tr>
<td width="50%" align="right">
<!-- Form1 - Older Product Calculations-->
<div class="c3">
<h2>Current Lighting Products</h2>
<form name="left">
Type of Lamp:
<select name="product_type" onchange="changeProduct();">
<option value="">Select Product</option>
</select>
<br/>
Wattage of Lamp:
<select name="wattage" onchange="changeWattage();" style="width: 130px;">
<option value="">Select Wattage</option>
</select> <br />
</form> <br />
</div>
</td>
<td width="50%" align="right">
<!-- Form1 - Older Product Calculations-->
<div class="c3">
<h2>Current Lighting Products</h2>
<form name="right">
Type of Lamp:
<input name="product_type" readonly>
<br/>
Wattage of Lamp:
<select name="wattage" style="width: 130px;">
</select> <br />
</form> <br />
</div>
</td>
</tr>
</table>
</body>
</html>

Wyrdathru
09-18-2011, 10:08 PM
Hey, Old Pedant.

I was just working on that table you wanted, but I'll run through that code now and see.

Thank you very much!

(Not that you need it now, but this is how I made it!)



var correspondences =

{

"MR16" : { 50 : 5, 35 : [3,5], 20 : 3 },
"GU10" : { 50 : 5, 35 : [3,5], 20 : 3 },
"Candle" : { 40 : 4, 25 : 3, 20 : 2.2 },
"Globe" : { 60 : 6, 40 : 4, 14 : 4, 9 : 4 },
"E14" : { 60 : 5, 40 : 3 },
"PAR" : { 120 : 22, 60 : 12 },
"Pygmy" : { 10 : 0.9 },
"2D" : { 28 : 14, 16 : 5 },
"Linear Halogen" : { 150 : 13 },
"Floodlight" : { 1000 : 120, 500 : 90, 400 : 48, 300 : 30, [120,100] : 10 },
"PL" : { [18,13,11] : 4 },
"T8" : { 95 : 21, 65 : 18, 46 : 16, 20 : 8 },
"Panel" : { 180 : 72, [100,80] : 36 },
"High Bay" : { 400 : 100 },
"Streetlight" : { 400 : 124, 250 : 28 },
"Cone" : { 70 : 15 }

};

Old Pedant
09-18-2011, 10:15 PM
Only the "PL" and "Floodlight" and "Panel" won't work.

You can't have an array on the left side of the colon.

For example, PL will have to be entered as

"PL" : { 18 : 4, 13: 4, 11: 4 },

It's a limitation of the JSON notation.

Wyrdathru
09-18-2011, 10:30 PM
Only the "PL" and "Floodlight" and "Panel" won't work.

You can't have an array on the left side of the colon.

For example, PL will have to be entered as

"PL" : { 18 : 4, 13: 4, 11: 4 },

It's a limitation of the JSON notation.

Ah-hah, thank you.

I took a gander and didn't realize this wouldn't work - glad you caught it!

Now, see this?



function initialize( )
{
addLamps(document.left.product_type);
// addLamps(document.right.product_type);
}


Why is the second portion commented, not in effect?

I don't get that.

Cheers.

Old Pedant
09-18-2011, 10:58 PM
Oh, sorry... Because I decided that we wouldn't even show any <option>s in the right side until a selection has been made on the left. And also decided to show the right side product as just a text box.

Both those decisions can be changed. If they need to be, then we likely would want to initialize the right side <select name="product_type">. But for now, it's not needed.

Wyrdathru
09-19-2011, 12:03 AM
I managed to get it all working with my other code, now I am going through and dissecting how it actually works.

Would you mind further questions about it being brought up and asked in here, Old Pedant? I can understand if not!

Thank you very much for all your assistance. It's a great help.

Old Pedant
09-19-2011, 12:44 AM
Ask away!

But PM is okay if you don't want to discuss something secret here.

Wyrdathru
09-21-2011, 11:35 AM
Hello again!

First off, thank you once again for your assistance - it is greatly appreciated.

As usual, the code is available to view at:
http://www.projectvoid.co.uk

Now, I've adopted your code so it fits in with mine and works after some trial and error.

I'm fairly new to JavaScript so you'll have to forgive my newbie questions. I'll even go a piece at a time in case you need to pimp-slap me into seeing sense.

So... this bit!



function addLamps(toWhat)
{
for ( var name in lamps )
{
var foo = lamps[name];
toWhat.options[toWhat.options.length] = new Option(name,name);
}
}


This creates a function that is used later in code. From what I can tell, it uses a for in statement, right?

So it's looping through the object array we created earlier, 'lamps'. [name] is therefore the name of the product, either "MR16", "GU10" or whatever, correct?

So what is... this:


toWhat.options[toWhat.options.length] = new Option(name,name);


I understand that toWhat is the location passed through the functions that are called later on, so it is a path name. The last bit is what confuses me.

The length property gives a number of how many named variables there are in the array object? So for us, there are sixteen.

Does that just mean it's creating sixteen different options?

Why would the code not look like this instead?



function addLamps(toWhat)
{
for ( var name in lamps )
{
var foo = lamps[name];
toWhat.options.length = new Option(name,name);
}
}


Cheers.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum