Forum Moderators: open

Message Too Old, No Replies

Clever Dropdown Redirect Needs A Twist

help make this great code snippet better, please!

         

ssling

10:19 am on Jun 9, 2007 (gmt 0)

10+ Year Member



hi there,

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;

Dabrowski

11:11 am on Jun 9, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



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.

ssling

10:00 am on Jun 10, 2007 (gmt 0)

10+ Year Member



Dabrowski-sensei, thanks very much for your solution above. your code works perfectly so mission accomplished.

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!

Dabrowski

11:51 am on Jun 11, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



ok, no problem, but we can't use the object refence anymore, so the first thing we'll do is take that out of the event listeners:

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.

colandy

2:58 pm on Jun 11, 2007 (gmt 0)

10+ Year Member



Just a quick spanner as to the functionality you are trying to accomplish.

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).

Dabrowski

5:22 pm on Jun 11, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hmmmm....nice spanner! ;)

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.

ssling

3:23 pm on Jun 12, 2007 (gmt 0)

10+ Year Member



hi guys,

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;

or at least the other js on my page does not function when it is present, and does function when it is commented out.

anyhow, i will have another go at this tomorrow and report back if i can get it to work... sorry, patience with the novice...

Dabrowski

4:57 pm on Jun 12, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



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.

ssling

12:38 pm on Jun 14, 2007 (gmt 0)

10+ Year Member



hi there.

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?

bcolflesh

12:45 pm on Jun 14, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



is there somthing like the w3c validator out there for javascript?

[jslint.com...]

Dabrowski

1:55 pm on Jun 14, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



ooo, new one on me.

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

f2Idx
and
f2
point 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.

colandy

2:20 pm on Jun 14, 2007 (gmt 0)

10+ Year Member



OK, I've just written some JS that works with 2 select boxes, if this is what your looking for then great, if not ........ buy a new keyboard.

<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>

colandy

2:22 pm on Jun 14, 2007 (gmt 0)

10+ Year Member



That was a nice piece of dirty coding, a switch inside a switch....hmmmmm

Dabrowski

5:06 pm on Jun 14, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Not to mention the interesting JavaScript comments?

ssling

11:04 am on Jun 16, 2007 (gmt 0)

10+ Year Member



hi there,

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..

Dabrowski

12:37 pm on Jun 16, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



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,

func1
would execute only
if( thing)
, but [fixdd]func2[/fixed] would execute all the time.

if( thing) {
func1;
func2;
...
}

In this example,

func1
and
func2
would 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
if
sections - 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!

Dabrowski

1:24 pm on Jun 16, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I guess you all are probobaly getting bored with me by now

I don't get bored of coding...I participate on this forum because I enjoy it!

colandy

3:34 pm on Jun 16, 2007 (gmt 0)

10+ Year Member



And I thought u participated because u wanted to help others.....Now I'm disappointed...

:)

Personally I only help cos I'm hoping someone will pay me commission.

Still Waiting

colandy

4:17 pm on Jun 16, 2007 (gmt 0)

10+ Year Member



Javascript Page Redirection:

window.location="page.html";

Using my original script, put quotes around the numbers:

case 1:

should be case '1':

Although I suspect tha Dabrowski's code will work once u use window.location="page.html";

Dabrowski

5:28 pm on Jun 16, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



And I thought u participated because u wanted to help others.....Now I'm disappointed...

Lol! People only ever help themselves, there's no such thing as a self-less act!

Actually I enjoy some of the challenges posed by users, I've written a lot of unique code, it's a learning experience for me too.

ssling

5:20 pm on Jun 18, 2007 (gmt 0)

10+ Year Member



hi there,

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(); };
}

Dabrowski

6:09 pm on Jun 18, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



ok, I think I see it:

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.