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

Column menu positioning bug in a 'horizontal scrolled'-grid in Firefox #5396

Closed
DaAitch opened this issue May 11, 2016 · 3 comments
Closed

Comments

@DaAitch
Copy link

DaAitch commented May 11, 2016

Reproduce:

  • open this plunkr in latest firefox (just googled for any plunkr with latest ui-grid and many columns in it)
  • scroll grid to the very right
  • open column menu
  • see, that the menu is left aligned in the grid viewport (and working in latest Chrome and IE)

ui-grid-scroll-bug

Analysis:
In ui-grid there is a uiGridColumnMenuService::getColumnElementPosition-Method, returning a to chrome different value of positionData.parentLeft which is zero in Firefox.

Possible Conclusion:
Firefox is using a different implementation of offsetParent?

Quick-(dirty)-fix:

  getColumnElementPosition: function( $scope, column, $columnElement ){
      var positionData = {};
      positionData.left = $columnElement[0].offsetLeft;
      positionData.top = $columnElement[0].offsetTop;
      positionData.parentLeft = $columnElement[0].offsetParent.offsetLeft;

      // chrome
      var domColumnElementOffsetParent = $columnElement[0].offsetParent;

      // firefox
      if(!angular.element(domColumnElementOffsetParent).hasClass('ui-grid-header-cell-wrapper')) {
        domColumnElementOffsetParent = domColumnElementOffsetParent.offsetParent;
      }
      positionData.parentLeft = domColumnElementOffsetParent.offsetLeft;

      // Get the grid scrollLeft
      positionData.offset = 0;
      if (column.grid.options.offsetLeft) {
        positionData.offset = column.grid.options.offsetLeft;
      }

      positionData.height = gridUtil.elementHeight($columnElement, true);
      positionData.width = gridUtil.elementWidth($columnElement, true);

      return positionData;
    },

As this is just a hack, I'm no going to provide a pull-request for this.

@andresbiso
Copy link

andresbiso commented May 24, 2016

Thanks @PhilippHToner!

Your quick-dirty-fix fixed my problem.

Here is how I use it (this way you don't have to change the ui-grid source code);

  • Create a ui-grid-menu-decorator.js
'use strict';
angular
  .module('app.core')
  .config(uiGridColumnMenuConfig);

uiGridColumnMenuConfig.$inject = ['$provide'];

function uiGridColumnMenuConfig($provide) {
  $provide.decorator('uiGridColumnMenuService', extendUiGridColumnMenuService);
}

extendUiGridColumnMenuService.$inject = ['$delegate', 'gridUtil'];

function extendUiGridColumnMenuService($delegate, gridUtil) {

  // wrap and overwrite uiGridColumnMenuService object methods
  /* jshint ignore:start */
  var getDirection;
  getDirection = $delegate.getColumnElementPosition;
  /* jshint ignore:end */

  $delegate.getColumnElementPosition = function ($scope, column, $columnElement) {
      var positionData, domColumnElementOffsetParent;
      positionData = {};
      positionData.left = $columnElement[0].offsetLeft;
      positionData.top = $columnElement[0].offsetTop;
      positionData.parentLeft = $columnElement[0].offsetParent.offsetLeft;

      // chrome
      domColumnElementOffsetParent = $columnElement[0].offsetParent;

      // firefox
      if (!angular.element(domColumnElementOffsetParent).hasClass('ui-grid-header-cell-wrapper')) {
        domColumnElementOffsetParent = domColumnElementOffsetParent.offsetParent;
      }
      positionData.parentLeft = domColumnElementOffsetParent.offsetLeft;

      // Get the grid scrollLeft
      positionData.offset = 0;
      if (column.grid.options.offsetLeft) {
        positionData.offset = column.grid.options.offsetLeft;
      }

      positionData.height = gridUtil.elementHeight($columnElement, true);
      positionData.width = gridUtil.elementWidth($columnElement, true);

      return positionData;
    };

  return $delegate;
}
  • Remember to include it in your index.html

<script src="app/core/core-decorators/ui-grid-menu-decorator.js"></script>

@caseyjhol
Copy link
Contributor

caseyjhol commented Mar 6, 2018

Firefox appears to be implementing offsetParent correctly, while IE and Chrome are not. It's supposed to return the nearest positioned element. In this case, it's actually .ui-grid-header-cell-row which has position: relative and an offsetLeft of 0. Chrome and IE return .ui-grid-header-cell-wrapper as the offsetParent, which is incorrect.

It looks like if an element has display: table-row, Chrome and IE are ignoring it as being positioned. See the console: https://jsfiddle.net/caseyjhol/q0wdegas/6/.

caseyjhol added a commit to snapappointments/ui-grid that referenced this issue Mar 8, 2018
Menu width calculation was removed in angular-ui#6588. Menu width needs to be
calculated in order to properly position the menu (if there is not
enough room to the left of the column). repositionMenu is now always
called in the 'menu-shown' event listener to ensure the width can be
properly calculated. The style attribute is removed from $elm in the
'menu-hidden' event listener to prevent the menu from appearing to slide
from the left or right when opening another column menu while one is
already open.

Menu animation speed was changed in angular-ui#6588 to have different add/remove
speeds. 0.04s has been chosen as a happy medium, and the $timeout
duration has been changed to reflect the new transition duration (to
reduce delay when hiding the menu).

`position: relative` has been removed from .ui-grid-header-cell-row to
ensure consistent calculation of offsetParent across browsers.

Fixes angular-ui#5396, angular-ui#5990, angular-ui#6085.
caseyjhol added a commit to snapappointments/ui-grid that referenced this issue Mar 8, 2018
Menu width calculation was removed in angular-ui#6588. Menu width needs to be
calculated in order to properly position the menu (if there is not
enough room to the left of the column). repositionMenu is now always
called in the 'menu-shown' event listener to ensure the width can be
properly calculated. The style attribute is removed from $elm in the
'menu-hidden' event listener to prevent the menu from appearing to slide
from the left or right when opening another column menu while one is
already open.

Menu animation speed was changed in angular-ui#6588 to have different add/remove
speeds. 0.04s has been chosen as a happy medium, and the $timeout
duration has been changed to reflect the new transition duration (to
reduce delay when hiding the menu).

`position: relative` has been removed from .ui-grid-header-cell-row to
ensure consistent calculation of offsetParent across browsers.

Fixes angular-ui#5396, angular-ui#5990, angular-ui#6085.
mportuga pushed a commit that referenced this issue Mar 11, 2018
Menu width calculation was removed in #6588. Menu width needs to be
calculated in order to properly position the menu (if there is not
enough room to the left of the column). repositionMenu is now always
called in the 'menu-shown' event listener to ensure the width can be
properly calculated. The style attribute is removed from $elm in the
'menu-hidden' event listener to prevent the menu from appearing to slide
from the left or right when opening another column menu while one is
already open.

Menu animation speed was changed in #6588 to have different add/remove
speeds. 0.04s has been chosen as a happy medium, and the $timeout
duration has been changed to reflect the new transition duration (to
reduce delay when hiding the menu).

`position: relative` has been removed from .ui-grid-header-cell-row to
ensure consistent calculation of offsetParent across browsers.

Fixes #5396, #5990, #6085.
@msp444
Copy link

msp444 commented Apr 19, 2019

Thank you andresbiso for your comment. This problem still existed for us in Firefox. I was able to implement your fix with 1 minor tweak: I had to change the module reference to 'ui.grid'

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

No branches or pull requests

4 participants