]> source.dussan.org Git - jquery-ui.git/commitdiff
Spinner: Fix step mismatches whenever stepping, paging or using the value setter.
authorScott González <scott.gonzalez@gmail.com>
Wed, 14 Sep 2011 12:54:29 +0000 (08:54 -0400)
committerScott González <scott.gonzalez@gmail.com>
Wed, 14 Sep 2011 12:55:22 +0000 (08:55 -0400)
Thanks Nate Ferrero

tests/unit/spinner/spinner_core.js
tests/unit/spinner/spinner_methods.js
tests/unit/spinner/spinner_options.js
ui/jquery.ui.spinner.js

index 34a79bb16e95c5f3665bd4cc519ba278a55565c7..e12d1af2f25d725e0f333b9e65aaa6fc3c8a5c05 100644 (file)
@@ -109,14 +109,12 @@ test( "mouse click on up button, increases value not greater than max", function
 });
 
 test( "mousewheel on input", function() {
-       expect( 5 );
+       expect( 4 );
 
-       var element = $( "#spin" ).spinner({
+       var element = $( "#spin" ).val( 0 ).spinner({
                step: 2
        });
 
-       equal( element.val(), 0 );
-
        element.trigger( "mousewheel" );
        equal( element.val(), 0, "mousewheel event without delta does not change value" );
 
@@ -198,10 +196,11 @@ test( "precision", function() {
        equal( element.val(), "0.0501", "precision from step" );
 
        element.val( 1.05 ).spinner( "option", {
-               step: 1
+               step: 1,
+               min: -9.95
        });
        element.spinner( "stepDown" );
-       equal( element.val(), "0.05", "precision from value" );
+       equal( element.val(), "0.05", "precision from min" );
 });
 
 })( jQuery );
index fbfcf1bb36964beea8980dd5d4815927a8c38b84..a9fd6c889f75e910134b46d26f8191b41f6a7345 100644 (file)
@@ -54,7 +54,7 @@ test( "disable", function() {
 
 test( "enable", function() {
        expect( 5 );
-       var element = $( "#spin" ).spinner({ disabled: true })
+       var element = $( "#spin" ).val( 1 ).spinner({ disabled: true })
                wrapper = element.spinner( "widget" );
 
        ok( wrapper.hasClass( "ui-spinner-disabled" ), "before: wrapper has ui-spinner-disabled class" );
@@ -66,7 +66,7 @@ test( "enable", function() {
        ok( !element.is( ":disabled" ), "after: input does not have disabled attribute" );
 
        spinner_simulateKeyDownUp( element, $.ui.keyCode.UP );
-       equals( 1, element.val(), "keyboard - value does not change on key UP" );
+       equals( 2, element.val(), "keyboard - value changes on key UP" );
 });
 
 test( "pageDown", function() {
@@ -117,23 +117,23 @@ test( "stepDown", function() {
        });
 
        element.spinner( "stepDown" );
-       equals( element.val(), -2, "stepDown 1 step" );
+       equals( element.val(), "-1", "stepDown 1 step" );
 
        element.spinner( "stepDown", 5 );
-       equals( element.val(), -12, "stepDown 5 steps" );
+       equals( element.val(), "-11", "stepDown 5 steps" );
 
        element.spinner( "stepDown", 4 );
-       equals( element.val(), -15, "close to min and stepDown 4 steps" );
+       equals( element.val(), "-15", "close to min and stepDown 4 steps" );
 
        element.spinner( "stepDown" );
-       equals( element.val(), -15, "at min and stepDown 1 step" );
+       equals( element.val(), "-15", "at min and stepDown 1 step" );
 });
 
 test( "stepUp", function() {
        expect( 4 );
        var element = $( "#spin" ).val( 0 ).spinner({
                step: 2,
-               max: 15
+               max: 16
        });
 
        element.spinner( "stepUp" );
@@ -143,20 +143,22 @@ test( "stepUp", function() {
        equals( element.val(), 12, "stepUp 5 steps" );
 
        element.spinner( "stepUp", 4 );
-       equals( element.val(), 15, "close to min and stepUp 4 steps" );
+       equals( element.val(), 16, "close to min and stepUp 4 steps" );
 
        element.spinner( "stepUp" );
-       equals( element.val(), 15, "at max and stepUp 1 step" );
+       equals( element.val(), 16, "at max and stepUp 1 step" );
 });
 
 test( "value", function() {
        expect( 2 );
-       var element = $( "#spin" ).val( 0 ).spinner();
+       var element = $( "#spin" ).val( 0 ).spinner({
+               step: 3
+       });
 
        element.spinner( "value", 10 );
-       equals( element.val(), 10, "change value via value method" );
+       equals( element.val(), 9, "change value via value method" );
 
-       equals( element.spinner( "value" ), 10, "get value via value method" );
+       equals( element.spinner( "value" ), 9, "get value via value method" );
 });
 
 })( jQuery );
index 48bdf96a9e2b2cb2281117907abed2ba4bf18e0c..2b557cb698fe55e0f75670cf93e7fd3fb172860d 100644 (file)
@@ -123,10 +123,11 @@ test( "step, 2", function() {
        equals( element.val(), "2", "stepUp" );
 
        element.spinner( "value", "10.5" );
-       equals( element.val(), "10.5", "value reset to 10.5" );
+       equals( element.val(), "10", "value reset to 10" );
 
+       element.val( "4.5" );
        element.spinner( "stepUp" );
-       equals( element.val(), "12.5", "stepUp" );
+       equals( element.val(), "6", "stepUp" );
 });
 
 test( "step, 0.7", function() {
index d58665265aa307166b32dd2a57f2177e5581607f..1fb715b1bcccadb4801f01afaf7faa0fd2492b05 100644 (file)
@@ -213,20 +213,16 @@ $.widget( "ui.spinner", {
        },
 
        _spin: function( step, event ) {
+               var value = this.value() || 0;
+
                if ( !this.counter ) {
                        this.counter = 1;
                }
 
-               var value = this.value(),
-                       newVal = value + step * this._increment( this.counter ),
-                       // fix precision from bad JS floating point math
-                       precision = Math.max( this._precision( value ),
-                               this._precision( this.options.step ) );
-               // clamp the new value
-               newVal = this._trimValue( newVal.toFixed( precision ) );
+               value = this._adjustValue( value + step * this._increment( this.counter ) );
 
-               if ( !this.spinning || this._trigger( "spin", event, { value: newVal } ) !== false) {
-                       this._value( newVal );
+               if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
+                       this._value( value );
                        this.counter++;
                }
        },
@@ -244,19 +240,40 @@ $.widget( "ui.spinner", {
        },
 
        _precision: function( num ) {
+               var precision = this._precisionOf( this.options.step );
+               if ( this.options.min !== null ) {
+                       precision = Math.max( precision, this._precisionOf( this.options.min ) );
+               }
+               return precision;
+       },
+
+       _precisionOf: function( num ) {
                var str = num.toString(),
                        decimal = str.indexOf( "." );
                return decimal === -1 ? 0 : str.length - decimal - 1;
        },
 
-       _trimValue: function( value ) {
-               var options = this.options;
+       _adjustValue: function( value ) {
+               var base, aboveMin,
+                       options = this.options;
 
-               if ( options.max != null && value > options.max) {
+               // make sure we're at a valid step
+               // - find out where we are relative to the base (min or 0)
+               base = options.min !== null ? options.min : 0;
+               aboveMin = value - base;
+               // - round to the nearest step
+               aboveMin = Math.round(aboveMin / options.step) * options.step;
+               // - rounding is based on 0, so adjust back to our base
+               value = base + aboveMin;
+
+               // fix precision from bad JS floating point math
+               value = parseFloat( value.toFixed( this._precision() ) );
+
+               // clamp the value
+               if ( options.max !== null && value > options.max) {
                        return options.max;
                }
-
-               if ( options.min != null && value < options.min ) {
+               if ( options.min !== null && value < options.min ) {
                        return options.min;
                }
 
@@ -295,10 +312,10 @@ $.widget( "ui.spinner", {
        }),
 
        _parse: function( val ) {
-               if ( typeof val === "string" ) {
+               if ( typeof val === "string" && val !== "" ) {
                        val = window.Globalize && this.options.numberFormat ? Globalize.parseFloat( val ) : +val;
                }
-               return isNaN( val ) ? null : val;
+               return val === "" || isNaN( val ) ? null : val;
        },
 
        _format: function( value ) {
@@ -320,13 +337,13 @@ $.widget( "ui.spinner", {
        },
 
        // update the value without triggering change
-       _value: function( value, ignoreRange ) {
+       _value: function( value, allowAny ) {
                var parsed;
                if ( value !== "" ) {
                        parsed = this._parse( value );
                        if ( parsed !== null ) {
-                               if ( !ignoreRange ) {
-                                       parsed = this._trimValue( parsed );
+                               if ( !allowAny ) {
+                                       parsed = this._adjustValue( parsed );
                                }
                                value = this._format( parsed );
                        }