Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
70
Disable mouse wheel scroll event for active Datepicker and IgxInput
posted

How to disable incrementing/decrementing the value of active Datepicker and IgxInput number field when user has mouse on the active input and starts scrolling with mouse?

  • 460
    Offline posted

    Hello,

    I have been looking into your question and your requirements can be achieved.

    First about the input field with the igxInput directive, what you can do is to handle the wheel event of the input field and when scrolling to prevent the event with the preventDefault method.

    <igx-input-group>
            <input igxInput name="number" type="number" (wheel)="wheel($event)"/>
            <label igxLabel for="number">Number</label>
      </igx-input-group>

    public wheel(event){
            event.preventDefault();
    }

    Second about the igx-date-picker component since its input is inside the component itself and cannot be accessed so as to handle the wheel event what can be done is after rendering the application in the ngAfterViewInit lifecycle hook to access the wheel itself input field using the getElementsByClassName method and passing the input class .igx-date-picker__input-date.

    public ngAfterViewInit(): void {
         let datePickerInput = document.getElementsByClassName("igx-date-picker__input-date")[0];
    }

    After we already have the input, we can add an event listener to it with the addEventListener method, which will listen for the wheel event of the input of the igx-date-picker component. After the given event is fired we can prevent it with the blur method to stop scrolling in the input field.

    datePickerInput.addEventListener("wheel", function(event){
                 this.blur();
    });

    However, this is not all that needs to be done to prevent scrolling, as an event is fired on scrolling that will cause the date to be incremented or decremented by at least one value. To prevent this scenario as well, we will create an additional variable to hold the date before scrolling.

    public date = new Date();
    public originalDate = this.date;

    After that, in the event listener for scrolling after the given event is triggered, we will set the original date that was before scrolling. This will be done with the select method of the igx-date-picker component, as in order to access it we will create a reference to the component and in the ngAfterViewInit lifecycle hook itself we must also add a reference to this keyword.

      public ngAfterViewInit(): void {
             let _this = this;
    
             let datePickerInput = document.getElementsByClassName("igx-date-picker__input-date")[0];
    
             datePickerInput.addEventListener("wheel", function(event){
                 this.blur();
                 _this.datePicker.select(_this.originalDate);
             });
    }

    However, there is one more scenario that needs to be handled, since when scrolling the datе is changed and we return it to the old one to prevent the change, the valueChange event of the igx-date-picker component must also be handled too. To begin with, a boolean flag will be added to indicate when we have changed the value of the igx-date-picker, either when scrolling or through the drop-down that expands the calendar.

    public isOpened = false;

    The opened and closed events of the igx-date-picker component will also be handled, that is, when a drop-down is opened, the flag will be set to true, and when it is closed, the flag will be set to false to specify whether we have changed the date when scrolling or when the drop-down is open. After that, in the fire of the valueChange event, we will get the new date only when it changes from the drop-down, that is, when the drop-down is open, and when the date changes and the drop-down is closed, that is, then we have a scroll.

    <igx-date-picker #picker [(ngModel)]="date" (opened)="handleOpened($event)" (closed)="handleClosed($event)" (valueChange)="valueChange($event)" >
             <label igxLabel>Date</label>
    </igx-date-picker>

    public handleOpened(event){
             this.isOpened = true;
         }
         
         public handleClosed(event){
             this.isOpened = false;
         }
    
         public valueChange(event){
             if(this.isOpened){
                 this.originalDate = event;
             }
         }

    The described scenario could be observed here where I scroll in both components but as you can see nothing happens:

     

    In addition, I have prepared small sample illustrating this behavior which could be found here. Please test it on your side and let me know how it behaves.

    Thank you for your cooperation.

    Regards,

    Georgi Anastasov

    Entry Level Software Developer

    Infragistics