/* * -------------------------------------------------------------------- * jQuery-Plugin - selectToUISlider - creates a UI slider component from a select element(s) * by Scott Jehl, scott@filamentgroup.com * http://www.filamentgroup.com * reference article: http://www.filamentgroup.com/lab/update_jquery_ui_16_slider_from_a_select_element/ * demo page: http://www.filamentgroup.com/examples/slider_v2/index.html *  * Copyright (c) 2008 Filament Group, Inc * Dual licensed under the MIT (filamentgroup.com/examples/mit-license.txt) and GPL (filamentgroup.com/examples/gpl-license.txt) licenses. * * Usage Notes: please refer to our article above for documentation *   * -------------------------------------------------------------------- */jQuery.fn.selectToUISlider = function(settings){	var selects = jQuery(this);		//accessible slider options	var options = jQuery.extend({		labels: 3, //number of visible labels		tooltip: true, //show tooltips, boolean		tooltipSrc: 'text',//accepts 'value' as well		labelSrc: 'value',//accepts 'value' as well	,		sliderOptions: null	}, settings);	//handle ID attrs - selects each need IDs for handles to find them	var handleIds = (function(){		var tempArr = [];		selects.each(function(){			tempArr.push('handle_'+jQuery(this).attr('id'));		});		return tempArr;	})();		//array of all option elements in select element (ignores optgroups)	var selectOptions = (function(){		var opts = [];		selects.eq(0).find('option').each(function(){			opts.push({				value: jQuery(this).attr('value'),				text: jQuery(this).text()			});		});		return opts;	})();		//array of opt groups if present	var groups = (function(){		if(selects.eq(0).find('optgroup').size()>0){			var groupedData = [];			selects.eq(0).find('optgroup').each(function(i){				groupedData[i] = {};				groupedData[i].label = jQuery(this).attr('label');				groupedData[i].options = [];				jQuery(this).find('option').each(function(){					groupedData[i].options.push({text: jQuery(this).text(), value: jQuery(this).attr('value')});				});			});			return groupedData;		}		else return null;	})();			//check if obj is array	function isArray(obj) {		return obj.constructor == Array;	}	//return tooltip text from option index	function ttText(optIndex){		return (options.tooltipSrc == 'text') ? selectOptions[optIndex].text : selectOptions[optIndex].value;	}		//plugin-generated slider options (can be overridden)	var sliderOptions = {		step: 1,		min: 0,		orientation: 'horizontal',		max: selectOptions.length-1,		range: selects.length > 1,//multiple select elements = true		slide: function(e, ui) {//slide function				var thisHandle = jQuery(ui.handle);				//handle feedback 				var textval = ttText(ui.value);				thisHandle					.attr('aria-valuetext', textval)					.attr('aria-valuenow', ui.value)					.find('.ui-slider-tooltip .ttContent')						.text( textval );				//control original select menu				var currSelect = jQuery('#' + thisHandle.attr('id').split('handle_')[1]);				currSelect.find('option').eq(ui.value).attr('selected', 'selected');		},		values: (function(){			var values = [];			selects.each(function(){				values.push( jQuery(this).get(0).selectedIndex );			});			return values;		})()	};		//slider options from settings	options.sliderOptions = (settings) ? jQuery.extend(sliderOptions, settings.sliderOptions) : sliderOptions;			//select element change event		selects.bind('change keyup click', function(){		var thisIndex = jQuery(this).get(0).selectedIndex;		var thisHandle = jQuery('#handle_'+ jQuery(this).attr('id'));		var handleIndex = thisHandle.data('handleNum');		thisHandle.parents('.ui-slider:eq(0)').slider("values", handleIndex, thisIndex);	});		//create slider component div	var sliderComponent = jQuery('<div></div>');	//CREATE HANDLES	selects.each(function(i){		var hidett = '';				//associate label for ARIA		var thisLabel = jQuery('label[for=' + jQuery(this).attr('id') +']');		//labelled by aria doesn't seem to work on slider handle. Using title attr as backup		var labelText = (thisLabel.size()>0) ? 'Slider control for '+ thisLabel.text()+'' : '';		var thisLabelId = thisLabel.attr('id') || thisLabel.attr('id', 'label_'+handleIds[i]).attr('id');						if( options.tooltip == false ){hidett = ' style="display: none;"';}		jQuery('<a '+				'href="#" tabindex="0" '+				'id="'+handleIds[i]+'" '+				'class="ui-slider-handle" '+				'role="slider" '+				'aria-labelledby="'+thisLabelId+'" '+				'aria-valuemin="'+options.sliderOptions.min+'" '+				'aria-valuemax="'+options.sliderOptions.max+'" '+				'aria-valuenow="'+options.sliderOptions.values[i]+'" '+				'aria-valuetext="'+ttText(options.sliderOptions.values[i])+'" '+			'><span class="screenReaderContext">'+labelText+'</span>'+			'<span class="ui-slider-tooltip ui-widget-content ui-corner-all"'+ hidett +'><span class="ttContent"></span>'+				'<span class="ui-tooltip-pointer-down ui-widget-content"><span class="ui-tooltip-pointer-down-inner"></span></span>'+			'</span></a>')			.data('handleNum',i)			.appendTo(sliderComponent);	});		//CREATE SCALE AND TICS		//write dl if there are optgroups	if(groups) {		var inc = 0;		var scale = sliderComponent.append('<dl class="ui-slider-scale ui-helper-reset" role="presentation"></dl>').find('.ui-slider-scale:eq(0)');		jQuery(groups).each(function(h){			scale.append('<dt style="width: '+ (100/groups.length).toFixed(2) +'%' +'; left:'+ (h/(groups.length-1) * 100).toFixed(2)  +'%' +'"><span>'+this.label+'</span></dt>');//class name becomes camelCased label			var groupOpts = this.options;			jQuery(this.options).each(function(i){				var style = (inc == selectOptions.length-1 || inc == 0) ? 'style="display: none;"' : '' ;				var labelText = (options.labelSrc == 'text') ? groupOpts[i].text : groupOpts[i].value;				scale.append('<dd style="left:'+ leftVal(inc) +'"><span class="ui-slider-label">'+ labelText +'</span><span class="ui-slider-tic ui-widget-content"'+ style +'></span></dd>');				inc++;			});		});	}	//write ol	else {		var scale = sliderComponent.append('<ol class="ui-slider-scale ui-helper-reset" role="presentation"></ol>').find('.ui-slider-scale:eq(0)');		jQuery(selectOptions).each(function(i){			var style = (i == selectOptions.length-1 || i == 0) ? 'style="display: none;"' : '' ;			var labelText = (options.labelSrc == 'text') ? this.text : this.value;			scale.append('<li style="left:'+ leftVal(i) +'"><span class="ui-slider-label">'+ labelText +'</span><span class="ui-slider-tic ui-widget-content"'+ style +'></span></li>');		});	}		function leftVal(i){		return (i/(selectOptions.length-1) * 100).toFixed(2)  +'%';			}				//show and hide labels depending on labels pref	//show the last one if there are more than 1 specified	if(options.labels > 1) sliderComponent.find('.ui-slider-scale li:last span.ui-slider-label, .ui-slider-scale dd:last span.ui-slider-label').addClass('ui-slider-label-show');	//set increment	var increm = Math.max(1, Math.round(selectOptions.length / options.labels));	//show em based on inc	for(var j=0; j<selectOptions.length; j+=increm){		if((selectOptions.length - j) > increm){//don't show if it's too close to the end label			sliderComponent.find('.ui-slider-scale li:eq('+ j +') span.ui-slider-label, .ui-slider-scale dd:eq('+ j +') span.ui-slider-label').addClass('ui-slider-label-show');		}	}	//style the dt's	sliderComponent.find('.ui-slider-scale dt').each(function(i){		jQuery(this).css({			'left': ((100 /( groups.length))*i).toFixed(2) + '%'		});	});		//inject and return 	sliderComponent	.insertAfter(jQuery(this).eq(this.length-1))	.slider(options.sliderOptions)	.attr('role','application')	.find('.ui-slider-label')	.each(function(){		jQuery(this).css('marginLeft', -jQuery(this).width()/2);	});		//update tooltip arrow inner color	sliderComponent.find('.ui-tooltip-pointer-down-inner').each(function(){				var bWidth = jQuery('.ui-tooltip-pointer-down-inner').css('borderTopWidth');				var bColor = jQuery(this).parents('.ui-slider-tooltip').css('backgroundColor')				jQuery(this).css('border-top', bWidth+' solid '+bColor);	});		var values = sliderComponent.slider('values');		if(isArray(values)){		jQuery(values).each(function(i){			sliderComponent.find('.ui-slider-tooltip .ttContent').eq(i).text( ttText(this) );		});	}	else {		sliderComponent.find('.ui-slider-tooltip .ttContent').eq(0).text( ttText(values) );	}		return this;}
