Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 700
proximus Avatar asked Nov 21 '11 12:11

proximus


2 Answers

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);
    });

});
like image 85
Philippe Avatar answered Nov 06 '22 15:11

Philippe


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);
                }
            }
        });
    }
);
like image 29
Richard Ayotte Avatar answered Nov 06 '22 17:11

Richard Ayotte