Skip to content

Commit d91cd61

Browse files
committed
Spinner: More refactorings and cleanups, and heavy improvement on the incremental-logic, including a delay of 500ms after the first increment and before continous increments
1 parent 720e9d3 commit d91cd61

File tree

2 files changed

+50
-72
lines changed

2 files changed

+50
-72
lines changed

demos/spinner/currency.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
$(function() {
1919
$("#currency").change(function() {
2020
var current = $("#spinner").spinner("value");
21-
console.log("before!!", current)
2221
Globalization.preferCulture($(this).val());
2322
$("#spinner").spinner("value", current);
2423
})

ui/jquery.ui.spinner.js

Lines changed: 50 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,14 @@ $.widget('ui.spinner', {
2727
},
2828

2929
_create: function() {
30-
// html5 attributes initalization
31-
// TODO refactor
30+
this._draw();
31+
this._markupOptions();
32+
this._mousewheel();
33+
this._aria();
34+
},
35+
36+
_markupOptions: function() {
37+
// TODO refactor and read only when the related option is null (set default to null, init Number.MAX_VALUE only when nothing is specified)
3238
var min = this.element.attr("min");
3339
if (typeof min == "string" && min.length > 0) {
3440
this.options.min = this._parse(min);
@@ -42,9 +48,6 @@ $.widget('ui.spinner', {
4248
this.options.step = this._parse(step);
4349
}
4450
this.value(this.options.value !== null ? this.options.value : this.element.val() || 0);
45-
this._draw();
46-
this._mousewheel();
47-
this._aria();
4851
},
4952

5053
_draw: function() {
@@ -69,7 +72,7 @@ $.widget('ui.spinner', {
6972
self.hovered = false;
7073
});
7174

72-
// TODO: need a better way to exclude IE8 without resorting to $.browser.version
75+
// TODO: move to theme, ask FG how
7376
// fix inline-block issues for IE. Since IE8 supports inline-block we need to exclude it.
7477
if (!$.support.opacity && uiSpinner.css('display') == 'inline-block' && $.browser.version < 8) {
7578
uiSpinner.css('display', 'inline');
@@ -110,12 +113,7 @@ $.widget('ui.spinner', {
110113
this.buttons = uiSpinner.find('.ui-spinner-button')
111114
.attr("tabIndex", -1)
112115
.button()
113-
.first()
114-
.removeClass("ui-corner-all")
115-
.end()
116-
.last()
117-
.removeClass("ui-corner-all")
118-
.end()
116+
.removeClass("ui-corner-all")
119117
.bind('mousedown', function(event) {
120118
if (self.options.disabled) {
121119
return;
@@ -129,9 +127,6 @@ $.widget('ui.spinner', {
129127
if (self.options.disabled) {
130128
return;
131129
}
132-
if (self.counter == 1) {
133-
self._spin(($(this).hasClass('ui-spinner-up') ? 1 : -1) * self.options.step, event);
134-
}
135130
if (self.spinning) {
136131
self._stop(event);
137132
self._change(event);
@@ -150,7 +145,7 @@ $.widget('ui.spinner', {
150145
}
151146
})
152147
.bind("mouseleave", function() {
153-
if (self.timer && self.spinning) {
148+
if (self.spinning) {
154149
self._stop(event);
155150
self._change(event);
156151
}
@@ -197,11 +192,9 @@ $.widget('ui.spinner', {
197192
return false;
198193
}
199194
self._spin((delta > 0 ? 1 : -1) * self.options.step, event);
200-
if (self.timeout) {
201-
window.clearTimeout(self.timeout);
202-
}
195+
clearTimeout(self.timeout);
203196
// TODO can we implement that without a timeout?
204-
self.timeout = window.setTimeout(function() {
197+
self.timeout = setTimeout(function() {
205198
if (self.spinning) {
206199
self._stop(event);
207200
self._change(event);
@@ -231,34 +224,33 @@ $.widget('ui.spinner', {
231224
return false;
232225
},
233226

234-
// TODO tune repeat behaviour, see http://jsbin.com/aruki4/2 for reference
235227
_repeat: function(i, steps, event) {
236228
var self = this;
237-
i = i || 100;
229+
i = i || 500;
238230

239-
if (this.timer) {
240-
window.clearTimeout(this.timer);
241-
}
242-
243-
this.timer = window.setTimeout(function() {
244-
self._repeat(self.options.incremental && self.counter > 20 ? 20 : i, steps, event);
231+
clearTimeout(this.timer);
232+
this.timer = setTimeout(function() {
233+
self._repeat(40, steps, event);
245234
}, i);
246235

247-
self._spin(steps*self.options.step, event);
236+
self._spin(steps * self.options.step, event);
248237
},
249238

250239
_spin: function(step, event) {
251240
if (!this.counter) {
252241
this.counter = 1;
253242
}
254243

255-
var newVal = this.options.value + step * (this.options.incremental && this.counter > 100
256-
? this.counter > 200
257-
? 100
258-
: 10
259-
: 1);
244+
// TODO refactor, maybe figure out some non-linear math
245+
var newVal = this.options.value + step * (this.options.incremental &&
246+
this.counter > 20
247+
? this.counter > 100
248+
? this.counter > 200
249+
? 100
250+
: 10
251+
: 2
252+
: 1);
260253

261-
// cancelable
262254
if (this._trigger('spin', event, { value: newVal }) !== false) {
263255
this.value(newVal);
264256
this.counter++;
@@ -288,28 +280,32 @@ $.widget('ui.spinner', {
288280
if (value > this.options.max) {
289281
value = this.options.max;
290282
}
291-
}
283+
}
284+
if (key == 'disabled') {
285+
if (value) {
286+
this.element.attr("disabled", true);
287+
this.buttons.button("disable");
288+
} else {
289+
this.element.removeAttr("disabled");
290+
this.buttons.button("enable");
291+
}
292+
}
292293
$.Widget.prototype._setOption.call( this, key, value );
293-
this._afterSetData(key, value);
294294
},
295295

296-
_afterSetData: function(key, value) {
297-
switch(key) {
298-
case 'value':
299-
this._format(this.options.value);
300-
case 'max':
301-
case 'min':
302-
case 'step':
303-
this._aria();
296+
_setOptions: function( options ) {
297+
$.Widget.prototype._setOptions.call( this, options );
298+
if ( "value" in options ) {
299+
this._format( this.options.value );
304300
}
301+
this._aria();
305302
},
306303

307304
_aria: function() {
308-
// TODO remove check, as soon as this method doesn't get called anymore before uiSpinner is initalized
309-
this.uiSpinner && this.uiSpinner
310-
.attr('aria-valuemin', this.options.min)
311-
.attr('aria-valuemax', this.options.max)
312-
.attr('aria-valuenow', this.options.value);
305+
this.uiSpinner
306+
.attr('aria-valuemin', this.options.min)
307+
.attr('aria-valuemax', this.options.max)
308+
.attr('aria-valuenow', this.options.value);
313309
},
314310

315311
_parse: function(val) {
@@ -327,6 +323,7 @@ $.widget('ui.spinner', {
327323
},
328324

329325
_format: function(num) {
326+
var num = this.options.value;
330327
this.element.val( window.Globalization && this.options.numberformat ? Globalization.format(num, this.options.numberformat) : num );
331328
},
332329

@@ -339,30 +336,12 @@ $.widget('ui.spinner', {
339336
this.uiSpinner.replaceWith(this.element);
340337
},
341338

342-
enable: function() {
343-
this.element
344-
.removeAttr('disabled')
345-
.parent()
346-
.removeClass('ui-spinner-disabled ui-state-disabled');
347-
this.options.disabled = false;
348-
this.buttons.button("enable");
349-
},
350-
351-
disable: function() {
352-
this.element
353-
.attr('disabled', true)
354-
.parent()
355-
.addClass('ui-spinner-disabled ui-state-disabled');
356-
this.options.disabled = true;
357-
this.buttons.button("disable");
358-
},
359-
360339
stepUp: function(steps) {
361-
this._spin((steps || 1) * this.options.step, null);
340+
this._spin((steps || 1) * this.options.step);
362341
},
363342

364343
stepDown: function(steps) {
365-
this._spin((steps || 1) * -this.options.step, null);
344+
this._spin((steps || 1) * -this.options.step);
366345
},
367346

368347
pageUp: function(pages) {
@@ -377,7 +356,7 @@ $.widget('ui.spinner', {
377356
if (!arguments.length) {
378357
return this.options.value;
379358
}
380-
this._setOption('value', newVal);
359+
this.option('value', newVal);
381360
},
382361

383362
widget: function() {

0 commit comments

Comments
 (0)