r2946 - spinner: further code clean-up and bugfixes in _parse and _format methods.
Author: pazu2k@gmail.com
Date: Mon Jul 20 02:07:03 2009
New Revision: 2946
Modified:
branches/dev/spinner/ui/ui.spinner.js
Log:
spinner: further code clean-up and bugfixes in _parse and _format methods.
Modified: branches/dev/spinner/ui/ui.spinner.js
==============================================================================
--- branches/dev/spinner/ui/ui.spinner.js (original)
+++ branches/dev/spinner/ui/ui.spinner.js Mon Jul 20 02:07:03 2009
@@ -19,27 +19,20 @@
$.widget('ui.spinner', {
_init: function() {
- // currentDelay can't be initialized as part of the prototype because
all widgets would share the same object
- this.currentDelay = {};
this._initOptions();
// set value on init
- this._value(this._value());
+ this._value(this._value() || this.options.value);
// draw widget
- this._draw();
+ this._draw();
if (this.options.hide) {
this._hide();
}
this._mousewheel();
-
- // disable spinner if element was already disabled
- if (this.element.attr("disabled")) {
- this.disable();
- }
},
_initOptions: function() {
var self = this,
@@ -87,15 +80,17 @@
spinnerClass = options.spinnerClass,
spinnerBoxClass = 'ui-spinner-box',
widgetClasses = 'ui-spinner ui-state-default ui-widget
ui-widget-content ui-corner-all ui-spinner-' + dir + (spinnerClass ? ' '+
spinnerClass: '');
-
+
var widget = self.element
.addClass(spinnerBoxClass)
.attr('autocomplete', 'off') // switch off autocomplete in opera
.wrap('<div role="spinbutton">')
.parent()
.addClass(widgetClasses)
- .append('<a class="ui-spinner-button ui-spinner-up ui-state-default
ui-corner-t'+ dir.substr(-1,1) +'"><span
class="ui-spinner-button-inner"><span class="ui-icon
ui-icon-triangle-1-n">▲</span></span></a>')
- .append('<a class="ui-spinner-button ui-spinner-down ui-state-default
ui-corner-b'+ dir.substr(-1,1) +'"><span
class="ui-spinner-button-inner"><span class="ui-icon
ui-icon-triangle-1-s">▼</span></span></a>');
+ .append(
+ '<a class="ui-spinner-button ui-spinner-up ui-state-default
ui-corner-t'+ dir.substr(-1,1) +'"><span
class="ui-spinner-button-inner"><span class="ui-icon
ui-icon-triangle-1-n">▲</span></span></a>' +
+ '<a class="ui-spinner-button ui-spinner-down ui-state-default
ui-corner-b'+ dir.substr(-1,1) +'"><span
class="ui-spinner-button-inner"><span class="ui-icon
ui-icon-triangle-1-s">▼</span></span></a>'
+ );
// TODO: need a better way to exclude IE8 without resorting to
$.browser.version
// fix inline-block issues for IE. Since IE8 supports inline-block we
need to exclude it.
@@ -138,8 +133,8 @@
self._delay(self._hide, 100, 'hide', options.hide);
}
});
-
- self.buttons = widget.find('.ui-spinner-button')
+
+ this.buttons = widget.find('.ui-spinner-button')
.bind('mousedown', function(event) {
self._start(event);
self._mousedown(100, $(this).hasClass('ui-spinner-up') ? 1 : -1,
event);
@@ -182,12 +177,12 @@
}
});
- self.element
+ this.element
.bind('keydown'+namespace, function(event) {
self._start(event);
})
.bind('keypress'+namespace, function(event) {
- return self._keydown.call(self, event);
+ return self._keydown(event);
})
.bind('keyup'+namespace, function(event) {
self._stop(event);
@@ -213,15 +208,21 @@
self._delay(self._hide, 100, 'hide', options.hide);
}
self._cleanUp();
- });
+ });
+
+ // disable spinner if element was already disabled
+ if (this.element.attr("disabled")) {
+ this.disable();
+ }
- self.widget = widget;
+ self.widget = widget;
},
_constrain: function() {
- if (this.options.min !== null && this._value() < this.options.min) {
+ var value = this._value();
+ if (value < this.options.min) {
this._value(this.options.min);
}
- if (this.options.max !== null && this._value() > this.options.max) {
+ if (value > this.options.max) {
this._value(this.options.max);
}
},
@@ -230,11 +231,15 @@
this._constrain();
},
_start: function(event) {
- if (!this.counter) {
- this.counter = 1;
+ if (!self.spinning) {
+ if (!this.counter) {
+ this.counter = 1;
+ }
+ this.spinning = true;
+ this._trigger('start', event, {
+ value: this.value()
+ });
}
- this.spinning = true;
- this._trigger('start', event, { value: this.value() });
},
_spin: function(step, event) {
if (this.disabled) {
@@ -276,7 +281,7 @@
},
_keydown: function(event) {
var o = this.options,
- jump = o.page * o.step;
+ jump = o.page * o.step,
KEYS = $.ui.keyCode;
switch (event.keyCode) {
@@ -297,8 +302,9 @@
return true;
default:
+ var code = event.keyCode || event.charCode;
if ((event.keyCode >= 96 && event.keyCode <= 105) || // numeric keypad
0-9
- (new RegExp('[' + this._validChars()
+ ']', 'i').test(String.fromCharCode(event.keyCode)))) {
+ (new RegExp('[' + this._validChars()
+ ']', 'i').test(String.fromCharCode(code)))) {
return true;
};
}
@@ -310,9 +316,7 @@
if ($.fn.mousewheel && self.options.mouseWheel) {
this.element.mousewheel(function(event, delta) {
delta = ($.browser.opera ? -delta / Math.abs(delta) : delta);
- if (!self.spinning) {
- self._start(event);
- }
+ self._start(event);
self._spin((delta > 0 ? 1 : -1) * self.options.step, event);
if (self.timeout) {
window.clearTimeout(self.timeout);
@@ -325,39 +329,21 @@
});
}
},
- _parse: function(val) {
- if (typeof val == 'string') {
- // Because groupSeparator is included in the regex, we must replace it
independently
- if (this.options.groupSeparator) {
- val = val.replace(this.options.groupSeparator, '');
- }
-
- val = val.replace(new RegExp('[^' + this._validChars()
+ ']', 'gi'), '').split(this.options.radixPoint);
-
- result = parseInt(val[0], this.options.radix);
- if (val.length > 1) {
- result += parseInt(val[1], this.options.radix) /
Math.pow(this.options.radix, val[1].length) *
- // must test first character of val[0] for minus sign because -0 is
parsed as 0 in result
- (val[0][0] == '-' ? -1 : 1);
- }
- val = result;
- }
- return isNaN(val) ? null : val;
- },
_value: function(newVal) {
if (!arguments.length) {
- var value = this._parse(this.element.val());
- return isNaN(value) ? this.options.value : value;
+ return this._parse(this.element.val());
}
- this.element.val(this._format(newVal));
+ this._format(newVal);
this.element.parents('.' + this.widgetBaseClass
+ ':first').attr('aria-valuenow', this.value());
},
// delays a function call, allowing only one at a time of the same type
_delay: function(callback, delay, type) {
type = type || 'a';
-
+ if (!this.currentDelay) {
+ this.currentDelay = {};
+ }
var self = this,
curDelay = self.currentDelay[type] || {},
args = Array.prototype.slice.call(arguments, 3);
@@ -387,7 +373,6 @@
return this;
},
_hide: function(speed) {
- // also removeClass(hover) in case it was left despite losing mouse hover
var buttons = this.buttons.stop().removeClass(hover);
if (!speed) {
buttons.css('opacity', 0);
@@ -420,32 +405,50 @@
$.widget.prototype._setData.call(this, key, value);
},
- _format: function(num) {
- var sym = this.options.currency ? this.options.currency : '',
- dec = this.options.currency ? 2 : this._precision,
- radix = this.options.currency ? 10 : this.options.radix,
- group = this.options.currency ? (this.options.groupSeparator || ',') :
this.options.groupSeprator,
- whole = Math.floor(Math.abs(num)),
- result = whole.toString(radix),
- part = Math.floor(((Math.abs(num) - whole) * Math.pow(radix,
dec))).toString(radix),
- regex = /(\d+)(\d{3})/;
-
- while (regex.test(result) && group) {
- result = result.replace(regex, '$1'+group+'$2');
- }
-
- if (dec > 0) {
- while (part.length < dec) {
- part = '0' + part;
+ _parse: function(val) {
+ if (typeof val == 'string') {
+ if (this.options.groupSeparator) {
+ val = val.replace(new
RegExp('\\'+this.options.groupSeparator,'g'), '');
}
- result += this.options.radixPoint + part;
+ val = val.replace(new RegExp('[^' + this._validChars()
+ ']', 'gi'), '').split(this.options.radixPoint);
+
+ result = parseInt(val[0], this.options.radix);
+ if (val.length > 1) {
+ result += parseInt(val[1], this.options.radix) /
Math.pow(this.options.radix, val[1].length) *
+ // must test first character of val[0] for minus sign because -0 is
parsed as 0 in result
+ (val[0][0] == '-' ? -1 : 1);
+ }
+ val = result;
}
-
- while (this.options.padLength && (result.length <
this.options.padLength)) {
+ return isNaN(val) ? null : val;
+ },
+ _format: function(num) {
+ var regex = /(\d+)(\d{3})/,
+ options = this.options,
+ sym = options.currency ? options.currency : '',
+ dec = options.currency ? 2 : this._precision,
+ radix = options.currency ? 10 : options.radix,
+ group = options.currency ? (options.groupSeparator || ',') :
options.groupSeparator,
+ pt = options.radixPoint;
+
+ for (
+ num = (
+ isNaN(num)
+ ? options.value
+ : radix === 10
+ ? parseFloat(num, radix).toFixed(dec)
+ : parseInt(num, radix)
+ ).toString(radix).replace('.', pt);
+ regex.test(num) && group;
+ num = num.replace(regex, '$1'+group+'$2')
+ );
+
+ result = num.replace('-','');
+ while (options.padLength && (result.length < options.padLength)) {
result = '0' + result;
}
- return (num < 0 ? '-' : '') + sym + result;
+ this.element.val((num < 0 ? '-' : '') + sym + result);
},
destroy: function() {