JavaXT
|
|
Slider Classif(!javaxt) var javaxt={}; if(!javaxt.dhtml) javaxt.dhtml={}; //****************************************************************************** //** Slider //*****************************************************************************/ /** * Horizontal slide control. Can be used as a range slider, play control, etc. * <br/> * Here's a simple example of how to instantiate the slider using an existing * div (DOM element) and a minimal config. See config settings for a full * range of options. <pre> var slider = new javaxt.dhtml.Slider(div, { units: "percent" }); </pre> * Once the slider is instantiated you can call any of the public methods. * You can also add event listeners by overriding any of the public "on" or * "before" methods like this: <pre> slider.onChange = function(value){ console.log(Math.round(value)+"%"); }; slider.setValue("50%"); </pre> * ******************************************************************************/ javaxt.dhtml.Slider = function(parent, config) { var me = this; var defaultConfig = { /** Initial value for the slider */ value: 0, /** If true, the slider will be disabled when it is initialized. The * slider can be enabled and disabled using the enable() and disable() * methods. */ disabled: false, /** Used to define the unit of measure for values returned by the * getValue(), onChange(), and onDrag() events. Options are "pixels" * (default) and "percent". */ units: "pixels", /** Style for individual elements within the component. Note that you can * provide CSS class names instead of individual style definitions. */ style: { groove: { position: "relative", display: "inline-block", backgroundColor: "#fff", backgroundImage: "linear-gradient(#4ea7ff, #6d72a5)", backgroundRepeat: "no-repeat", height: "9px", border: "1px solid #dcdcdc", borderRadius: "4px" }, handle: { position: "absolute", display: "inline-block", width: "20px", height: "20px", borderRadius: "50%", backgroundColor: "#dcdcdc", backgroundImage: "linear-gradient(#aaa, #ddd, #ccc)" } } }; var isRendered = false; var handle, slider, mask; var value; //number - leave undefined initially var sliderHeight = 0; var handleWidth = 0; var handleHeight = 0; //************************************************************************** //** Constructor //************************************************************************** var init = function(){ if (typeof parent === "string"){ parent = document.getElementById(parent); } if (!parent) return; //Clone the config so we don't modify the original config object var clone = {}; merge(clone, config); //Merge clone with default config merge(clone, defaultConfig); config = clone; //Create slider div slider = createElement('div', parent, config.style.groove); slider.style.position = "relative"; slider.style.padding = "0px"; //padding inside the grove can throw off height calc slider.style.width = '100%'; me.el = slider; //Add slider control handle = createElement('div', slider, config.style.handle); handle.style.position = "absolute"; onRender(slider, function(){ var handleRect = javaxt.dhtml.utils.getRect(handle); var sliderRect = javaxt.dhtml.utils.getRect(slider); handleWidth = handleRect.width; handleHeight = handleRect.height; sliderHeight = sliderRect.height; updateSlider(0, true); handle.style.left = -(handleWidth/2) + 'px'; handle.style.top = (-(handleHeight/2) + (sliderHeight/2)) + 'px'; var xOffset = 0; initDrag(handle, { onDragStart: function(mouseX, mouseY){ sliderRect = javaxt.dhtml.utils.getRect(slider); handleRect = javaxt.dhtml.utils.getRect(handle); xOffset = mouseX-handleRect.left; //pixels from left side of handle }, onDrag: function(mouseX, mouseY){ var w2 = handleWidth/2; var minX = -w2; var maxX = sliderRect.width-w2; var x = (mouseX-sliderRect.left)-xOffset; if (x<minX) x = minX; else if (x>maxX) x = maxX; this.style.left = x + 'px'; //Update the slider var val = x+w2; updateSlider(val); //Fire the onDrag event if (config.units==="percent") val = (value/sliderRect.width) * 100; me.onDrag(val); }, onDragEnd: function(){ this.style.cursor = 'default'; } }); if (config.disabled===true) me.disable(); isRendered = true; me.setValue(config.value, true); me.onRender(); }); }; //************************************************************************** //** enable //************************************************************************** /** Used to enable the slider. */ this.enable = function(){ var outerDiv = me.el; outerDiv.style.opacity = ""; if (mask) mask.style.visibility = "hidden"; }; //************************************************************************** //** disable //************************************************************************** /** Used to disable the slider. */ this.disable = function(){ var outerDiv = me.el; outerDiv.style.opacity = "0.5"; if (mask){ mask.style.visibility = "visible"; } else{ mask = createElement('div'); mask.setAttribute("desc", "mask"); mask.style.position = "absolute"; mask.style.zIndex = 1; mask.style.width = "100%"; mask.style.height = handleHeight + "px"; mask.style.top = handle.style.top; mask.style.left = -(handleWidth/2) + "px"; var m2 = mask.cloneNode(); m2.style.top = ""; m2.style.left = ""; m2.style.right = -(handleWidth/2) + "px"; mask.appendChild(m2); outerDiv.insertBefore(mask, outerDiv.firstChild); } }; //************************************************************************** //** isEnabled //************************************************************************** /** Returns true if the slider is enabled. */ this.isEnabled = function(){ return !me.isDisabled(); }; //************************************************************************** //** isDisabled //************************************************************************** /** Returns true if the slider is disabled. */ this.isDisabled = function(){ if (mask){ if (mask.style.visibility !== "hidden") return true; } return false; }; //************************************************************************** //** onRender //************************************************************************** /** Called after the slider has been added to the DOM */ this.onRender = function(){}; //************************************************************************** //** onDrag //************************************************************************** /** Called whenever the slider handle is dragged by the user. */ this.onDrag = function(val){}; //************************************************************************** //** onChange //************************************************************************** /** Called whenever the position of the slider handle has changed. */ this.onChange = function(val){}; //************************************************************************** //** getValue //************************************************************************** /** Returns the value of the slider. */ this.getValue = function(){ var returnPercentage = (arguments.length>0 && arguments[0]===true) || config.units==="percent"; if (returnPercentage===true){ var w = me.getWidth(); var p = (value/w) * 100; return p; } else{ return value; } }; //************************************************************************** //** getPosition //************************************************************************** /** Returns the current position of the slider, in pixels. */ this.getPosition = function(){ return value; }; //************************************************************************** //** getWidth //************************************************************************** /** Returns the width of the slider, in pixels. */ this.getWidth = function(){ return javaxt.dhtml.utils.getRect(slider).width; }; //************************************************************************** //** setValue //************************************************************************** /** Used to set the position of the slider. Note that the update will be * deferred until the slider is rendered. * @param x A number or a string representing a percentage value (e.g. '50%'). * If a number is provided and the "units" config is set to "percent", then * the number will be interpreted as a percent value from 0-100. Otherwise, * the number will be interpreted as pixels from the left of the slider. * @param silent If true, will not fire the onChange event */ this.setValue = function(x, silent){ if (!isRendered){ config.value = x; return; } onRender(slider, function(){ var setValue = function(x){ handle.style.left = (x-(handleWidth/2)) + 'px'; updateSlider(x, silent); }; if (javaxt.dhtml.utils.isString(x)){ if (x.lastIndexOf("%")===x.length-1){ x = parseFloat(x.substring(0,x.length-1)); if (isNaN(x) || x<0 || x>100) return; x = me.getWidth() * (x/100); setValue(x); } } else{ x = parseFloat(x+""); if (x<0) return; if (config.units==="percent"){ if (x>100) return; x = me.getWidth() * (x/100); } setValue(x); } }); }; //************************************************************************** //** updateSlider //************************************************************************** /** Updates the background of the slider and fires the onChange event. * @param x Pixels from the left side of the slider * @param silent If true, will not fire the onChange event */ var updateSlider = function(x, silent){ if (x===value) return; value = x; //Update the position of the background image var w = me.getWidth(); var p = (x/w)*100; var sz = p + "% auto, 100% auto"; slider.style.MozBackgroundSize = sz; //-moz-background-size slider.style.backgroundSize = sz; //background-size //Fire onChange event as needed if (silent===true) return; var val = value; if (config.units==="percent") val = p; me.onChange(val); }; //************************************************************************** //** Utils //************************************************************************** var createElement = javaxt.dhtml.utils.createElement; var initDrag = javaxt.dhtml.utils.initDrag; var onRender = javaxt.dhtml.utils.onRender; var merge = javaxt.dhtml.utils.merge; init(); }; |