2008-09-19 18:00:57 +00:00
|
|
|
/*
|
|
|
|
* jQuery UI Spinner @VERSION
|
|
|
|
*
|
|
|
|
* Copyright (c) 2008 jQuery
|
|
|
|
* Dual licensed under the MIT (MIT-LICENSE.txt)
|
|
|
|
* and GPL (GPL-LICENSE.txt) licenses.
|
|
|
|
*
|
|
|
|
* http://docs.jquery.com/UI/Spinner
|
|
|
|
*
|
|
|
|
* Depends:
|
|
|
|
* ui.core.js
|
|
|
|
*/
|
|
|
|
(function($) {
|
|
|
|
|
|
|
|
$.widget('ui.spinner', {
|
|
|
|
_init: function() {
|
2008-09-22 11:22:14 +00:00
|
|
|
this._trigger('init', null, this.ui(null));
|
2008-09-19 18:00:57 +00:00
|
|
|
|
2008-09-20 19:04:01 +00:00
|
|
|
// perform data bind on generic objects
|
|
|
|
if (typeof this.options.items[0] == 'object' && !this.element.is('input')) {
|
|
|
|
var data = this.options.items;
|
|
|
|
for (var i=0; i<data.length; i++) {
|
|
|
|
this._addItem(data[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-09-20 14:46:26 +00:00
|
|
|
// check for decimals in steppinng and set _decimals as internal
|
2008-09-23 00:57:25 +00:00
|
|
|
this._decimals = parseInt(this.options.decimals, 10);
|
2008-09-19 18:00:57 +00:00
|
|
|
if (this.options.stepping.toString().indexOf('.') != -1) {
|
|
|
|
var s = this.options.stepping.toString();
|
|
|
|
this._decimals = s.slice(s.indexOf('.')+1, s.length).length;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Initialize needed constants
|
|
|
|
var self = this;
|
|
|
|
this.element
|
|
|
|
.addClass('ui-spinner-box')
|
|
|
|
.attr('autocomplete', 'off'); // switch off autocomplete in opera
|
|
|
|
|
|
|
|
this._setValue( isNaN(this._getValue()) ? this.options.start : this._getValue() );
|
|
|
|
|
|
|
|
this.element
|
|
|
|
.wrap('<div>')
|
|
|
|
.parent()
|
|
|
|
.addClass('ui-spinner')
|
|
|
|
.append('<button class="ui-spinner-up" type="button">▲</button>')
|
|
|
|
.find('.ui-spinner-up')
|
|
|
|
.bind('mousedown', function(e) {
|
|
|
|
$(this).addClass('ui-spinner-pressed');
|
2008-09-23 00:57:25 +00:00
|
|
|
if (!self.counter) {
|
|
|
|
self.counter = 1;
|
|
|
|
}
|
2008-09-19 18:00:57 +00:00
|
|
|
self._mousedown(100, '_up', e);
|
|
|
|
})
|
|
|
|
.bind('mouseup', function(e) {
|
|
|
|
$(this).removeClass('ui-spinner-pressed');
|
2008-09-23 00:57:25 +00:00
|
|
|
if (self.counter == 1) {
|
|
|
|
self._up(e);
|
|
|
|
}
|
2008-09-19 18:00:57 +00:00
|
|
|
self._mouseup(e);
|
|
|
|
})
|
|
|
|
.bind('mouseout', function(e) {
|
|
|
|
$(this).removeClass('ui-spinner-pressed');
|
2008-09-23 07:58:29 +00:00
|
|
|
if (self.timer) {
|
|
|
|
self._mouseup(e);
|
|
|
|
}
|
2008-09-19 18:00:57 +00:00
|
|
|
})
|
|
|
|
// mousedown/mouseup capture first click, now handle second click
|
|
|
|
.bind('dblclick', function(e) {
|
|
|
|
$(this).removeClass('ui-spinner-pressed');
|
|
|
|
self._up(e);
|
2008-09-23 07:58:29 +00:00
|
|
|
self._mouseup(e);
|
2008-09-19 18:00:57 +00:00
|
|
|
})
|
|
|
|
.bind('keydown.spinner', function(e) {
|
|
|
|
var KEYS = $.keyCode;
|
|
|
|
if (e.keyCode == KEYS.SPACE || e.keyCode == KEYS.ENTER) {
|
|
|
|
$(this).addClass('ui-spinner-pressed');
|
2008-09-23 00:57:25 +00:00
|
|
|
if (!self.counter) {
|
|
|
|
self.counter = 1;
|
|
|
|
}
|
2008-09-19 18:00:57 +00:00
|
|
|
self._up.call(self, e);
|
|
|
|
} else if (e.keyCode == KEYS.DOWN || e.keyCode == KEYS.RIGHT) {
|
|
|
|
self.element.siblings('.ui-spinner-down').focus();
|
|
|
|
} else if (e.keyCode == KEYS.LEFT) {
|
|
|
|
self.element.focus();
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.bind('keyup.spinner', function(e) {
|
|
|
|
$(this).removeClass('ui-spinner-pressed');
|
|
|
|
self.counter = 0;
|
|
|
|
self._propagate('change', e);
|
|
|
|
})
|
|
|
|
.end()
|
|
|
|
.append('<button class="ui-spinner-down" type="button">▼</button>')
|
|
|
|
.find('.ui-spinner-down')
|
|
|
|
.bind('mousedown', function(e) {
|
|
|
|
$(this).addClass('ui-spinner-pressed');
|
2008-09-23 00:57:25 +00:00
|
|
|
if (!self.counter) {
|
|
|
|
self.counter = 1;
|
|
|
|
}
|
2008-09-19 18:00:57 +00:00
|
|
|
self._mousedown(100, '_down', e);
|
|
|
|
})
|
|
|
|
.bind('mouseup', function(e) {
|
|
|
|
$(this).removeClass('ui-spinner-pressed');
|
2008-09-23 00:57:25 +00:00
|
|
|
if (self.counter == 1) {
|
|
|
|
self._down();
|
|
|
|
}
|
2008-09-19 18:00:57 +00:00
|
|
|
self._mouseup(e);
|
|
|
|
})
|
|
|
|
.bind('mouseout', function(e) {
|
|
|
|
$(this).removeClass('ui-spinner-pressed');
|
2008-09-23 07:58:29 +00:00
|
|
|
if (self.timer) {
|
|
|
|
self._mouseup(e);
|
|
|
|
}
|
2008-09-19 18:00:57 +00:00
|
|
|
})
|
|
|
|
// mousedown/mouseup capture first click, now handle second click
|
|
|
|
.bind('dblclick', function(e) {
|
|
|
|
$(this).removeClass('ui-spinner-pressed');
|
|
|
|
self._down(e);
|
2008-09-23 07:58:29 +00:00
|
|
|
self._mouseup(e);
|
2008-09-19 18:00:57 +00:00
|
|
|
})
|
|
|
|
.bind('keydown.spinner', function(e) {
|
|
|
|
var KEYS = $.keyCode;
|
|
|
|
if (e.keyCode == KEYS.SPACE || e.keyCode == KEYS.ENTER) {
|
|
|
|
$(this).addClass('ui-spinner-pressed');
|
2008-09-23 00:57:25 +00:00
|
|
|
if (!self.counter) {
|
|
|
|
self.counter = 1;
|
|
|
|
}
|
2008-09-19 18:00:57 +00:00
|
|
|
self._down.call(self, e);
|
|
|
|
} else if (e.keyCode == KEYS.UP || e.keyCode == KEYS.LEFT) {
|
|
|
|
self.element.siblings('.ui-spinner-up').focus();
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.bind('keyup.spinner', function(e) {
|
|
|
|
$(this).removeClass('ui-spinner-pressed');
|
|
|
|
self.counter = 0;
|
|
|
|
self._propagate('change', e);
|
|
|
|
})
|
|
|
|
.end();
|
|
|
|
|
|
|
|
// DataList: Set contraints for object length and step size.
|
|
|
|
// Manipulate height of spinner.
|
|
|
|
this._items = this.element.children().length;
|
|
|
|
if (this._items > 1) {
|
2008-10-02 18:49:42 +00:00
|
|
|
var height = this.element.outerHeight()/this._items;
|
2008-09-19 18:00:57 +00:00
|
|
|
this.element
|
|
|
|
.addClass('ui-spinner-list')
|
2008-10-02 18:49:42 +00:00
|
|
|
.height(height)
|
2008-09-19 18:00:57 +00:00
|
|
|
.children()
|
|
|
|
.addClass('ui-spinner-listitem')
|
2008-10-02 18:49:42 +00:00
|
|
|
.height(height)
|
2008-09-20 19:04:01 +00:00
|
|
|
.css('overflow', 'hidden')
|
2008-09-19 18:00:57 +00:00
|
|
|
.end()
|
|
|
|
.parent()
|
2008-10-02 18:49:42 +00:00
|
|
|
.height(height)
|
2008-09-19 18:00:57 +00:00
|
|
|
.end();
|
|
|
|
this.options.stepping = 1;
|
|
|
|
this.options.min = 0;
|
|
|
|
this.options.max = this._items-1;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.element
|
|
|
|
.bind('keydown.spinner', function(e) {
|
2008-09-23 00:57:25 +00:00
|
|
|
if (!self.counter) {
|
|
|
|
self.counter = 1;
|
|
|
|
}
|
2008-09-19 18:00:57 +00:00
|
|
|
return self._keydown.call(self, e);
|
|
|
|
})
|
|
|
|
.bind('keyup.spinner', function(e) {
|
|
|
|
self.counter = 0;
|
|
|
|
self._propagate('change', e);
|
|
|
|
})
|
|
|
|
.bind('blur.spinner', function(e) {
|
|
|
|
self._cleanUp();
|
|
|
|
});
|
|
|
|
|
|
|
|
if ($.fn.mousewheel) {
|
|
|
|
this.element.mousewheel(function(e, delta) {
|
|
|
|
self._mousewheel(e, delta);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
_constrain: function() {
|
2008-09-23 00:57:25 +00:00
|
|
|
if (this.options.min != undefined && this._getValue() < this.options.min) {
|
|
|
|
this._setValue(this.options.min);
|
|
|
|
}
|
|
|
|
if (this.options.max != undefined && this._getValue() > this.options.max) {
|
|
|
|
this._setValue(this.options.max);
|
|
|
|
}
|
2008-09-19 18:00:57 +00:00
|
|
|
},
|
|
|
|
_cleanUp: function() {
|
|
|
|
this._setValue(this._getValue());
|
|
|
|
this._constrain();
|
|
|
|
},
|
|
|
|
_spin: function(d, e) {
|
2008-09-23 00:57:25 +00:00
|
|
|
if (this.disabled) {
|
|
|
|
return;
|
|
|
|
}
|
2008-09-19 18:00:57 +00:00
|
|
|
|
2008-09-23 00:57:25 +00:00
|
|
|
if (isNaN(this._getValue())) {
|
|
|
|
this._setValue(this.options.start);
|
|
|
|
}
|
2008-09-19 18:00:57 +00:00
|
|
|
this._setValue(this._getValue() + (d == 'up' ? 1:-1) * (this.options.incremental && this.counter > 100 ? (this.counter > 200 ? 100 : 10) : 1) * this.options.stepping);
|
|
|
|
this._animate(d);
|
|
|
|
this._constrain();
|
2008-09-23 00:57:25 +00:00
|
|
|
if (this.counter) {
|
|
|
|
this.counter++;
|
|
|
|
}
|
2008-09-19 18:00:57 +00:00
|
|
|
this._propagate('spin', e);
|
|
|
|
},
|
|
|
|
_down: function(e) {
|
|
|
|
this._spin('down', e);
|
|
|
|
this._propagate('down', e);
|
|
|
|
},
|
|
|
|
_up: function(e) {
|
|
|
|
this._spin('up', e);
|
|
|
|
this._propagate('up', e);
|
|
|
|
},
|
|
|
|
_mousedown: function(i, d, e) {
|
|
|
|
var self = this;
|
|
|
|
i = i || 100;
|
2008-09-23 00:57:25 +00:00
|
|
|
if (this.timer) {
|
|
|
|
window.clearInterval(this.timer);
|
2008-09-23 07:58:29 +00:00
|
|
|
this.timer = 0;
|
2008-09-23 00:57:25 +00:00
|
|
|
}
|
2008-09-19 18:00:57 +00:00
|
|
|
this.timer = window.setInterval(function() {
|
|
|
|
self[d](e);
|
2008-09-23 00:57:25 +00:00
|
|
|
if (self.counter > 20) {
|
|
|
|
self._mousedown(20, d, e);
|
|
|
|
}
|
2008-09-19 18:00:57 +00:00
|
|
|
}, i);
|
|
|
|
},
|
|
|
|
_mouseup: function(e) {
|
|
|
|
this.counter = 0;
|
2008-09-23 00:57:25 +00:00
|
|
|
if (this.timer) {
|
|
|
|
window.clearInterval(this.timer);
|
2008-09-23 07:58:29 +00:00
|
|
|
this.timer = 0;
|
2008-09-23 00:57:25 +00:00
|
|
|
}
|
2008-09-19 18:00:57 +00:00
|
|
|
this.element[0].focus();
|
|
|
|
this._propagate('change', e);
|
|
|
|
},
|
|
|
|
_keydown: function(e) {
|
|
|
|
var KEYS = $.keyCode;
|
|
|
|
|
2008-09-23 00:57:25 +00:00
|
|
|
if (e.keyCode == KEYS.UP) {
|
|
|
|
this._up(e);
|
|
|
|
}
|
|
|
|
if (e.keyCode == KEYS.DOWN) {
|
|
|
|
this._down(e);
|
|
|
|
}
|
|
|
|
if (e.keyCode == KEYS.HOME) {
|
|
|
|
//Home key goes to min, if defined, else to start
|
|
|
|
this._setValue(this.options.min || this.options.start);
|
|
|
|
}
|
|
|
|
if (e.keyCode == KEYS.END && this.options.max != undefined) {
|
|
|
|
//End key goes to maximum
|
|
|
|
this._setValue(this.options.max);
|
|
|
|
}
|
2008-09-19 18:00:57 +00:00
|
|
|
return (e.keyCode == KEYS.TAB || e.keyCode == KEYS.BACKSPACE ||
|
|
|
|
e.keyCode == KEYS.LEFT || e.keyCode == KEYS.RIGHT || e.keyCode == KEYS.PERIOD ||
|
|
|
|
e.keyCode == KEYS.NUMPAD_DECIMAL || e.keyCode == KEYS.NUMPAD_SUBTRACT ||
|
|
|
|
(e.keyCode >= 96 && e.keyCode <= 105) || // add support for numeric keypad 0-9
|
|
|
|
(/[0-9\-\.]/).test(String.fromCharCode(e.keyCode))) ? true : false;
|
|
|
|
},
|
|
|
|
_mousewheel: function(e, delta) {
|
2008-09-26 07:21:56 +00:00
|
|
|
var self = this;
|
2008-09-19 18:00:57 +00:00
|
|
|
delta = ($.browser.opera ? -delta / Math.abs(delta) : delta);
|
2008-09-26 07:21:56 +00:00
|
|
|
(delta > 0 ? self._up(e) : self._down(e));
|
|
|
|
if (self.timeout) {
|
|
|
|
window.clearTimeout(self.timeout);
|
|
|
|
self.timeout = 0;
|
|
|
|
}
|
2008-09-27 03:36:13 +00:00
|
|
|
self.timeout = window.setTimeout(function(){self._propagate('change', e)}, 400);
|
2008-09-19 18:00:57 +00:00
|
|
|
e.preventDefault();
|
|
|
|
},
|
|
|
|
_getValue: function() {
|
|
|
|
return parseFloat(this.element.val().replace(/[^0-9\-\.]/g, ''));
|
|
|
|
},
|
|
|
|
_setValue: function(newVal) {
|
2008-09-23 00:57:25 +00:00
|
|
|
if (isNaN(newVal)) {
|
|
|
|
newVal = this.options.start;
|
|
|
|
}
|
2008-09-19 18:00:57 +00:00
|
|
|
this.element.val(
|
|
|
|
this.options.currency ?
|
|
|
|
$.ui.spinner.format.currency(newVal, this.options.currency) :
|
|
|
|
$.ui.spinner.format.number(newVal, this._decimals)
|
|
|
|
);
|
|
|
|
},
|
|
|
|
_animate: function(d) {
|
|
|
|
if (this.element.hasClass('ui-spinner-list') && ((d == 'up' && this._getValue() <= this.options.max) || (d == 'down' && this._getValue() >= this.options.min)) ) {
|
2008-10-02 18:49:42 +00:00
|
|
|
this.element.animate({marginTop: '-' + this._getValue() * this.element.parent().height() }, {
|
2008-09-20 03:23:42 +00:00
|
|
|
duration: 'fast',
|
2008-09-19 18:00:57 +00:00
|
|
|
queue: false
|
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
2008-09-20 19:04:01 +00:00
|
|
|
_addItem: function(obj, fmt) {
|
2008-09-19 18:00:57 +00:00
|
|
|
if (!this.element.is('input')) {
|
|
|
|
var wrapper = 'div';
|
|
|
|
if (this.element.is('ol') || this.element.is('ul')) {
|
|
|
|
wrapper = 'li';
|
|
|
|
}
|
2008-09-20 19:04:01 +00:00
|
|
|
var html = obj; // string or object set it to html first
|
|
|
|
|
|
|
|
if (typeof obj == 'object') {
|
2008-09-23 00:57:25 +00:00
|
|
|
var format = (fmt !== undefined ? fmt : this.options.format);
|
2008-09-20 19:04:01 +00:00
|
|
|
|
|
|
|
html = format.replace(/%(\(([^)]+)\))?/g,
|
|
|
|
(function(data){
|
|
|
|
return function(match, a, lbl) {
|
|
|
|
if (!lbl) {
|
|
|
|
for (var itm in data) {
|
|
|
|
return data[itm]; // return the first item only
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return data[lbl];
|
|
|
|
}
|
2008-09-23 00:57:25 +00:00
|
|
|
};
|
2008-09-20 19:04:01 +00:00
|
|
|
})(obj)
|
|
|
|
);
|
|
|
|
}
|
2008-09-19 18:00:57 +00:00
|
|
|
this.element.append('<'+ wrapper +' class="ui-spinner-dyn">'+ html + '</'+ wrapper +'>');
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
plugins: {},
|
|
|
|
ui: function(e) {
|
|
|
|
return {
|
|
|
|
options: this.options,
|
|
|
|
element: this.element,
|
|
|
|
value: this._getValue(),
|
|
|
|
add: this._addItem
|
|
|
|
};
|
|
|
|
},
|
|
|
|
_propagate: function(n,e) {
|
|
|
|
$.ui.plugin.call(this, n, [e, this.ui()]);
|
|
|
|
return this.element.triggerHandler(n == 'spin' ? n : 'spin'+n, [e, this.ui()], this.options[n]);
|
|
|
|
},
|
|
|
|
destroy: function() {
|
2008-09-23 00:57:25 +00:00
|
|
|
if (!$.data(this.element[0], 'spinner')) {
|
|
|
|
return;
|
|
|
|
}
|
2008-09-19 18:00:57 +00:00
|
|
|
if ($.fn.mousewheel) {
|
|
|
|
this.element.unmousewheel();
|
|
|
|
}
|
|
|
|
this.element
|
|
|
|
.removeClass('ui-spinner-box ui-spinner-list')
|
|
|
|
.removeAttr('disabled')
|
|
|
|
.removeAttr('autocomplete')
|
|
|
|
.removeData('spinner')
|
|
|
|
.unbind('.spinner')
|
|
|
|
.siblings()
|
|
|
|
.remove()
|
|
|
|
.end()
|
|
|
|
.children()
|
|
|
|
.removeClass('ui-spinner-listitem')
|
|
|
|
.remove('.ui-spinner-dyn')
|
|
|
|
.end()
|
|
|
|
.parent()
|
|
|
|
.removeClass('ui-spinner ui-spinner-disabled')
|
|
|
|
.before(this.element.clone())
|
|
|
|
.remove()
|
|
|
|
.end();
|
|
|
|
},
|
|
|
|
enable: function() {
|
|
|
|
this.element
|
|
|
|
.removeAttr('disabled')
|
|
|
|
.siblings()
|
|
|
|
.removeAttr('disabled')
|
|
|
|
.parent()
|
|
|
|
.removeClass('ui-spinner-disabled');
|
|
|
|
this.disabled = false;
|
|
|
|
},
|
|
|
|
disable: function() {
|
|
|
|
this.element
|
|
|
|
.attr('disabled', true)
|
|
|
|
.siblings()
|
|
|
|
.attr('disabled', true)
|
|
|
|
.parent()
|
|
|
|
.addClass('ui-spinner-disabled');
|
|
|
|
this.disabled = true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
$.extend($.ui.spinner, {
|
|
|
|
defaults: {
|
2008-09-20 14:46:26 +00:00
|
|
|
decimals: 0,
|
2008-09-19 18:00:57 +00:00
|
|
|
stepping: 1,
|
|
|
|
start: 0,
|
|
|
|
incremental: true,
|
2008-09-20 19:04:01 +00:00
|
|
|
currency: false,
|
|
|
|
format: '%',
|
|
|
|
items: []
|
2008-09-19 18:00:57 +00:00
|
|
|
},
|
|
|
|
format: {
|
|
|
|
currency: function(num, sym) {
|
2008-10-02 18:06:30 +00:00
|
|
|
num = isNaN(num) ? 0 : num;
|
|
|
|
return (num !== Math.abs(num) ? '-' : '') + sym + this.number(Math.abs(num), 2);
|
2008-09-19 18:00:57 +00:00
|
|
|
},
|
2008-10-02 18:06:30 +00:00
|
|
|
number: function(num, dec) {
|
2008-10-03 04:08:08 +00:00
|
|
|
var regex = /(\d+)(\d{3})/;
|
|
|
|
for (num = isNaN(num) ? 0 : parseFloat(num,10).toFixed(dec); regex.test(num); num=num.replace(regex, '$1,$2'));
|
|
|
|
return num;
|
2008-09-19 18:00:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
})(jQuery);
|