Avatar of hankknight
hankknightFlag for Canada

asked on 

jQuery: onchange for select replacement

I use a jQuery plugin to change the appearance of select/option drop downs.

How can I trigger an event when the value is changed?
<!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"> 
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<style type="text/css">

.jqtSelectWrapper {
	width: 150px;
	height: 31px;
	background: #F5F5F5 url(http://www.cs.umd.edu/hcil/counterpoint/download/tutorial/down_arrow.gif) no-repeat scroll 99% 4px;
	min-width: 200px;
	margin-right: 17px;
	border: 1px solid #aaa;
	cursor: pointer;

.jqtSelectWrapper div span {
	font-size: 12px;
	float: none;
	position: absolute;
	white-space: nowrap;
	height: 31px;
	line-height: 15px;
	padding: 8px 0 0 7px;
	overflow: hidden;
	width: 194px !important;

.jqtSelectWrapper ul {
	position: absolute;
	width: 43px;
	top: 30px;
	left: 0px;
	list-style: none;
	background-color: #FFF;
	border: solid 1px #CCC;
	display: none;
	margin: 0px;
	padding: 0px;
	height: 150px;
	overflow: auto;
	overflow-y: auto;

.jqtSelectWrapper ul a {
	display: block;
	padding: 5px;
	text-decoration: none;
	background-color: #FFF;
	font-size: 12px;

.jqtSelectWrapper ul a.selected {
	background: #EDEDED;
	color: #333;

.jqtSelectWrapper ul a:hover, .jqtSelectWrapper ul a.selected:hover {
	color: #fff;

.jqtHidden {display: none;}


<h1>I want to trigger an alert when the value has been changed for either of the items below.</h1>

<h2>This works:</h2>

<select name="s2">
<option value="">---Select---</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
<option value="4">Four</option>
<option value="5">Five</option>

<h2>This does NOT work:</h2>

<form action="/" method="post"> 
<select name="s1">
<option value="">---Select---</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
<option value="4">Four</option>
<option value="5">Five</option>

<h3>The problem is caused by the selection replacement plugin.</h3>

<script type="text/javascript">

	var jqtPreloadHoverFocusImg = function(strImgUrl) {
		strImgUrl = strImgUrl.replace(/^url\((.*)\)/,'$1').replace(/^\"(.*)\"$/,'$1');
		var imgHover = new Image();
		imgHover.src = strImgUrl.replace(/\.([a-zA-Z]*)$/,'-hover.$1');
		var imgFocus = new Image();
		imgFocus.src = strImgUrl.replace(/\.([a-zA-Z]*)$/,'-focus.$1');				

	var jqtGetLabel = function(objfield){
	/* Hide all open selects */
	var jqtHideSelect = function(oTarget){

	/* Add a new handler for the reset action */
	var jqtReset = function(f){
		var sel;
		$('.jqtSelectWrapper select', f).each(function(){sel = (this.selectedIndex<0) ? 0 : this.selectedIndex; $('ul', $(this).parent()).each(function(){$('a:eq('+ sel +')', this).click();});});

	$.fn.jqTransSelect = function(){
		return this.each(function(index){
			var $select = $(this);

			if($select.hasClass('jqtHidden')) {return;}
			if($select.attr('multiple')) {return;}

			var oLabel  =  jqtGetLabel($select);
			/* First thing we do is Wrap it */
			var $wrapper = $select
				.wrap('<div class="jqtSelectWrapper"></div>')
				.css({zIndex: 10-index})
			/* Now add the html for the select */
			$wrapper.prepend('<div><span></span><a href="#" class="jqtSelectOpen"></a></div><ul></ul>');
			var $ul = $('ul', $wrapper).css('width',$select.width()).hide();
			/* Now we add the options */
			$('option', this).each(function(i){
				var oLi = $('<li><a href="#" index="'+ i +'">'+ $(this).html() +'</a></li>');
			/* Add click handler to the a */
					$('a.selected', $wrapper).removeClass('selected');
					/* Fire the onchange event */
					if ($select[0].selectedIndex != $(this).attr('index') && $select[0].onchange) { $select[0].selectedIndex = $(this).attr('index'); $select[0].onchange(); }
					$select[0].selectedIndex = $(this).attr('index');
					$('span:eq(0)', $wrapper).html($(this).html());
					return false;
			/* Set the default */
			$('a:eq('+ this.selectedIndex +')', $ul).click();
			$('span:first', $wrapper).click(function(){$("a.jqtSelectOpen",$wrapper).trigger('click');});
			oLabel && oLabel.click(function(){$("a.jqtSelectOpen",$wrapper).trigger('click');});
			this.oLabel = oLabel;
			/* Apply the click handler to the Open */
			var oLinkOpen = $('a.jqtSelectOpen', $wrapper)
					//Check if box is already open to still allow toggle, but close all other selects
					if( $ul.css('display') == 'none' ) {jqtHideSelect();} 
					if($select.attr('disabled')){return false;}

					$ul.slideToggle('fast', function(){					
						var offSet = ($('a.selected', $ul).offset().top - $ul.offset().top);
						$ul.animate({scrollTop: offSet});
					return false;

			// Set the new width
			var iSelectWidth = $select.outerWidth();
			var oSpan = $('span:first',$wrapper);
			var newWidth = (iSelectWidth > oSpan.innerWidth())?iSelectWidth+oLinkOpen.outerWidth():$wrapper.width();
			// Calculate the height if necessary, less elements that the default height
			//show the ul to calculate the block, if ul is not displayed li height value is 0
			var iSelectHeight = ($('li',$ul).length)*($('li:first',$ul).height());//+1 else bug ff
			(iSelectHeight < $ul.height()) && $ul.css({height:iSelectHeight,'overflow':'hidden'});//hidden else bug with ff
	$.fn.jqt = function(options){
		/* each form */
		 return this.each(function(){
			var selfForm = $(this);
			if(selfForm.hasClass('jqtdone')) {return;}
			if( $('select', this).jqTransSelect().length > 0 ){}
			selfForm.bind('reset',function(){var action = function(){jqtReset(this);}; window.setTimeout(action, 10);});			
		}); /* End Form each */
	};/* End the Plugin */



$('select').change(function() {
  alert('Selection has been changed');


Open in new window


Avatar of undefined
Last Comment
Avatar of dr_Pitter


there are two points in your script:

1. jQuery uses it's own event-system. So you'll have to check for change instead of onchange  (line 162)

2. $select is a jQuery-object. It's an Array of matched Select-Elements. So $select[0] is a native HtmlSelectElement. Use $select.first() to get the select wrapped by a jQuery-Object

so, buttomline: replace

Open in new window



Open in new window

Avatar of hankknight
Flag of Canada image


Thanks, dr_Pitter.  I tried your idea but it didn't solve my problem.  Maybe I do not understand how to implement your idea.

Does this also need to be changed?
$('select').change(function() {

Open in new window

Please test the code below and let me know what I am doing wrong, thanks.
Avatar of dr_Pitter

Blurred text
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial

JavaScript is a dynamic, object-based language commonly used for client-side scripting in web browsers. Recently, server side JavaScript frameworks have also emerged. JavaScript runs on nearly every operating system and in almost every mainstream web browser.

Top Experts
Get a personalized solution from industry experts
Ask the experts
Read over 600 more reviews


IBM logoIntel logoMicrosoft logoUbisoft logoSAP logo
Qualcomm logoCitrix Systems logoWorkday logoErnst & Young logo
High performer badgeUsers love us badge
LinkedIn logoFacebook logoX logoInstagram logoTikTok logoYouTube logo