3 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
\r
4 <title>The source code</title>
\r
5 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
\r
6 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
\r
8 <body onload="prettyPrint();">
\r
9 <pre class="prettyprint lang-js"><div id="cls-Ext.Slider"></div>/**
\r
11 * @extends Ext.BoxComponent
\r
12 * Slider which supports vertical or horizontal orientation, keyboard adjustments,
\r
13 * configurable snapping, axis clicking and animation. Can be added as an item to
\r
14 * any container. Example usage:
\r
17 renderTo: Ext.getBody(),
\r
26 Ext.Slider = Ext.extend(Ext.BoxComponent, {
\r
27 <div id="cfg-Ext.Slider-value"></div>/**
\r
28 * @cfg {Number} value The value to initialize the slider with. Defaults to minValue.
\r
30 <div id="cfg-Ext.Slider-vertical"></div>/**
\r
31 * @cfg {Boolean} vertical Orient the Slider vertically rather than horizontally, defaults to false.
\r
34 <div id="cfg-Ext.Slider-minValue"></div>/**
\r
35 * @cfg {Number} minValue The minimum value for the Slider. Defaults to 0.
\r
38 <div id="cfg-Ext.Slider-maxValue"></div>/**
\r
39 * @cfg {Number} maxValue The maximum value for the Slider. Defaults to 100.
\r
42 <div id="cfg-Ext.Slider-decimalPrecision."></div>/**
\r
43 * @cfg {Number/Boolean} decimalPrecision.
\r
44 * <p>The number of decimal places to which to round the Slider's value. Defaults to 0.</p>
\r
45 * <p>To disable rounding, configure as <tt><b>false</b></tt>.</p>
\r
47 decimalPrecision: 0,
\r
48 <div id="cfg-Ext.Slider-keyIncrement"></div>/**
\r
49 * @cfg {Number} keyIncrement How many units to change the Slider when adjusting with keyboard navigation. Defaults to 1. If the increment config is larger, it will be used instead.
\r
52 <div id="cfg-Ext.Slider-increment"></div>/**
\r
53 * @cfg {Number} increment How many units to change the slider when adjusting by drag and drop. Use this option to enable 'snapping'.
\r
58 <div id="cfg-Ext.Slider-clickToChange"></div>/**
\r
59 * @cfg {Boolean} clickToChange Determines whether or not clicking on the Slider axis will change the slider. Defaults to true
\r
61 clickToChange : true,
\r
62 <div id="cfg-Ext.Slider-animate"></div>/**
\r
63 * @cfg {Boolean} animate Turn on or off animation. Defaults to true
\r
67 <div id="prop-Ext.Slider-dragging"></div>/**
\r
68 * True while the thumb is in a drag operation
\r
74 initComponent : function(){
\r
75 if(!Ext.isDefined(this.value)){
\r
76 this.value = this.minValue;
\r
78 Ext.Slider.superclass.initComponent.call(this);
\r
79 this.keyIncrement = Math.max(this.increment, this.keyIncrement);
\r
81 <div id="event-Ext.Slider-beforechange"></div>/**
\r
82 * @event beforechange
\r
83 * Fires before the slider value is changed. By returning false from an event handler,
\r
84 * you can cancel the event and prevent the slider from changing.
\r
85 * @param {Ext.Slider} slider The slider
\r
86 * @param {Number} newValue The new value which the slider is being changed to.
\r
87 * @param {Number} oldValue The old value which the slider was previously.
\r
90 <div id="event-Ext.Slider-change"></div>/**
\r
92 * Fires when the slider value is changed.
\r
93 * @param {Ext.Slider} slider The slider
\r
94 * @param {Number} newValue The new value which the slider has been changed to.
\r
97 <div id="event-Ext.Slider-changecomplete"></div>/**
\r
98 * @event changecomplete
\r
99 * Fires when the slider value is changed by the user and any drag operations have completed.
\r
100 * @param {Ext.Slider} slider The slider
\r
101 * @param {Number} newValue The new value which the slider has been changed to.
\r
104 <div id="event-Ext.Slider-dragstart"></div>/**
\r
106 * Fires after a drag operation has started.
\r
107 * @param {Ext.Slider} slider The slider
\r
108 * @param {Ext.EventObject} e The event fired from Ext.dd.DragTracker
\r
111 <div id="event-Ext.Slider-drag"></div>/**
\r
113 * Fires continuously during the drag operation while the mouse is moving.
\r
114 * @param {Ext.Slider} slider The slider
\r
115 * @param {Ext.EventObject} e The event fired from Ext.dd.DragTracker
\r
118 <div id="event-Ext.Slider-dragend"></div>/**
\r
120 * Fires after the drag operation has completed.
\r
121 * @param {Ext.Slider} slider The slider
\r
122 * @param {Ext.EventObject} e The event fired from Ext.dd.DragTracker
\r
128 Ext.apply(this, Ext.Slider.Vertical);
\r
132 // private override
\r
133 onRender : function(){
\r
135 cls: 'x-slider ' + (this.vertical ? 'x-slider-vert' : 'x-slider-horz'),
\r
136 cn:{cls:'x-slider-end',cn:{cls:'x-slider-inner',cn:[{cls:'x-slider-thumb'},{tag:'a', cls:'x-slider-focus', href:"#", tabIndex: '-1', hidefocus:'on'}]}}
\r
138 Ext.Slider.superclass.onRender.apply(this, arguments);
\r
139 this.endEl = this.el.first();
\r
140 this.innerEl = this.endEl.first();
\r
141 this.thumb = this.innerEl.first();
\r
142 this.halfThumb = (this.vertical ? this.thumb.getHeight() : this.thumb.getWidth())/2;
\r
143 this.focusEl = this.thumb.next();
\r
147 // private override
\r
148 initEvents : function(){
\r
149 this.thumb.addClassOnOver('x-slider-thumb-over');
\r
150 this.mon(this.el, {
\r
152 mousedown: this.onMouseDown,
\r
153 keydown: this.onKeyDown
\r
156 this.focusEl.swallowEvent("click", true);
\r
158 this.tracker = new Ext.dd.DragTracker({
\r
159 onBeforeStart: this.onBeforeDragStart.createDelegate(this),
\r
160 onStart: this.onDragStart.createDelegate(this),
\r
161 onDrag: this.onDrag.createDelegate(this),
\r
162 onEnd: this.onDragEnd.createDelegate(this),
\r
166 this.tracker.initEl(this.thumb);
\r
169 // private override
\r
170 onMouseDown : function(e){
\r
174 if(this.clickToChange && e.target != this.thumb.dom){
\r
175 var local = this.innerEl.translatePoints(e.getXY());
\r
176 this.onClickChange(local);
\r
182 onClickChange : function(local){
\r
183 if(local.top > this.clickRange[0] && local.top < this.clickRange[1]){
\r
184 this.setValue(Ext.util.Format.round(this.reverseValue(local.left), this.decimalPrecision), undefined, true);
\r
189 onKeyDown : function(e){
\r
190 if(this.disabled){e.preventDefault();return;}
\r
191 var k = e.getKey();
\r
197 this.setValue(this.maxValue, undefined, true);
\r
199 this.setValue(this.value+this.keyIncrement, undefined, true);
\r
206 this.setValue(this.minValue, undefined, true);
\r
208 this.setValue(this.value-this.keyIncrement, undefined, true);
\r
212 e.preventDefault();
\r
217 doSnap : function(value){
\r
218 if(!(this.increment && value)){
\r
221 var newValue = value,
\r
222 inc = this.increment,
\r
228 }else if(m * 2 < -inc){
\r
232 return newValue.constrain(this.minValue, this.maxValue);
\r
236 afterRender : function(){
\r
237 Ext.Slider.superclass.afterRender.apply(this, arguments);
\r
238 if(this.value !== undefined){
\r
239 var v = this.normalizeValue(this.value);
\r
240 if(v !== this.value){
\r
242 this.setValue(v, false);
\r
244 this.moveThumb(this.translateValue(v), false);
\r
250 getRatio : function(){
\r
251 var w = this.innerEl.getWidth(),
\r
252 v = this.maxValue - this.minValue;
\r
253 return v == 0 ? w : (w/v);
\r
257 normalizeValue : function(v){
\r
258 v = this.doSnap(v);
\r
259 v = Ext.util.Format.round(v, this.decimalPrecision);
\r
260 v = v.constrain(this.minValue, this.maxValue);
\r
264 <div id="method-Ext.Slider-setValue"></div>/**
\r
265 * Programmatically sets the value of the Slider. Ensures that the value is constrained within
\r
266 * the minValue and maxValue.
\r
267 * @param {Number} value The value to set the slider to. (This will be constrained within minValue and maxValue)
\r
268 * @param {Boolean} animate Turn on or off animation, defaults to true
\r
270 setValue : function(v, animate, changeComplete){
\r
271 v = this.normalizeValue(v);
\r
272 if(v !== this.value && this.fireEvent('beforechange', this, v, this.value) !== false){
\r
274 this.moveThumb(this.translateValue(v), animate !== false);
\r
275 this.fireEvent('change', this, v);
\r
276 if(changeComplete){
\r
277 this.fireEvent('changecomplete', this, v);
\r
283 translateValue : function(v){
\r
284 var ratio = this.getRatio();
\r
285 return (v * ratio) - (this.minValue * ratio) - this.halfThumb;
\r
288 reverseValue : function(pos){
\r
289 var ratio = this.getRatio();
\r
290 return (pos + this.halfThumb + (this.minValue * ratio)) / ratio;
\r
294 moveThumb: function(v, animate){
\r
295 if(!animate || this.animate === false){
\r
296 this.thumb.setLeft(v);
\r
298 this.thumb.shift({left: v, stopFx: true, duration:.35});
\r
303 focus : function(){
\r
304 this.focusEl.focus(10);
\r
308 onBeforeDragStart : function(e){
\r
309 return !this.disabled;
\r
313 onDragStart: function(e){
\r
314 this.thumb.addClass('x-slider-thumb-drag');
\r
315 this.dragging = true;
\r
316 this.dragStartValue = this.value;
\r
317 this.fireEvent('dragstart', this, e);
\r
321 onDrag: function(e){
\r
322 var pos = this.innerEl.translatePoints(this.tracker.getXY());
\r
323 this.setValue(Ext.util.Format.round(this.reverseValue(pos.left), this.decimalPrecision), false);
\r
324 this.fireEvent('drag', this, e);
\r
328 onDragEnd: function(e){
\r
329 this.thumb.removeClass('x-slider-thumb-drag');
\r
330 this.dragging = false;
\r
331 this.fireEvent('dragend', this, e);
\r
332 if(this.dragStartValue != this.value){
\r
333 this.fireEvent('changecomplete', this, this.value);
\r
338 onResize : function(w, h){
\r
339 this.innerEl.setWidth(w - (this.el.getPadding('l') + this.endEl.getPadding('r')));
\r
344 onDisable: function(){
\r
345 Ext.Slider.superclass.onDisable.call(this);
\r
346 this.thumb.addClass(this.disabledClass);
\r
348 //IE breaks when using overflow visible and opacity other than 1.
\r
349 //Create a place holder for the thumb and display it.
\r
350 var xy = this.thumb.getXY();
\r
352 this.innerEl.addClass(this.disabledClass).dom.disabled = true;
\r
353 if (!this.thumbHolder){
\r
354 this.thumbHolder = this.endEl.createChild({cls: 'x-slider-thumb ' + this.disabledClass});
\r
356 this.thumbHolder.show().setXY(xy);
\r
361 onEnable: function(){
\r
362 Ext.Slider.superclass.onEnable.call(this);
\r
363 this.thumb.removeClass(this.disabledClass);
\r
365 this.innerEl.removeClass(this.disabledClass).dom.disabled = false;
\r
366 if(this.thumbHolder){
\r
367 this.thumbHolder.hide();
\r
374 <div id="method-Ext.Slider-syncThumb"></div>/**
\r
375 * Synchronizes the thumb position to the proper proportion of the total component width based
\r
376 * on the current slider {@link #value}. This will be called automatically when the Slider
\r
377 * is resized by a layout, but if it is rendered auto width, this method can be called from
\r
378 * another resize handler to sync the Slider if necessary.
\r
380 syncThumb : function(){
\r
382 this.moveThumb(this.translateValue(this.value));
\r
386 <div id="method-Ext.Slider-getValue"></div>/**
\r
387 * Returns the current value of the slider
\r
388 * @return {Number} The current value of the slider
\r
390 getValue : function(){
\r
395 beforeDestroy : function(){
\r
396 Ext.destroyMembers(this, 'endEl', 'innerEl', 'thumb', 'halfThumb', 'focusEl', 'tracker', 'thumbHolder');
\r
397 Ext.Slider.superclass.beforeDestroy.call(this);
\r
400 Ext.reg('slider', Ext.Slider);
\r
402 // private class to support vertical sliders
\r
403 Ext.Slider.Vertical = {
\r
404 onResize : function(w, h){
\r
405 this.innerEl.setHeight(h - (this.el.getPadding('t') + this.endEl.getPadding('b')));
\r
409 getRatio : function(){
\r
410 var h = this.innerEl.getHeight(),
\r
411 v = this.maxValue - this.minValue;
\r
415 moveThumb: function(v, animate){
\r
416 if(!animate || this.animate === false){
\r
417 this.thumb.setBottom(v);
\r
419 this.thumb.shift({bottom: v, stopFx: true, duration:.35});
\r
423 onDrag: function(e){
\r
424 var pos = this.innerEl.translatePoints(this.tracker.getXY()),
\r
425 bottom = this.innerEl.getHeight()-pos.top;
\r
426 this.setValue(this.minValue + Ext.util.Format.round(bottom/this.getRatio(), this.decimalPrecision), false);
\r
427 this.fireEvent('drag', this, e);
\r
430 onClickChange : function(local){
\r
431 if(local.left > this.clickRange[0] && local.left < this.clickRange[1]){
\r
432 var bottom = this.innerEl.getHeight() - local.top;
\r
433 this.setValue(this.minValue + Ext.util.Format.round(bottom/this.getRatio(), this.decimalPrecision), undefined, true);
\r