r3152 committed - spinner: removed readOnly option; fixed a load of bugs flagged from un...
Revision: 3152
Author: pazu2k@gmail.com
Date: Thu Aug 27 08:58:51 2009
Log: spinner: removed readOnly option; fixed a load of bugs flagged from
unit tests; minor code refactor.
http://code.google.com/p/jquery-ui/source/detail?r=3152
Added:
/branches/dev/spinner/tests/visual/spinner/spinner_option_padding.html
/branches/dev/spinner/tests/visual/spinner/spinner_option_precision.html
Modified:
/branches/dev/spinner/tests/unit/spinner/spinner_core.js
/branches/dev/spinner/tests/unit/spinner/spinner_defaults.js
/branches/dev/spinner/tests/unit/spinner/spinner_options.js
/branches/dev/spinner/tests/visual/spinner/spinner.html
/branches/dev/spinner/tests/visual/spinner/spinner_option_readOnly.html
/branches/dev/spinner/ui/ui.spinner.js
=======================================
--- /dev/null
+++ /branches/dev/spinner/tests/visual/spinner/spinner_option_padding.html
Thu Aug 27 08:58:51 2009
@@ -0,0 +1,24 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <title>Spinner Visual Test : Spinner option padding</title>
+ <link rel="stylesheet" href="../visual.css" type="text/css">
+ <link rel="stylesheet" href="../../../themes/base/ui.all.css"
type="text/css">
+ <script type="text/javascript" src="../../../jquery-1.3.2.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.core.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.spinner.js"></script>
+ <script type="text/javascript">
+ $(function() {
+ $('#spinner').spinner({ padding: 5 });
+ $('#spinner').spinner('option', 'padding', 4);
+ });
+ </script>
+</head>
+<body>
+<div class="ui-widget">
+
+ <label>padded value:</label> <input id="spinner" type="text"
value="10">
+
+</div>
+</body>
+</html>
=======================================
--- /dev/null
+++
/branches/dev/spinner/tests/visual/spinner/spinner_option_precision.html
Thu Aug 27 08:58:51 2009
@@ -0,0 +1,24 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <title>Spinner Visual Test : Spinner option precision</title>
+ <link rel="stylesheet" href="../visual.css" type="text/css">
+ <link rel="stylesheet" href="../../../themes/base/ui.all.css"
type="text/css">
+ <script type="text/javascript" src="../../../jquery-1.3.2.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.core.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.spinner.js"></script>
+ <script type="text/javascript">
+ $(function() {
+ $('#spinner').spinner({ precision: 4, value: 1.23456789 });
+ $('#spinner').spinner('option', 'precision', 2);
+ });
+ </script>
+</head>
+<body>
+<div class="ui-widget">
+
+ <label>precision:</label> <input id="spinner" type="text"
value="10">
+
+</div>
+</body>
+</html>
=======================================
--- /branches/dev/spinner/tests/unit/spinner/spinner_core.js Mon Aug 24
21:15:22 2009
+++ /branches/dev/spinner/tests/unit/spinner/spinner_core.js Thu Aug 27
08:58:51 2009
@@ -204,7 +204,7 @@
simulateKeyDownUp(el, $.ui.keyCode.HOME);
equals(el.val(), -100);
- el.spinner('options', 'min', -200);
+ el.spinner('option', 'min', -200);
simulateKeyDownUp(el, $.ui.keyCode.HOME);
@@ -223,7 +223,7 @@
simulateKeyDownUp(el, $.ui.keyCode.END);
equals(el.val(), 100);
- el.spinner('options', 'max', 200);
+ el.spinner('option', 'max', 200);
simulateKeyDownUp(el, $.ui.keyCode.END);
=======================================
--- /branches/dev/spinner/tests/unit/spinner/spinner_defaults.js Tue Jul 28
07:46:46 2009
+++ /branches/dev/spinner/tests/unit/spinner/spinner_defaults.js Thu Aug 27
08:58:51 2009
@@ -17,7 +17,6 @@
precision: 0,
radix: 10,
radixPoint: '.',
- readOnly: null,
spinnerClass: null,
step: null,
value: 0,
=======================================
--- /branches/dev/spinner/tests/unit/spinner/spinner_options.js Tue Aug 25
11:17:52 2009
+++ /branches/dev/spinner/tests/unit/spinner/spinner_options.js Thu Aug 27
08:58:51 2009
@@ -110,10 +110,8 @@
equals(el.val(), "-$50.00", "Home key to min");
for ( var i = 1 ; i<=120 ; i++ ) {
- el.simulate("keydown",{keyCode:$.ui.keyCode.UP});
- }
-
- el.simulate("keyup",{keyCode:$.ui.keyCode.UP});
+ simulateKeyDownUp(el, $.ui.keyCode.UP);
+ }
equals(el.val(), "-$14.00", "keydown 120 times");
});
@@ -307,21 +305,21 @@
el.spinner('value', 1000);
equals(el.val(), 100, "max constrained if value method is greater");
- el.val(1000);
+ el.val(1000).blur();
equals(el.val(), 100, "max constrained if manual entry");
});
test("min", function() {
expect(3);
- el = $("#spin").spinner({ max: -100, value: -1000 });
- equals(el.val(), -100, "max constrained if value option is greater");
+ el = $("#spin").spinner({ min: -100, value: -1000 });
+ equals(el.val(), -100, "min constrained if value option is greater");
el.spinner('value', -1000);
- equals(el.val(), -100, "max constrained if value method is greater");
-
- el.val(-1000);
- equals(el.val(), -100, "max constrained if manual entry");
+ equals(el.val(), -100, "min constrained if value method is greater");
+
+ el.val(-1000).blur();
+ equals(el.val(), -100, "min constrained if manual entry");
});
test("mouseWheel", function() {
@@ -363,13 +361,13 @@
test("precision", function() {
expect(2);
- el = $("#spin").spinner({ precision: 2, value: 1.23456789 });
-
- equals(el.val(), '1.23', "2 decimal places");
-
- el.spinner('option', 'precision', 4);
-
- equals(el.val(), '1.2345', "4 decimal places");
+ el = $("#spin").spinner({ precision: 4, value: 1.23456789 });
+
+ equals(el.val(), '1.2346', "4 decimal places");
+
+ el.spinner('option', 'precision', 2);
+
+ equals(el.val(), '1.23', "2 decimal places");
});
test("radix", function() {
@@ -405,32 +403,6 @@
equals(el.val(), '-29,00', 'page down into negative space');
});
-test("readOnly", function() {
- expect(5);
-
- el = $('#spin').spinner({ readOnly: true, value: 0 });
-
- upButton().trigger('mousedown').trigger('mouseup');
-
- equals(el.val(), 0, 'mouse - value does not change on clicking up
button');
-
- simulateKeyDownUp(el, $.ui.keyCode.UP);
-
- equals(el.val(), 0, 'keyboard - value does not change on key UP');
-
- el.spinner('stepUp');
-
- equals(el.val(), 1, 'api - value changes on stepUp');
-
- el.spinner('value', 100);
-
- equals(el.val(), 100, 'api - value changes on calling the value method');
-
- el.spinner('option', 'value', 200);
-
- equals(el.val(), 200, 'api - value changes on setting option value');
-});
-
test("spinnerClass", function() {
expect(3);
=======================================
--- /branches/dev/spinner/tests/visual/spinner/spinner.html Mon Aug 17
08:28:27 2009
+++ /branches/dev/spinner/tests/visual/spinner/spinner.html Thu Aug 27
08:58:51 2009
@@ -18,17 +18,23 @@
// event callbacks
$('#spinner2').spinner({
start: function(event, ui) {
+ console.log(event, ui);
},
spin: function(event, ui) {
+ console.log(event, ui);
+ return false;
},
stop: function(event) {
+ console.log(event);
},
change: function(event) {
+ console.log(event);
}
});
// hook via bind
$('#spinner3').spinner().bind('spinstart spin spinstop spinchange',
function(event, ui) {
- });
+
+ });
});
</script>
</head>
=======================================
--- /branches/dev/spinner/tests/visual/spinner/spinner_option_readOnly.html
Thu Jul 30 21:01:26 2009
+++ /branches/dev/spinner/tests/visual/spinner/spinner_option_readOnly.html
Thu Aug 27 08:58:51 2009
@@ -11,7 +11,7 @@
$(function() {
$('#spinner1').spinner();
- $('#spinner2').spinner({ readOnly: true });
+ $('#spinner2').spinner();
});
</script>
@@ -20,7 +20,6 @@
<div class="ui-widget">
<label>HTML attribute readOnly:</label> <input id="spinner1"
type="text" readonly="readonly" value="100">
- <label>Spinner option readOnly:</label> <input id="spinner2"
type="text">
</div>
</body>
=======================================
--- /branches/dev/spinner/ui/ui.spinner.js Mon Aug 24 07:32:07 2009
+++ /branches/dev/spinner/ui/ui.spinner.js Thu Aug 27 08:58:51 2009
@@ -17,14 +17,15 @@
active = 'ui-state-active',
namespace = '.spinner',
buttonRegex = /hide|auto|fast|slow|(\d+)/,
- buttonDefault = 'show';
+ buttonDefault = 'show',
+ uiSpinnerClasses = 'ui-spinner ui-state-default ui-widget
ui-widget-content ui-corner-all ';
$.widget('ui.spinner', {
_init: function() {
this._initOptions();
-
- this._value(this._value() || this.options.value);
-
+
+ this.value(this._parse(this.element.val() || this.options.value));
+
this._draw();
this._mousewheel();
@@ -32,6 +33,8 @@
if (this.options.buttons !== buttonDefault) {
this.buttons.hide();
}
+
+ this._aria();
},
_initOptions: function() {
var self = this,
@@ -39,7 +42,7 @@
// parse min, max, step, and page based on radix
// min, max and step pull from attributes if the option is set to null
- $.each({ min: -Number.MAX_VALUE, max: Number.MAX_VALUE, step: 1},
+ $.each({ min: -Number.MAX_VALUE, max: Number.MAX_VALUE, step: 1 },
function(option, defaultValue) {
options[option] = self._parse(options[option] !== null
? options[option]
@@ -50,24 +53,21 @@
options.page = self._parse(options.page || 1);
- options.readOnly = options.readOnly !== null
- ? options.readOnly
- : self.element.attr('readonly');
-
// check for precision in stepping and set _precision as internal
- self._precision = parseInt(options.precision, 10);
-
- if (options.step.toString().indexOf('.') != -1 && self._precision === 0)
{
+ var precision = parseInt(options.precision, 10);
+
+ if (options.step.toString().indexOf('.') != -1 && precision === 0) {
var s = options.step.toString();
- self._precision = s.slice(s.indexOf('.')+1, s.length).length;
+ precision = s.slice(s.indexOf('.')+1, s.length).length;
}
// set currency options
if (options.currency) {
- this._precision = 2;
- options.radix = 10,
+ precision = 2;
+ options.radix = 10;
options.groupSeparator = options.groupSeparator || (options.radixPoint
=== ',' ? '' : ',');
}
+ options.precision = precision;
},
_draw: function() {
var self = this,
@@ -80,13 +80,9 @@
.parent()
// add buttons
.append(self._buttonHtml())
- // add aria properties
- .attr('aria-valuemin',options.min)
- .attr('aria-valuemax',options.max)
- .attr('aria-valuenow',options.value)
// add behaviours
.hover(function() {
- if (!options.readOnly && !options.disabled) {
+ if (!options.disabled) {
$(this).addClass(hover);
}
self.hovered = true;
@@ -122,20 +118,16 @@
}
})
.bind('focus'+namespace, function() {
- if (options.readOnly) {
- self.element.blur();
- return false;
- }
uiSpinner.addClass(active);
self.focused = true;
})
.bind('blur'+namespace, function(event) {
+ self._value(self.element.val());
if (!self.hovered) {
uiSpinner.removeClass(active);
}
self.focused = false;
- self._cleanUp();
- });
+ });
// force width if passed through options
if (options.width) {
@@ -155,7 +147,7 @@
}
self._repeat(null, $(this).hasClass('ui-spinner-up') ? 1 : -1, event);
- if (!self.options.disabled && !self.options.readOnly) {
+ if (!self.options.disabled) {
$(this).addClass(active);
uiSpinner.addClass(active);
}
@@ -171,7 +163,7 @@
$(this).removeClass(active);
})
.hover(function() {
- if (!self.options.disabled && !self.options.readOnly) {
+ if (!self.options.disabled) {
$(this).addClass(hover);
}
}, function(event) {
@@ -185,7 +177,7 @@
self.uiSpinner = uiSpinner;
},
_uiSpinnerHtml: function() {
- return '<div role="spinbutton" class="ui-spinner ui-state-default
ui-widget ui-widget-content ui-corner-all ' +
+ return '<div role="spinbutton" class="' + uiSpinnerClasses +
(this.options.spinnerClass || '') +
' ui-spinner-' + this.options.dir +
'"></div>';
@@ -196,21 +188,8 @@
'<a class="ui-spinner-button ui-spinner-down ui-state-default
ui-corner-b' + this.options.dir.substr(-1,1) +
'"><span class="ui-spinner-button-inner"><span class="ui-icon
ui-icon-triangle-1-s">▼</span></span></a>';
},
- _constrain: function() {
- var value = this._value();
- if (value < this.options.min) {
- this._value(this.options.min);
- }
- if (value > this.options.max) {
- this._value(this.options.max);
- }
- },
- _cleanUp: function() {
- this._value(this._value());
- this._constrain();
- },
_start: function(event) {
- if (!this.spinning && !this.options.readOnly && this._trigger('start',
event, { value: this.value()}) !== false) {
+ if (!this.spinning && this._trigger('start', event, { value:
this.value()}) !== false) {
if (!this.counter) {
this.counter = 1;
}
@@ -220,7 +199,7 @@
return false
},
_spin: function(step, event) {
- if (this.options.disabled || this.options.readOnly) {
+ if (this.options.disabled) {
return;
}
if (!this.counter) {
@@ -236,7 +215,6 @@
// cancelable
if (this._trigger('spin', event, { value: newVal }) !== false) {
this._value(newVal);
- this._constrain();
this.counter++;
}
},
@@ -289,6 +267,10 @@
case KEYS.NUMPAD_DECIMAL:
case KEYS.NUMPAD_SUBTRACT:
return true;
+
+ case KEYS.ENTER:
+ this.value(this.element.val());
+ return true;
default:
if ((event.keyCode >= 96 && event.keyCode <= 105) || // numeric keypad
0-9
@@ -321,48 +303,65 @@
});
}
},
- _value: function(newVal) {
+ _value: function(newValue) {
if (!arguments.length) {
- return this._parse(this.element.val());
- }
-
- this._format(newVal);
- this._setData('value', newVal);
- this.uiSpinner && this.uiSpinner.attr('aria-valuenow', this.value());
+ return this.options.value;
+ }
+ this._setData('value', newValue);
},
_setData: function(key, value) {
switch (key) {
case 'buttons':
this._hide();
break;
+ case 'value':
+ value = this._parse(value);
+ if (value < this.options.min) {
+ value = this.options.min;
+ }
+ if (value > this.options.max) {
+ value = this.options.max;
+ }
+ break;
+ case 'spinnerClass':
+ this.uiSpinner
+ .removeClass(this.options.spinnerClass)
+ .addClass(uiSpinnerClasses + value);
+ break;
+ }
+
+ $.widget.prototype._setData.call(this, key, value);
+
+ this._afterSetData(key, value);
+ this._aria();
+ },
+ _afterSetData: function(key, value) {
+ switch(key) {
case 'max':
case 'min':
case 'step':
- if (this.options[key] != null) {
+ if (value != null) {
// write attributes back to element if original exist
if (this.element.attr(key)) {
this.element.attr(key, value);
}
- // add aria properties
- if (/min|max/.test(key)) {
- this.element.parent().attr('aria-value'+key, value);
- }
- }
- break;
- case 'value':
- this._format(value);
+ }
break;
case 'width':
this.element.width(value);
break;
- case 'spinnerClass':
- this.uiSpinner
- .removeClass(this.options.spinnerClass)
- .addClass(value);
+ case 'precision':
+ case 'value':
+ this._format(this._parse(this.options.value));
break;
}
-
- $.widget.prototype._setData.call(this, key, value);
+ },
+ _aria: function() {
+ this.uiSpinner
+ && this.uiSpinner
+ .attr('aria-valuemin', this.options.min)
+ .attr('aria-valuemax', this.options.max)
+ .attr('aria-valuenow', this.value());
},
_validChars: function() {
var radix = parseInt(this.options.radix);
@@ -394,10 +393,11 @@
var regex = /(\d+)(\d{3})/,
options = this.options,
sym = options.currency || '',
- dec = this._precision,
+ dec = options.precision,
radix = options.radix,
group = options.groupSeparator,
- pt = options.radixPoint;
+ pt = options.radixPoint,
+ neg = num < 0 ? '-' : '';
for (
num = (
@@ -414,9 +414,8 @@
result = num.replace('-','');
while (options.padding && (result.length < options.padding)) {
result = '0' + result;
- }
-
- this.element.val((num < 0 ? '-' : '') + sym + result);
+ }
+ this.element.val(neg + sym + result);
},
_hide: function(hide) {
if (this.options.buttons === buttonDefault) {
@@ -439,7 +438,7 @@
self.buttons.animate({opacity: hide ? 'hide' : 'show'}, speed);
}, 200);
},
-
+
destroy: function() {
if ($.fn.mousewheel) {
this.element.unmousewheel();
@@ -514,7 +513,6 @@
precision: 0,
radix: 10,
radixPoint: '.',
- readOnly: null,
spinnerClass: null,
step: null,
value: 0,