PDA

View Full Version : changing select boxes



Spudhead
Jun 19th, 2002, 04:11 PM
Sorry, my Javascript is a bit rusty. This is all ASP-driven so I may have to go into more detail later, but for now:

I've got an array containing names of select boxes:


employeeFields[0]="FirstName";
employeeFields[1]="Surname";

I populate these select boxes from a database:


<select name="FirstName" onChange="updateEmployeeFields(this.options[this.selectedIndex].value)">
<option value="25">Bill</option>
</select>

<select name="Surname" onChange="updateEmployeeFields(this.options[this.selectedIndex].value)">
<option value="25">Gates</option>
</select>

the "25" in this example is the database ID field.

When a user chooses, say, a first name, I want any other select boxes on the page that are populated from the same database data to change to reflect that. If I select "Bill" in the FirstName, I want the Surname to change to "Gates". It shouldn't be too hard because their index values are both gonna be 25.

Here's the function I call onChange:


function updateEmployeeFields(whichIndex){
for(i=0;i<employeeFields.length;i++){
eval("document.form1."+employeeFields[i]+".selectedIndex="+whichIndex);
}
}

which - should - loop through all the relevant select box names and make their selectedIndex whatever was sent to it in "whichIndex". Right?

All it does is sets all the relevant select boxes - those in my array - to blank, and I'm not sure why. Any suggestions?

Cheers.

mordred
Jun 19th, 2002, 04:46 PM
You have to manipulate the options, not the <select> element itself. For instance, you have selectedIndex is a property of the options array. That's why you should change your function call to

onChange="updateEmployeeFields(this.options[this.[b]options.[]selectedIndex].value)"

So now you've got the value of the currently selected option. And that value is not necessarily the index of the options array! To set another select list to the option that corresponds to the select option in the firs list, try sth. like



function updateEmployeeFields(whichValue){
for(i=0;i<employeeFields.length;i++){

inner: for (var j = 0; j < document.form1.elements[employeeFields[i]].options.length; j++) {
if (document.form1.elements[employeeFields[i]].options[j].value == whichValue) {
document.form1.elements[employeeFields[i]].options[j].selected = true;
break inner;
}
}

}
}


All out of my hand and from scratch, might need a little bit polishing, but the concept should be clear (I hope) :)

Spudhead
Jun 19th, 2002, 05:46 PM
Yes, I think it is a little clearer, thanks - I'll give it a shot this evening. Except one thing: "inner". I've never seen that before, and I've only used "break" in switch statements. What does "inner" do?

(BTW I've plugged it in and it does the job beautifully :) Nice one.)

jkd
Jun 19th, 2002, 07:35 PM
break inner;

"Breaks" the statement labelled inner.

Javascript supports labels, though I rarely see them used. He labelled his for loop inner, and explicitly breaks it - it may help understanding exactly what the code does better, but I usually figure not labelling the loop, and just calling "break" is obvious enough. :)

mordred
Jun 19th, 2002, 07:45 PM
"inner" was just a useless feature I had implemented. It is an identifier that gives the inner for loop the, uhm, label "inner". When using break or continue statements, you can explicitly define which loop structure you want to manipulate:

http://devedge.netscape.com/docs/manuals/js/core/jsref15/stmt.html#1018088

Well, why did I use it all? It works perfectly alright when you drop it, because the break statement defaults to the nearest loop you're in at that moment. That was not clear to me while writing my reply, so I thought I'd add to be sure it should work.
However, if I'd wanted to stop the execution of the outer loop, I'd have to resort to labels or mangle with flag variables or the loop variable.

"break" can be used in any loop structure to terminate it's execution. That's why I used it actually, think you have an options array that is 237 elements long. Now if the iterating function finds the value "25" on third place, why traverse that whole thing any longer? So basically, the "break" should enhance performance. Though for smaller lists and on fast computers the time gain should neglectible.

TrueLies
Jun 19th, 2002, 08:27 PM
Hi

yes labels are fine, and not unsual.
Maybe we can add to the thread that normally we label the outmost loop in case we have a set of *nested* loops: if one of the nested loops meets a condition which is conclusive, you may want to stop not just this latest loop but also (maybe arguably all) the loops up in the cahin that were nesting it.
By labeling a loop higher in the ladder by sintax name+column+loop

aLabelName:
for(...
for(...
for(...

you can instruct form the second or third loop to conclude ALL the loops. This just avoid that, by breaking (break+optionalLableName) a nested loop after mert the eventual condition, the outer loops might go on for a few seconds looping objects that would not actually need be looped any longer. That was the deal!

ciao