JavaScript dropdown help

I am trying to make a dropdown list where, when the user clicks the option "more…"it takes them to a URL.

I am using a <select> list, it’s for an ecommerce site where the user is selecting the quantity. It goes up to ‘10’, then the last option is ‘More…’, which is supposed to take them to a product page.

I have googled and tried different things, and they all kinda work, but not how I want them to. What I’m currently using right now:

<select name="qty" id="qty" onchange="window.open(this.options[this.selectedIndex].value,'_top')" >
<option value="1" selected="selected">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
<option value="<?php echo $_product->getProductUrl() ?>">More...</option>
</select>

(note: this is all wrapped in <form> tags). What this does is go to the URL specified by ‘value=’. Except I only want it to go to a URL when ‘More…’ is selected. How could I accomplish this?

You can try:

form.qty.onchange = function() {
	if( this.options[this.selectedIndex].text === 'More...' ) {
		window.location = this.value;
	}
};

While what centered effect has posted is fine it’s using the old HTML 4.01 ECMA JavaScript standards which still a valid way to write the onchange event but shouldn’t be used with XHTML and HTML5, also at the moment the onchange event is static which means if you were to change your select list from saying More… to something like Need more then 10? you risk forgetting about the onchange event which would cause the script to stop working.

The below code i have posted will seek out the last index of the select options and compared it with the currently selected index, if they match it will then redirect you otherwise it will act as a normal select box:

<select name="qty" id="qty" onchange="redirect(this)">
    <!-- options here -->
</select>
function redirect(ele) {
    var options = ele.options,
        length  = ele.options.length,
        curIdx  = ele.selectedIndex;
    
    if (options[length - 1].index === curIdx) {
        window.location = 'somefile.php?qty=' + options[curIdx].value;
    }
}

You can also see the following jsFiddle for a demo http://jsfiddle.net/zMEDy/

The next step from here is to remove the inline event attribute from the HTML content, so that it can be placed with the scripting code instead as a part of the behavioral changes that occur.


<select name="qty" id="qty"[s][color="red"] onchange="redirect(this)"[/color][/s]>
    <!-- options here -->
</select>


...
document.getElementById('qty').onchange = redirect;

The next step is to listen for the keyup event as well. Here I removed the inline JavaScript and added John Resig’s addEvent listener function, and I am checking against non integers (parseInt):

Untested…

<form>
	<select name="qty" id="qty">
	    <option value="1" selected="selected">1</option>
	    <option value="2">2</option>
	    <option value="3">3</option>
	    <option value="4">4</option>
	    <option value="5">5</option>
	    <option value="6">6</option>
	    <option value="7">7</option>
	    <option value="8">8</option>
	    <option value="9">9</option>
	    <option value="10">10</option>
	    <option value="products.php?item=1234">Next Bundle....</option>
	</select>		
</form>

// http://ejohn.org/projects/flexible-javascript-events/
function addEvent( obj, type, fn ) {
	if ( obj.attachEvent ) {
		obj['e'+type+fn] = fn;
		obj[type+fn] = function(){
			obj['e'+type+fn]( window.event );
		};
		obj.attachEvent( 'on'+type, obj[type+fn] );
	} else
		obj.addEventListener( type, fn, false );
}	

function redirectBasedOnOption(el, fn) {
	addEvent( el, 'change', fn );
	addEvent( el, 'keyup', fn );	
}		

redirectBasedOnOption(
	document.getElementById('qty'),
	function() {
		var val = parseInt(this.value);
		if(isNaN(val)) {
			console.log(this.value);
			// window.location = this.value;	
		}
	}
);

Something you will find is that IE references the event object instead of copying it, resulting in the this keyword getting clobbered and referring to the window object instead.

Thanks for all your help guys. I ended up going with chris.upjohn’s solution and it works perfectly.