/** * Ext JS Library 3.4.0 * Copyright(c) 2006-2011 Sencha Inc. * licensing@sencha.com * http://www.sencha.com/license */ /** * @class Ext.ux.Spinner * @extends Ext.util.Observable * Creates a Spinner control utilized by Ext.ux.form.SpinnerField */ Ext.ux.Spinner = Ext.extend(Ext.util.Observable, { incrementValue: 1, alternateIncrementValue: 5, triggerClass: 'x-form-spinner-trigger', splitterClass: 'x-form-spinner-splitter', alternateKey: Ext.EventObject.shiftKey, defaultValue: 0, accelerate: false, constructor: function (config) { Ext.ux.Spinner.superclass.constructor.call(this, config); Ext.apply(this, config); this.mimicing = false; }, init: function (field) { this.field = field; field.afterMethod('onRender', this.doRender, this); field.afterMethod('onEnable', this.doEnable, this); field.afterMethod('onDisable', this.doDisable, this); field.afterMethod('afterRender', this.doAfterRender, this); field.afterMethod('onResize', this.doResize, this); field.afterMethod('onFocus', this.doFocus, this); field.beforeMethod('onDestroy', this.doDestroy, this); }, doRender: function (ct, position) { var el = (this.el = this.field.getEl()); var f = this.field; if (!f.wrap) { f.wrap = this.wrap = el.wrap({ cls: 'x-form-field-wrap', }); } else { this.wrap = f.wrap.addClass('x-form-field-wrap'); } this.trigger = this.wrap.createChild({ tag: 'img', src: Ext.BLANK_IMAGE_URL, cls: 'x-form-trigger ' + this.triggerClass, }); if (!f.width) { this.wrap.setWidth(el.getWidth() + this.trigger.getWidth()); } this.splitter = this.wrap.createChild({ tag: 'div', cls: this.splitterClass, style: 'width:13px; height:2px;', }); this.splitter .setRight(Ext.isIE ? 1 : 2) .setTop(10) .show(); this.proxy = this.trigger.createProxy('', this.splitter, true); this.proxy.addClass('x-form-spinner-proxy'); this.proxy.setStyle('left', '0px'); this.proxy.setSize(14, 1); this.proxy.hide(); this.dd = new Ext.dd.DDProxy(this.splitter.dom.id, 'SpinnerDrag', { dragElId: this.proxy.id, }); this.initTrigger(); this.initSpinner(); }, doAfterRender: function () { var y; if (Ext.isIE && this.el.getY() != (y = this.trigger.getY())) { this.el.position(); this.el.setY(y); } }, doEnable: function () { if (this.wrap) { this.disabled = false; this.wrap.removeClass(this.field.disabledClass); } }, doDisable: function () { if (this.wrap) { this.disabled = true; this.wrap.addClass(this.field.disabledClass); this.el.removeClass(this.field.disabledClass); } }, doResize: function (w, h) { if (typeof w == 'number') { this.el.setWidth(w - this.trigger.getWidth()); } this.wrap.setWidth(this.el.getWidth() + this.trigger.getWidth()); }, doFocus: function () { if (!this.mimicing) { this.wrap.addClass('x-trigger-wrap-focus'); this.mimicing = true; Ext.get(Ext.isIE ? document.body : document).on( 'mousedown', this.mimicBlur, this, { delay: 10, } ); this.el.on('keydown', this.checkTab, this); } }, // private checkTab: function (e) { if (e.getKey() == e.TAB) { this.triggerBlur(); } }, // private mimicBlur: function (e) { if (!this.wrap.contains(e.target) && this.field.validateBlur(e)) { this.triggerBlur(); } }, // private triggerBlur: function () { this.mimicing = false; Ext.get(Ext.isIE ? document.body : document).un( 'mousedown', this.mimicBlur, this ); this.el.un('keydown', this.checkTab, this); this.field.beforeBlur(); this.wrap.removeClass('x-trigger-wrap-focus'); this.field.onBlur.call(this.field); }, initTrigger: function () { this.trigger.addClassOnOver('x-form-trigger-over'); this.trigger.addClassOnClick('x-form-trigger-click'); }, initSpinner: function () { this.field.addEvents({ spin: true, spinup: true, spindown: true, }); this.keyNav = new Ext.KeyNav(this.el, { up: function (e) { e.preventDefault(); this.onSpinUp(); }, down: function (e) { e.preventDefault(); this.onSpinDown(); }, pageUp: function (e) { e.preventDefault(); this.onSpinUpAlternate(); }, pageDown: function (e) { e.preventDefault(); this.onSpinDownAlternate(); }, scope: this, }); this.repeater = new Ext.util.ClickRepeater(this.trigger, { accelerate: this.accelerate, }); this.field.mon(this.repeater, 'click', this.onTriggerClick, this, { preventDefault: true, }); this.field.mon(this.trigger, { mouseover: this.onMouseOver, mouseout: this.onMouseOut, mousemove: this.onMouseMove, mousedown: this.onMouseDown, mouseup: this.onMouseUp, scope: this, preventDefault: true, }); this.field.mon(this.wrap, 'mousewheel', this.handleMouseWheel, this); this.dd.setXConstraint(0, 0, 10); this.dd.setYConstraint(1500, 1500, 10); this.dd.endDrag = this.endDrag.createDelegate(this); this.dd.startDrag = this.startDrag.createDelegate(this); this.dd.onDrag = this.onDrag.createDelegate(this); }, onMouseOver: function () { if (this.disabled) { return; } var middle = this.getMiddle(); this.tmpHoverClass = Ext.EventObject.getPageY() < middle ? 'x-form-spinner-overup' : 'x-form-spinner-overdown'; this.trigger.addClass(this.tmpHoverClass); }, //private onMouseOut: function () { this.trigger.removeClass(this.tmpHoverClass); }, //private onMouseMove: function () { if (this.disabled) { return; } var middle = this.getMiddle(); if ( (Ext.EventObject.getPageY() > middle && this.tmpHoverClass == 'x-form-spinner-overup') || (Ext.EventObject.getPageY() < middle && this.tmpHoverClass == 'x-form-spinner-overdown') ) { } }, //private onMouseDown: function () { if (this.disabled) { return; } var middle = this.getMiddle(); this.tmpClickClass = Ext.EventObject.getPageY() < middle ? 'x-form-spinner-clickup' : 'x-form-spinner-clickdown'; this.trigger.addClass(this.tmpClickClass); }, //private onMouseUp: function () { this.trigger.removeClass(this.tmpClickClass); }, //private onTriggerClick: function () { if (this.disabled || this.el.dom.readOnly) { return; } var middle = this.getMiddle(); var ud = Ext.EventObject.getPageY() < middle ? 'Up' : 'Down'; this['onSpin' + ud](); }, //private getMiddle: function () { var t = this.trigger.getTop(); var h = this.trigger.getHeight(); var middle = t + h / 2; return middle; }, //private //checks if control is allowed to spin isSpinnable: function () { if (this.disabled || this.el.dom.readOnly) { Ext.EventObject.preventDefault(); //prevent scrolling when disabled/readonly return false; } return true; }, handleMouseWheel: function (e) { //disable scrolling when not focused if (this.wrap.hasClass('x-trigger-wrap-focus') == false) { return; } var delta = e.getWheelDelta(); if (delta > 0) { this.onSpinUp(); e.stopEvent(); } else if (delta < 0) { this.onSpinDown(); e.stopEvent(); } }, //private startDrag: function () { this.proxy.show(); this._previousY = Ext.fly(this.dd.getDragEl()).getTop(); }, //private endDrag: function () { this.proxy.hide(); }, //private onDrag: function () { if (this.disabled) { return; } var y = Ext.fly(this.dd.getDragEl()).getTop(); var ud = ''; if (this._previousY > y) { ud = 'Up'; } //up if (this._previousY < y) { ud = 'Down'; } //down if (ud != '') { this['onSpin' + ud](); } this._previousY = y; }, //private onSpinUp: function () { if (this.isSpinnable() == false) { return; } if (Ext.EventObject.shiftKey == true) { this.onSpinUpAlternate(); return; } else { this.spin(false, false); } this.field.fireEvent('spin', this); this.field.fireEvent('spinup', this); }, //private onSpinDown: function () { if (this.isSpinnable() == false) { return; } if (Ext.EventObject.shiftKey == true) { this.onSpinDownAlternate(); return; } else { this.spin(true, false); } this.field.fireEvent('spin', this); this.field.fireEvent('spindown', this); }, //private onSpinUpAlternate: function () { if (this.isSpinnable() == false) { return; } this.spin(false, true); this.field.fireEvent('spin', this); this.field.fireEvent('spinup', this); }, //private onSpinDownAlternate: function () { if (this.isSpinnable() == false) { return; } this.spin(true, true); this.field.fireEvent('spin', this); this.field.fireEvent('spindown', this); }, spin: function (down, alternate) { var v = parseFloat(this.field.getValue()); var incr = alternate == true ? this.alternateIncrementValue : this.incrementValue; down == true ? (v -= incr) : (v += incr); v = isNaN(v) ? this.defaultValue : v; v = this.fixBoundries(v); this.field.setRawValue(v); }, fixBoundries: function (value) { var v = value; if (this.field.minValue != undefined && v < this.field.minValue) { v = this.field.minValue; } if (this.field.maxValue != undefined && v > this.field.maxValue) { v = this.field.maxValue; } return this.fixPrecision(v); }, // private fixPrecision: function (value) { var nan = isNaN(value); if ( !this.field.allowDecimals || this.field.decimalPrecision == -1 || nan || !value ) { return nan ? '' : value; } return parseFloat( parseFloat(value).toFixed(this.field.decimalPrecision) ); }, doDestroy: function () { if (this.trigger) { this.trigger.remove(); } if (this.wrap) { this.wrap.remove(); delete this.field.wrap; } if (this.splitter) { this.splitter.remove(); } if (this.dd) { this.dd.unreg(); this.dd = null; } if (this.proxy) { this.proxy.remove(); } if (this.repeater) { this.repeater.purgeListeners(); } if (this.mimicing) { Ext.get(Ext.isIE ? document.body : document).un( 'mousedown', this.mimicBlur, this ); } }, }); //backwards compat Ext.form.Spinner = Ext.ux.Spinner;