Align slider value to step. Fixes #5471 - value not aligned to step when set programatically

This commit is contained in:
Richard D. Worth 2010-04-01 15:00:45 -04:00
parent ab1f806293
commit 5ffd3ab36a
2 changed files with 59 additions and 23 deletions

View File

@ -88,17 +88,50 @@ test("range", function() {
ok(false, "missing test - untested code is broken code."); ok(false, "missing test - untested code is broken code.");
}); });
//spec: http://wiki.jqueryui.com/Slider#specs
// value option/method: the value option is not restricted by min/max/step.
// What is returned by the value method is restricted by min (>=), max (<=), and step (even multiple)
test("step", function() { test("step", function() {
var el = $('<div></div>').slider({ var el = $('<div></div>').slider({
step: 10 min: 0,
value: 0,
step: 10,
max: 100,
}); });
equals( el.slider("value"), 0 ) equals( el.slider("value"), 0 );
el.slider("value", 1); el.slider("value", 1);
equals( el.slider("value"), 0 );
el.slider("value", 9);
equals( el.slider("value"), 10 ); equals( el.slider("value"), 10 );
el.slider("value", 10);
equals( el.slider("value"), 10 );
el.slider("value", 11); el.slider("value", 11);
equals( el.slider("value"), 10 );
el.slider("value", 19);
equals( el.slider("value"), 20 ); equals( el.slider("value"), 20 );
el = $('<div></div>').slider({
min: 0,
value: 0,
step: 20,
max: 100,
});
el.slider("value", 0);
el.slider("option", "value", 1);
equals( el.slider("value"), 0 );
el.slider("option", "value", 9);
equals( el.slider("value"), 0 );
el.slider("option", "value", 11);
equals( el.slider("value"), 20 );
el.slider("option", "value", 19);
equals( el.slider("value"), 20 );
el.slider('destroy'); el.slider('destroy');
}); });

View File

@ -340,17 +340,9 @@ $.widget("ui.slider", $.ui.mouse, {
percentMouse = 1 - percentMouse; percentMouse = 1 - percentMouse;
var valueTotal = this._valueMax() - this._valueMin(), var valueTotal = this._valueMax() - this._valueMin(),
valueMouse = percentMouse * valueTotal, valueMouse = percentMouse * valueTotal;
valueMouseModStep = valueMouse % this.options.step,
normValue = this._valueMin() + valueMouse - valueMouseModStep;
if (valueMouseModStep > (this.options.step / 2))
normValue += this.options.step;
// Since JavaScript has problems with large floats, round
// the final value to 5 digits after the decimal point (see #4124)
return parseFloat(normValue.toFixed(5));
return this._trimAlignValue(valueMouse);
}, },
_start: function(event, index) { _start: function(event, index) {
@ -440,7 +432,7 @@ $.widget("ui.slider", $.ui.mouse, {
value: function(newValue) { value: function(newValue) {
if (arguments.length) { if (arguments.length) {
this.options.value = this._trimValue(newValue); this.options.value = this._trimAlignValue(newValue);
this._refreshValue(); this._refreshValue();
this._change(null, 0); this._change(null, 0);
} }
@ -452,7 +444,7 @@ $.widget("ui.slider", $.ui.mouse, {
values: function(index, newValue) { values: function(index, newValue) {
if (arguments.length > 1) { if (arguments.length > 1) {
this.options.values[index] = this._trimValue(newValue); this.options.values[index] = this._trimAlignValue(newValue);
this._refreshValue(); this._refreshValue();
this._change(null, index); this._change(null, index);
} }
@ -461,7 +453,7 @@ $.widget("ui.slider", $.ui.mouse, {
if ($.isArray(arguments[0])) { if ($.isArray(arguments[0])) {
var vals = this.options.values, newValues = arguments[0]; var vals = this.options.values, newValues = arguments[0];
for (var i = 0, l = vals.length; i < l; i++) { for (var i = 0, l = vals.length; i < l; i++) {
vals[i] = this._trimValue(newValues[i]); vals[i] = this._trimAlignValue(newValues[i]);
this._change(null, i); this._change(null, i);
} }
this._refreshValue(); this._refreshValue();
@ -528,9 +520,9 @@ $.widget("ui.slider", $.ui.mouse, {
_value: function() { _value: function() {
//internal value getter //internal value getter
// _value() returns value trimmed by min and max // _value() returns value trimmed by min and max, aligned by step
var val = this.options.value; var val = this.options.value;
val = this._trimValue(val); val = this._trimAlignValue(val);
return val; return val;
}, },
@ -542,7 +534,7 @@ $.widget("ui.slider", $.ui.mouse, {
if (arguments.length) { if (arguments.length) {
var val = this.options.values[index]; var val = this.options.values[index];
val = this._trimValue(val); val = this._trimAlignValue(val);
return val; return val;
} else { } else {
@ -550,7 +542,7 @@ $.widget("ui.slider", $.ui.mouse, {
// this copy gets trimmed by min and max and then returned // this copy gets trimmed by min and max and then returned
var vals = this.options.values.slice(); var vals = this.options.values.slice();
for (var i = 0, l = vals.length; i < l; i++) { for (var i = 0, l = vals.length; i < l; i++) {
vals[i] = this._trimValue(vals[i]); vals[i] = this._trimAlignValue(vals[i]);
} }
return vals; return vals;
@ -558,14 +550,25 @@ $.widget("ui.slider", $.ui.mouse, {
}, },
_trimValue: function(val) { // returns the step-aligned value that val is closest to, between (inclusive) min and max
_trimAlignValue: function(val) {
if (val < this._valueMin()) { if (val < this._valueMin()) {
return this._valueMin(); return this._valueMin();
} }
if (val > this._valueMax()) { if (val > this._valueMax()) {
return this._valueMax(); return this._valueMax();
} }
return val; var step = this.options.step,
valModStep = val % step,
alignValue = this._valueMin() + val - valModStep;
if (valModStep >= (step / 2)) {
alignValue += step;
}
// Since JavaScript has problems with large floats, round
// the final value to 5 digits after the decimal point (see #4124)
return parseFloat(alignValue.toFixed(5));
}, },
_valueMin: function() { _valueMin: function() {