We help IT Professionals succeed at work.
Get Started

jQuery: onchange for select replacement

hankknight
hankknight asked
on
2,623 Views
Last Modified: 2012-05-11
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"> 
<head>
<title>Demo</title>
<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;
	position:relative;
	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;
	cursor:pointer;
	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;
	z-index:10;
}

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

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

.jqtSelectWrapper ul a:hover, .jqtSelectWrapper ul a.selected:hover {
	background:#3582c4;
	color: #fff;
}

.jqtHidden {display: none;}

</style>
</head> 
<body> 

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

<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>
</select>
</form>

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

<script type="text/javascript">

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


	/***************************
	  Select 
	 ***************************/	
	$.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
				.addClass('jqtHidden')
				.wrap('<div class="jqtSelectWrapper"></div>')
				.parent()
				.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>');
				$ul.append(oLi);
			});
			
			/* Add click handler to the a */
			$ul.find('a').click(function(){
					$('a.selected', $wrapper).removeClass('selected');
					$(this).addClass('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());
					$ul.hide();
					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)
				.click(function(){
					//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();
			$wrapper.css('width',newWidth);
			$ul.css('width',newWidth-2);
			oSpan.css({width:iSelectWidth});
		
			// 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
			$ul.css({display:'block',visibility:'hidden'});
			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
			$ul.css({display:'none',visibility:'visible'});
			
		});
	};
	$.fn.jqt = function(options){
		
		/* each form */
		 return this.each(function(){
			var selfForm = $(this);
			if(selfForm.hasClass('jqtdone')) {return;}
			selfForm.addClass('jqtdone');
			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 */

})(jQuery);

$(function(){$('form').jqt();});

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

</script> 
</body>
</html>

Open in new window

Comment
Watch Question
This problem has been solved!
Unlock 1 Answer and 3 Comments.
See Answer
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE