How to disable mousewheel events on dijit.form.NumberSpinner widgets?
Asked Answered
N

2

5

I'm using some dijit.form.NumberSpinner widgets in my dojo-based application, all of them are connected to onChange actions.

A problem occurs when one has an area with lots of NumberSpinners: Users scroll across the page and accidentally fill the NumberSpinner fields with unintended values while scrolling with the mousewheel all over the area.

Is it somehow possible to disable mousewheel events on dijit.form.NumberSpinner widgets?

Negate answered 21/11, 2011 at 12:51 Comment(0)
A
6

If you never need it, and if you have access to the dojo sources and are able to do your own builds, comment this line on dijit/form/_Spinner.js :

postCreate: function(){
    // [...]
    // this.connect(this.domNode, !has("mozilla") ? "onmousewheel" : 'DOMMouseScroll', "_mouseWheeled");
    // [...]
}

Alternatively, you can set the intermediateChanges property to true on your widget, and do something like this :

In your html :

<input id="spinner1" name="someNumber" data-dojo-type="dijit.form.NumberSpinner" data-dojo-props="value:'1000',smallDelta:'10',constraints:{min:9,max:1550,places:0}, intermediateChanges:'true'"/>

In your javascript block :

dojo.ready(function(){
    var spinner = dijit.byId("spinner1");
    var currentValue = spinner.get('value');
    dojo.connect(spinner, "onChange", function(value){
        currentValue = value;
    });
    dojo.connect(spinner.domNode, (!dojo.isMozilla ? "onmousewheel" : "DOMMouseScroll"), function(e){
        spinner.set('value',currentValue);
    });

});
Amatruda answered 21/11, 2011 at 17:12 Comment(1)
customizing the sources as you described and making an own build perfectly worked out for me, thx. ;-)Negate
G
1

A quick and dirty way to have the mousewheel only work when the widget has focus is to add if (!this.focused) return; to the top of _mouseWheeled in dijit/form/_Spinner.js.

_mouseWheeled: function(/*Event*/ evt){
    // summary:
    //      Mouse wheel listener where supported
    if (!this.focused) return;
    ...

The proper way though would be to extend the widget.

// Disable _mouseWheeled when not in focus.
require(
    [
        "dojo/_base/lang"
        , "dojo/_base/event"
        , "dijit/form/_Spinner"
    ]
    , function(
        lang
        , event
        , _Spinner
    ){
        lang.extend(_Spinner, {
            _mouseWheeled: function(/*Event*/ evt){
                // summary:
                //      Mouse wheel listener where supported

                if (!this.focused) return;

                event.stop(evt);
                // FIXME: Safari bubbles

                // be nice to DOH and scroll as much as the event says to
                var wheelDelta = evt.wheelDelta / 120;
                if(Math.floor(wheelDelta) != wheelDelta){
                    // If not an int multiple of 120, then its touchpad scrolling.
                    // This can change very fast so just assume 1 wheel click to make it more manageable.
                    wheelDelta = evt.wheelDelta > 0 ? 1 : -1;
                }
                var scrollAmount = evt.detail ? (evt.detail * -1) : wheelDelta;
                if(scrollAmount !== 0){
                    var node = this[(scrollAmount > 0 ? "upArrowNode" : "downArrowNode" )];

                    this._arrowPressed(node, scrollAmount, this.smallDelta);

                    if(!this._wheelTimer){
                        clearTimeout(this._wheelTimer);
                    }
                    this._wheelTimer = setTimeout(lang.hitch(this,"_arrowReleased",node), 50);
                }
            }
        });
    }
);
Gastronome answered 25/6, 2012 at 15:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.