Forum Moderators: open
i was hoping one of the javascript expert's could help me out with this... i have a form on my page with a drop-down selection which redirects the user to anther page if they make a certain selection. well, i would like to add a second field on the same form which does the same thing, assuming the user makes it that far along.
the problem is, i have a very clever js solution (which was given to me) and i cannot figure out how to modify it to work for more than one field. below is the code in my external.js file which performs this task.
to be clear: what i am trying to do is include another field, say "field_2" to this code, and then add various cases of "selection_c", "selection_d" and so on.
btw, this code is very useful for anyone trying to redirect users based on dropdown selections... please try it out!
<!--This code allows different select options to send to different pages-->
function selectCallback(s)
{
// This function gets called when selection changes
if( s.selectedIndex == -1 ) return;
var v = s.options[s.selectedIndex].value;
switch(v) {
case 'selection_a':
// Go to page A
document.location.href='http://www.myurl.com/a.html';
alert('you will now be redirected to page a ');
break;
case 'selection_b':
document.location.href='http://www.myurl.com/b.html';
alert('you will now be redirected to page b ');
break;
default:
// Do nothing for other selections
break;
}
}
function attachBehaviors()
{
// Attach event handler to your select object
var s = document.getElementById("field_1");
if( s )
{
s.onchange = function(){selectCallback(s);};
}
}
window.onload = attachBehaviors;
i have a very clever js solution
It's not that clever really, simple stuff. Actually you might want to bring your event listeners up to date, we done use onchange= onload= any more.
Anyway, that aside, try this. First we'll modify your init function to add a listener for the second field.
function attachBehaviors()
{
// Attach event handler to your select object
var f1 = document.getElementById("field_1");
if( f1 ) f1.onchange = function(){selectCallback( f1);};var f2 = document.getElementById("field_2");
if( f2 ) f2.onchange = function(){selectCallback( f2);};
}
Now, we simply add more values into your callback function.
function selectCallback(s)
{
// This function gets called when selection changes
if( s.selectedIndex == -1 ) return;
var v = s.options[s.selectedIndex].value;switch(v) {
case 'selection_a':
// Go to page A
document.location.href='http://www.myurl.com/a.html';
alert('you will now be redirected to page a ');
break;case 'selection_b':
document.location.href='http://www.myurl.com/b.html';
alert('you will now be redirected to page b ');
break;case 'selection_y':
document.location.href='http://www.myurl.com/y.html';
alert('you will now be redirected to page y ');
break;case 'selection_z':
document.location.href='http://www.myurl.com/z.html';
alert('you will now be redirected to page z ');
break;default:
// Do nothing for other selections
break;
}
}
The drawbacks of this is that every <option> in both lists needs a unique value as the callback function is combined. You might want to modify the function to check the value of field_1 and field_2 separately, you might want 2 different redirects for the same value in field_2, if field_1 is different.
Anyway, give that a go for now.
you also state
You might want to modify the function to check the value of field_1 and field_2 separately, you might want 2 different redirects for the same value in field_2, if field_1 is different.
actually that is exactly what i would like to do. for a given value in field_2, i would like to have two different redirects, depending on the value of field_1 would you be so kind as to indicate how this is done?
thanks very much!
function attachBehaviors()
{
// Attach event handler to your select object
var f1 = document.getElementById("field_1");
if( f1 ) f1.onchange = function(){ selectCallback(); };
var f2 = document.getElementById("field_2");
if( f2 ) f2.onchange = function(){ selectCallback(); };
}
Next, we need to change your callback function to look for both fields, and act accordingly. Note we've removed the 's' parameter.
function selectCallback() {
// This function gets called when selection changes
var f1Idx = document.yourformname.field_1.selectedIdx;
var f1 = document.yourformname.field_1.options[ idx].value;var f2Idx = document.yourformname.field_1.selectedIdx;
var f2 = document.yourformname.field_1.options[ idx].value;if(!f1 ¦¦!f2) return;
First we get the selectedIndex for each, then look up the value for each. Just in case I've stuck a failsafe in so the function aborts if it hasn't got either value.
Next, the part where you check the values, I prefer if/else over switch/case, but you can always change it if you like. There's a couple of ways of doing this, depending on how you want to compare the values it may be easier one way or the other.
Method 1, compare everything every time:
if( f1 == "foo" && f2 == "bar") {
// Something} else if( f1 == "stuff" && f2 == "nonsense") {
// Something} else {
// Default}
Method 2, compare f1 first:
if( f1 == "foo") {
if( f2 == "bar") {
// Something} else if( f2 == "yung") {
// Something} else {
// Default}
} else if( f1 == "stuff") {
if( f2 == "nonsense") {
// Something} else if( f2 == "items") {
// Something} else {
// Default}
} else {
// Default}
Method 3, compare f2 first, just switch f1 and f2 in method 2.
If every combination will redirect to other pages, use method 1.
If drop down 1 is set to 'a' and drop down 2 is set to 'x', but the user wants the page that is only viewable by selecting 'b' in drop down 1 and 'z' in drop down 2. How does he get there.
The only reason I ask is because as soon as any 1 of the drop downs is changed, the page will redirect..?!?!? Unless you make 'a'-'z' and 'b'-'x' non-redirectable(if thats a word).
To get round this the easy way, make an option with no value, at the top of each list, saying something like 'Select an Option...'.
Then the failsafe will come in handy, as nothing will happen until the user has chosen from both fields.
If that doesn't cut it then we'll have to make 2 handlers and I can tell it's going to get messy, so I hope that way is ok!
Let us know.
i'm kinda struggling with the latest insallment here... having trouble getting it to work so i'll give it another crack tomorrow with a fresh head.
in the meantime, i did notice two things:
1) in the first solution Dabrowski-sensei gives (in the second post of this thread), the behaviour works on ie and opera but not on firefox. this is with respect to the newly added field_2 the redirect still works with the original field_1 in this case.
2) in the second solution given by Dabrowski (fourth post of this thread) there seems to a problem with this code:
if(!f1 ¦¦!f2) return;
anyhow, i will have another go at this tomorrow and report back if i can get it to work... sorry, patience with the novice...
1) in the first solution Dabrowski-sensei gives (in the second post of this thread), the behaviour works on ie and opera but not on firefox. this is with respect to the newly added field_2 the redirect still works with the original field_1 in this case.
Why do you keep saying 'Dabrowski-sensei'?
Not using that code anymore, see the updated stuff. There is also a typo in there, spot the deliberate mistake:
var f2Idx = document.yourformname.field_1.selectedIdx;
var f2 = document.yourformname.field_1.options[ idx].value;
Did you see it?
2) in the second solution given by Dabrowski (fourth post of this thread) there seems to a problem with this code:if(!f1 ¦¦!f2) return;
The problem is actually with this website, the ¦ character is actually a single pipe, on a UK keyboard, SHIFT + \
They really should fix that.
sorry but i have to report continued forehead to keyboard bashing. i can't get this to work.
as for the deliberate mistake, i guess the space in [ idx]? what would really help me is some kind of javascript code validator, as this seems to be my biggest problem: not the logic (which you have provided), but the execution (not being an experienced programmer).
is there somthing like the w3c validator out there for javascript?
A decent code editor helps too, I use one called PSPad, it's freeware, and provides code syntax highlighting, bracket matching and that basic sort of stuff. Very handy.
The mistake was that
f2Idxand
f2point to field_1's values. That's what you get for copying & pasting!
The extra space character is just my style of coding, I just find it easier to read with a space after almost every bracket.
Did you change the ¦ character, what error(s) are you getting? Can you paste your whole JS back in here please.
<HTML>
<HEAD>
<TITLE>Test Page</TITLE>
<SCRIPT TYPE="text/javascript">
function test()
{
var fd1=document.getElementById('test1');
var fd2=document.getElementById('test2');
var val1=fd1.options[fd1.selectedIndex].value;
var val2=fd2.options[fd2.selectedIndex].value;
switch(val1)
{
case 1:
switch(val2)
{
case 1:
<!-- opt1 = 1 and opt 2 = 1 So do something wierd -->
break;
case 2:
<!-- opt1 = 1 and opt 2 = 2 So do something wierd -->
break;
case 3:
<!-- opt1 = 1 and opt 2 = 3 So do something wierd -->
break;
}
break;
case 2:
switch(val2)
{
case 1:
<!-- opt1 = 2 and opt 2 = 1 So do something wierd -->
break;
case 2:
<!-- opt1 = 2 and opt 2 = 2 So do something wierd -->
break;
case 3:
<!-- opt1 = 2 and opt 2 = 3 So do something wierd -->
break;
}
break;
}
}
</SCRIPT>
</HEAD>
<BODY>
<SELECT id="test1" name="test1" onChange="javascript:test();">
<option>Please Select One</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
<option value="4">Option 4</option>
</SELECT>
<br><br>
<SELECT id="test2" name="test2" onChange="javascript:test();">
<option>Please Select One</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
<option value="4">Option 4</option>
</SELECT>
</BODY>
</HTML>
well, going back to Dabrowski's code, i've had another long go at it and there still seems to be an error in this code below somewhere, but I can't find it.
function selectCallback() {
// This function gets called when selection changes
var f1Idx = document.formname.field_1.selectedIdx;
var f1 = document.formname.field_1.options[ idx].value;
var f2Idx = document.formname.field_2.selectedIdx;
var f2 = document.secured.field_2.options[ idx].value;
if(!f1 ¦¦!f2) return;
if( f1 == "A" && f2 == "X") {
// Something
document.location.href='http://www.myurl.com';
alert('You will now be redirected. ');
break;
} else if( f1 == "A" && f2 == "Y") {
// Something
document.location.href='http://www.myurl.com';
alert('You will now be redirected. ');
break;
} else {
// Default
break;
}
}
function attachBehaviors()
{
// Attach event handler to your select object
var f1 = document.getElementById("field_1");
if( f1 ) f1.onchange = function(){ selectCallback(); };
var f2 = document.getElementById("field_2");
if( f2 ) f2.onchange = function(){ selectCallback(); };
}
(btw, yes i have the correct ¦¦ characters in my file and the field names are arranged correctly)
I cannot seem to fix the errors given by the code verifier at www.jslint.com, which are as follows:
Error:
Problem at line 9 character 15: Expected '{' and instead saw 'return'.
if(!f1 ¦¦!f2) return;
Problem at line 32 character 10: Expected '{' and instead saw 'f1'.
if( f1 ) f1.onchange = function(){ selectCallback(); };
Problem at line 34 character 10: Expected '{' and instead saw 'f2'.
if( f2 ) f2.onchange = function(){ selectCallback(); };
BTW, I also had a full-on attempt with colandy's code as well, which didn't generate any errors, but also didn't seem to execute the redirect when the various cases were true.
I tried it by modifying the various bits in my actual form to conform to the "case 1" etc.. format but to no avail.
I also tried just cut / pasting the exact code as it appears above into a new file and uploading to my server with the following just below "...So do something wierd -->"
document.location.href='http://www.myurl.com';
alert('You will now be redirected. ');
I also tried doing exactly the above with php and html extensions (not sure if that makes any difference), and couldn't get it to work that way either
Anyhow, I guess you all are probobaly getting bored with me by now. If you see anything above I'm still obviously doing wrong, I would very much appreciate your comments. Otherwise I may just have to throw in the towel and outsource this one.. Thanks very much..
Problem at line 9 character 15: Expected '{' and instead saw 'return'.if(!f1 ¦¦!f2) return;
This is not an error. Nor are the other 2 occurances. If you don't use the {}'s, the next statement only is executed. See examples....
if( thing)
func1;
func2;
In this example,
func1would execute only
if( thing), but [fixdd]func2[/fixed] would execute all the time.
if( thing) {
func1;
func2;
...
}
In this example,
func1and
func2would execute only
if( thing)
if(!f1 ¦¦!f2) { return; }
Is exactly the same, and would make no difference. The code is correct both ways.
Aside from that I can't see anything really wrong, remove the
break;statements from the
ifsections - you don't need them. First because you're using if/else, which means only 1 can possibly execute anyway, and second because all expressions are different, means only 1 can match.
Your alert should be before your redirect line, in fact, there's the error! The location object is a child of window, not document.
Try this:
window.location.href = "www.myurl.com";
See how that goes!
okay, i've finally had a chance to work this out. i've managed to get colandy's code to work, but still not Dabrowski's.
colandy, your latest comment:
case 1:should be case '1':
did the trick and now the code works. it also enabled me to go back to my descriptive values, rather than numbers, which is more useful for me elsewhere. i also figured out how to tweak your switch within a switch to handle all combinations of redirects that i need. not least, now i know to handle switches!
Dabrowski, there still seems to be an error in the code pasted below. i'm basing this observation on the simple fact that when i remove this code, all the other javascript on my external.js file works, and when i put it back in, none of it works. for the life of me i don't know what the error is. must be some typo error on my part somewhere that just isn't showing up on this forum.
anyhow, i think i'm sorted now with colandy's code so i'm going to go with that. thanks very much to both of you! it took a while to get there but the effort was worth it to figure this one out.
/ssling
function selectCallback() {
// This function gets called when selection changes
var f1Idx = document.formname.field_1.selectedIdx;
var f1 = document.formname.field_1.options[ idx].value;
var f2Idx = document.formname.field_2.selectedIdx;
var f2 = document.formname.field_2.options[ idx].value;
if(!f1 ¦¦!f2) return;
if( f1 == "select1" && f2 == "select2") {
// Something
alert('You will now be redirected. ');
window.location.href='http://www.myurl.com';
} else if( f1 == "select1" && f2 == "select3") {
// Something
alert('You will now be redirected to our home page. ');
window.location.href='http://www.myurl.com';
} else {
// Default
break;
}
}
function attachBehaviors()
{
// Attach event handler to your select object
var f1 = document.getElementById("field_1");
if( f1 ) f1.onchange = function(){ selectCallback(); };
var f2 = document.getElementById("field_2");
if( f2 ) f2.onchange = function(){ selectCallback(); };
}
var f1Idx = document.formname.field_1.selectedIdx;
var f1 = document.formname.field_1.options[ idx].value;var f2Idx = document.formname.field_2.selectedIdx;
var f2 = document.formname.field_2.options[ idx].value;
Should be......
var f1Idx = document.formname.field_1.selectedIndex;
var f1 = document.formname.field_1.options[ f1Idx].value;var f2Idx = document.formname.field_2.selectedIndex;
var f2 = document.formname.field_2.options[ f2Idx].value;
Don't know what I was thinking. Still, glad you got it sorted.