Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When the mouse is on the grid, the container can't scroll #1926

Closed
calebkiage opened this issue Oct 27, 2014 · 69 comments
Closed

When the mouse is on the grid, the container can't scroll #1926

calebkiage opened this issue Oct 27, 2014 · 69 comments
Assignees
Milestone

Comments

@calebkiage
Copy link

Hello, I have disable grid scrolling but when the mouse pointer is in the grid, the container cannot scroll. Any ideas on how I can disable this behavior?

@calebkiage
Copy link
Author

So I had a look at the source code and found that there is an event binding on the uiGridRenderContainer directive (line 2337 on version v3.0.0-rc.12-6fa2e47) that causes this behavior.

$elm.bind('wheel mousewheel DomMouseScroll MozMousePixelScroll', function(evt) {
          // use wheelDeltaY
          evt.preventDefault();
          ...
});

Is there a reason why the grid needs to disable the browser's native scrolling? And if so, can I disable this?

@c0bra
Copy link
Contributor

c0bra commented Nov 3, 2014

Yes it needs to catch those events so it can virtualize properly. That's
the whole reason for the grid, basically.
On Nov 3, 2014 5:15 AM, "Caleb Kiage" notifications@github.com wrote:

So I had a look at the source code and found that there is an event
binding on the uiGridRenderContainer directive (line 2337 on version
v3.0.0-rc.12-6fa2e47) that causes this behavior.

$elm.bind('wheel mousewheel DomMouseScroll MozMousePixelScroll', function(evt) {
// use wheelDeltaY
evt.preventDefault();
...});

Is there a reason why the grid needs to disable the browser's native
scrolling? And if so, can I disable this?


Reply to this email directly or view it on GitHub
#1926 (comment).

@PaulL1 PaulL1 added this to the 3.0 milestone Nov 4, 2014
@calebkiage
Copy link
Author

Oh, thanks for the clarification. What I'm wondering about is why it has to call evt.preventDefault();. Most users find it very frustrating when the grid prevents them from scrolling the page especially when the grid takes the container's full width.

@mese79
Copy link

mese79 commented Nov 4, 2014

Yes, this is also my issue.

@dreftymac
Copy link

+1

@jraadt
Copy link

jraadt commented Nov 11, 2014

+1
This is frustrating especially on mobile where the table takes up the full width and height of the screen. You can't scroll to anything below the table.

@dshybeka
Copy link

+1

@jraadt
Copy link

jraadt commented Nov 12, 2014

In case it helps anyone, here's the code I added to fix this issue. It only prevents the page from scrolling when your mouse is in the grid and you haven't reached the top or bottom of the grid yet. I moved the evt.preventDefault() from here:

$elm.bind('wheel mousewheel DomMouseScroll MozMousePixelScroll', function(evt) {
          // use wheelDeltaY
          evt.preventDefault();
          ...
});

to:

            $elm.bind('wheel mousewheel DomMouseScroll MozMousePixelScroll', function(evt) {
              // use wheelDeltaY

              var newEvent = GridUtil.normalizeWheelEvent(evt);

              var args = { target: $elm };
              if (newEvent.deltaY !== 0) {
                var scrollYAmount = newEvent.deltaY * -120;

                // Get the scroll percentage
                var scrollYPercentage = (containerCtrl.viewport[0].scrollTop + scrollYAmount) / (rowContainer.getCanvasHeight() - rowContainer.getViewportHeight());

                if ((newEvent.deltaY == -1 && scrollYPercentage < 1) || (newEvent.deltaY == 1 && scrollYPercentage > 0)) {
                  evt.preventDefault();
                }
                ...

@c0bra
Copy link
Contributor

c0bra commented Dec 8, 2014

@jraadt Thanks for this. I'll take a look at implementing it. I'd be curious how it will affect scrolling within subgrids.

@ghost
Copy link

ghost commented Dec 22, 2014

+1

@PaulL1
Copy link
Contributor

PaulL1 commented Jan 14, 2015

I believe this is now resolved - could people verify?

@calebkiage
Copy link
Author

It seems that this has been partially fixed. When scrolling up, the page continues scrolling when the grid's scroller reaches the top which is good. But the same doesn't happen when the grid's scroller is at the bottom. See 102 Sorting
Also, I have noticed that grids don't have enough items to scroll still give issues with scrolling the page. See 101 Intro to UI-Grid

@PaulL1
Copy link
Contributor

PaulL1 commented Jan 15, 2015

Interesting. Grids with little data such as the 101 tut allow the page to scroll downwards, but not upwards. Grids with more data such as 102 sorting allow the page to scroll upwards (when reaching the end of the scroll), but not downwards.

@PaulL1
Copy link
Contributor

PaulL1 commented Jan 15, 2015

Thinking further on this, it could be the case that the grid decides whether to scroll itself or propagate to the parent based on how far through the grid scroll it currently is. If it's 100% and you scroll down, it propagates to the page. If you're at 0% and you scroll up, it propagates to the page.

So, when you have a grid with less than a page of data, it's always at 100% scroll. So it won't propagate the scroll up to the page. And currently we have a miscalculation on the vertical scroll so that when you reach the end of the data, you're not at 100% scroll. So when you have more than a page of data, currently you maybe cannot get to 100% so that it propagates the scroll down to the parent.

A theory at this stage, no more.

@joshmackey
Copy link
Contributor

I'm also getting this problem. I've set the grid to be as tall as needed. We don't want the grid to be scrolling, only the page as a whole. However, whenever the mouse is over the grid, it disabled the whole page scrolling even if the grid itself doesn't scroll any.

@PaulL1
Copy link
Contributor

PaulL1 commented Jan 16, 2015

OK, my theory on it not getting to 100% scroll is incorrect, it's a rendering glitch rather than a logic glitch. That is to say, the scroll bar on my Mac doesn't go all the way to the bottom, but if you look closely it's going all the way to the end of the scroll - perhaps it's leaving space for the horizontal to slide in underneath it?

I can resolve the scrolling on a grid with little data (no scrollbars) by commenting out the preventDefault in ui-grid-render-container.js (about line 156), and it appears to have no impact on anything else. With the larger grids with scrollbars, I can cause scrolling off the bottom if I "throw" it hard enough, so I still think there's some sort of calculation issue in there.

EDIT: it does have an ill-effect - it makes the scrolling "janky" - and so when you scroll using mousewheel quite fast, you get a bit of parent scroll as well as grid scroll. But I can fix the small datasets in another way, by checking scrollTop, in or about the same line of code.

But I still can't sort the scrolling off the bottom. It's not hitting the preventDefault, so that's not the cause of the issue. And if your mouse is over the header, then it does propagate (somewhat) to the page, but if over the body it doesn't. That's also weird.

On a crazy hunch, I looked at the pinning tutorial. If you have a pinned left and a pinned right, it propagates fine. If only a body, it doesn't. More accurately, it works if you scroll over the container without a scrollbar - so if you have a right container, then scrolling on body or left container will propagate. If you have no right container, then only scrolling on the left container will propagate.

I'm not sure I can fix this, as it's kinda weird. @swalters may have some ideas. But hopefully I've given some pointers to a diagnosis. I'll commit the change for small grids to scroll.

@Yipyipyip
Copy link

+1

@andreicocari
Copy link

I also had this problem. I managed to fix it by adding 'ui.grid.autoResize' to my module declaration. Hope it helps.
Cheers,
Andrei Co.

@shanet
Copy link

shanet commented Dec 11, 2015

I was unable to scroll down when pagination was enabled (although I could scroll up just fine). As a workaround, I added a directive to my table element based off of alejandromagnorsky's solution as follows:

  return {
    link: function(scope, element, attr) {
      scope.$watch('isDisplayed', function(newValue, oldValue) {
        var viewport = element.find('.ui-grid-render-container');

        ['touchstart', 'touchmove', 'touchend','keydown', 'wheel', 'mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'].forEach(function (eventName) {
          viewport.unbind(eventName);
        });
      });
    },
  };

Scrolling down appears to work now. This was with version 3.0.7.

@Kamaraju333
Copy link

I still has issue with 3.0.7 scroll doesnt work in chrome in Mac

@vittal288
Copy link

@shanet
Why you are unbinding the all events instead it should be bind rt.
Correct if I am wrong here...

@vittal288
Copy link

The above solution which has given by @shanet is working in my case...

Thank you so much @shanet

@nselvidge
Copy link

+1 on 3.1.1

@piyush-avantsoft
Copy link

Still it does not allow me to scroll till bottom of grid,
2nd issue is when I do scrolling upwards/downwards other row seems blinking or looks like removed for while, its not giving smooth scroll.

@dan2k3k4
Copy link

Which directive did you modify ? Or can I unbind the events inside the onRegisterApi function ?

@piyush-avantsoft
Copy link

piyush-avantsoft commented May 28, 2016

@calebkiage This issue doesn't seem resolved so it should not be closed.

@Yoav80
Copy link

Yoav80 commented Jun 2, 2016

+1 ,
i noticed that when i hide the grid headers the outer scroll starts working.. so i guess it has something to do with the calculations of the height of the header..

@boris-meerovich-sp
Copy link

+1
have the same issue in version 3.1.1

@stormcrow85
Copy link

+1
none of the above solutions helped in my case
version 3.1.1

@aviad-chen-sp
Copy link

+1

@ghost
Copy link

ghost commented Jun 15, 2016

@alejandromagnorsky Thank you. You’re so helpful.

@avim101
Copy link

avim101 commented Jun 16, 2016

this is my solution based on @alejandromagnorsky solution:
ui-grid - v3.1.1

(function () {
  'use strict';
  angular.module('myApp')
    .config(function ($provide) {
      $provide.decorator('Grid', function ($delegate,$timeout) {
        $delegate.prototype.renderingComplete = function(){
          if (angular.isFunction(this.options.onRegisterApi)) {
            this.options.onRegisterApi(this.api);
          }
          this.api.core.raise.renderingComplete( this.api );
          $timeout(function () {
           var $viewport =  $('.ui-grid-render-container');
            ['touchstart', 'touchmove', 'touchend','keydown', 'wheel', 'mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'].forEach(function (eventName) {
              $viewport.unbind(eventName);
            });
          }.bind(this));
        };
        return $delegate;
      });
    });

})();

that way i dont need to add watchers,directives and extra code for every grid i add.

@ericsvendsen
Copy link

I've tried unbinding the events as @avim101, @shanet, and @alejandromagnorsky suggested, but it simply doesn't work. Putting @avim101's example in my app config doesn't do it, and neither does just putting the forEach loop inside my controller. My grid is not in a directive. I can call $viewport.bind(eventName) and add whatever I want to the event listener, but it will not unbind. So frustrating.

I can comment out this line in the source and my grid scrolls perfectly, but of course I don't want to modify 3rd party source code.

Anyone have any suggestions or hints regarding placement of the unbind within a regular controller?

@avim101
Copy link

avim101 commented Jun 27, 2016

@ericsvendsen if you can add plunker / github repo we might help you to solve your problem

@ericsvendsen
Copy link

@avim101 right, my bad. I created a test repository that exhibits this behavior: https://github.com/ericsvendsen/grid-test.

I'm trying to unbind the events starting on line 209 of gridController.

As I say in the readme and in the test app, unbinding seems to work for trackpads, but I can't make it work for mouse scrollwheels. As long as the cursor is over the grid, the page won't scroll down (the side nav should be long enough unless you're using a 4K monitor). Thanks for offering to have a look.

@avim101
Copy link

avim101 commented Jun 28, 2016

@ericsvendsen
replace

 .ui-grid, .ui-grid-viewport {
     height: 100%!important;
 }

with

.ui-grid {
   .ui-grid-viewport {
     height: 100% !important;
   }
 }

and you need to calculate grid height dynamically:
http://stackoverflow.com/questions/27837335/angular-ui-grid-dynamically-calculate-height-of-the-grid

@ghost
Copy link

ghost commented Jul 14, 2016

@alejandromagnorsky solution worked for me. Thanks!

BTW, I execute the code every time the screen is resized.




Actually, I made a solution for my case in particular. In the link function of the directive that wraps the ui-grid I use:

$timeout(function () {
    var $viewport = $element.find('.ui-grid-render-container');
    ['touchstart', 'touchmove', 'touchend','keydown', 'wheel', 'mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'].forEach(function (eventName) {
        $viewport.unbind(eventName);
    });
);

@benjaminW78
Copy link

@avim101 your solution was perfectly clear and worked very well for me thank you ! 👍

@avim101
Copy link

avim101 commented Jul 18, 2016

@benjaminW78 glad it helped

@arefaydi
Copy link

arefaydi commented Aug 6, 2016

for 3.0.6 , I replaced the line on the ui-grid.js
var mouseWheeltoBind = ( 'onwheel' in document || document.documentMode >= 9 ) ? ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
with
var mouseWheeltoBind = [],

@javaScriptCodeer
Copy link

The ui-grid uses (3.1.1) an internal event ($destroy) to unbind all events.
So I just create an event $destroy in jQuery and trigger it. I do it within the onRegisterApi callback.

var callEventToUnbindMouseEventWhenScroll = function() {
$timeout(function() {
var e = jQuery.Event('$destroy');
var element = jQuery('.ui-grid-render-container');
if(element != null) {
jQuery('.ui-grid-render-container').trigger(e);
}
});
};

@TSkills
Copy link

TSkills commented Jan 9, 2017

Using 3.2.9, wheel works up and down when the grid has enableFiltering set to true.
If I don't want any column filter, but still want the wheel to work, I also set enableFiltering to false on each visible column.

@VincentBlouin
Copy link

VincentBlouin commented Mar 14, 2017

I included 'gridUtil' in my directive and I went gridUtil.on.mousewheel = function() {}; It works. I dont allow scrolling within the datatable anyway. Is this (temporary) solution ok? am I missing something? My problem would occur when I changed paginationSize.

@odravison
Copy link

The solution from @avim101 worked fine to me 👍 🎊
Thanks.

@hey24sheep
Copy link

+1

@classix-od
Copy link
Contributor

Maybe this would help someone later:

classix@6285e3f

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests