Skip to content

Commit

Permalink
feat(RTL): Adding RTL support and fixing virtualization
Browse files Browse the repository at this point in the history
  • Loading branch information
c0bra committed Aug 7, 2014
1 parent d062ed5 commit d5a9982
Show file tree
Hide file tree
Showing 9 changed files with 180 additions and 59 deletions.
18 changes: 15 additions & 3 deletions misc/tutorial/299_RTL.ngdoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,21 @@ The grid supports RTL languages
app.controller('MainCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.gridOptions = {
columnDefs: [
{ field: 'name', width: 200 },
{ field: 'gender', width: 200 },
{ field: 'company', width: 200 }
{ name: 'field1', field: 'name', width: 200 },
{ name: 'field2', field: 'gender', width: 200 },
{ name: 'field3', field: 'company', width: 200 },
{ name: 'field4', field: 'name', width: 200 },
{ name: 'field5', field: 'gender', width: 200 },
{ name: 'field6', field: 'company', width: 200 },
{ name: 'field7', field: 'name', width: 200 },
{ name: 'field8', field: 'gender', width: 200 },
{ name: 'field9', field: 'company', width: 200 },
{ name: 'field10', field: 'name', width: 200 },
{ name: 'field11', field: 'gender', width: 200 },
{ name: 'field12', field: 'company', width: 200 },
{ name: 'field13', field: 'name', width: 200 },
{ name: 'field14', field: 'gender', width: 200 },
{ name: 'field15', field: 'company', width: 200 }
]
};

Expand Down
10 changes: 5 additions & 5 deletions src/js/core/directives/ui-grid-native-scrollbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
rowContainer.horizontalScrollbarHeight = scrollBarWidth;

// Save the initial scroll position for use in scroll events
previousScrollPosition = $elm[0].scrollLeft;
previousScrollPosition = gridUtil.normalizeScrollLeft($elm);
}

// Save the contents elm inside the scrollbar elm so it sizes correctly
Expand Down Expand Up @@ -154,15 +154,14 @@
previousScrollPosition = newScrollTop;
}
else if ($scope.type === 'horizontal') {
var newScrollLeft = $elm[0].scrollLeft;
// var newScrollLeft = $elm[0].scrollLeft;
var newScrollLeft = gridUtil.normalizeScrollLeft($elm);

var xDiff = previousScrollPosition - newScrollLeft;

var horizScrollLength = (colContainer.getCanvasWidth() - colContainer.getViewportWidth());
var horizScrollPercentage = newScrollLeft / horizScrollLength;

$log.debug('horizScrollPercentage', horizScrollPercentage);

var xArgs = {
target: $elm,
x: {
Expand Down Expand Up @@ -213,7 +212,8 @@

var newScrollLeft = Math.max(0, args.x.percentage * horizScrollLength);

$elm[0].scrollLeft = newScrollLeft;
// $elm[0].scrollLeft = newScrollLeft;
$elm[0].scrollLeft = gridUtil.denormalizeScrollLeft($elm, newScrollLeft);
}
}
}
Expand Down
27 changes: 21 additions & 6 deletions src/js/core/directives/ui-grid-render-container.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@

var scrollWidth = (colContainer.getCanvasWidth() - colContainer.getViewportWidth());

var oldScrollLeft = containerCtrl.viewport[0].scrollLeft;
// var oldScrollLeft = containerCtrl.viewport[0].scrollLeft;
var oldScrollLeft = GridUtil.normalizeScrollLeft(containerCtrl.viewport);

var scrollXPercentage;
if (typeof(args.x.percentage) !== 'undefined' && args.x.percentage !== undefined) {
Expand All @@ -128,11 +129,14 @@

// uiGridCtrl.adjustScrollHorizontal(newScrollLeft, scrollXPercentage);

containerCtrl.viewport[0].scrollLeft = newScrollLeft;
// containerCtrl.viewport[0].scrollLeft = newScrollLeft;
containerCtrl.viewport[0].scrollLeft = GridUtil.denormalizeScrollLeft(containerCtrl.viewport, newScrollLeft);

containerCtrl.prevScrollLeft = newScrollLeft;

if (containerCtrl.headerViewport) {
containerCtrl.headerViewport.scrollLeft = newScrollLeft;
// containerCtrl.headerViewport.scrollLeft = newScrollLeft;
containerCtrl.headerViewport.scrollLeft = GridUtil.denormalizeScrollLeft(containerCtrl.headerViewport, newScrollLeft);
}

// uiGridCtrl.grid.options.offsetLeft = newScrollLeft;
Expand Down Expand Up @@ -165,7 +169,8 @@
var scrollXAmount = newEvent.deltaX * -120;

// Get the scroll percentage
var scrollXPercentage = (containerCtrl.viewport[0].scrollLeft + scrollXAmount) / (colContainer.getCanvasWidth() - colContainer.getViewportWidth());
var scrollLeft = GridUtil.normalizeScrollLeft(containerCtrl.viewport);
var scrollXPercentage = (scrollLeft + scrollXAmount) / (colContainer.getCanvasWidth() - colContainer.getViewportWidth());

// Keep scrollPercentage within the range 0-1.
if (scrollXPercentage < 0) { scrollXPercentage = 0; }
Expand Down Expand Up @@ -229,7 +234,12 @@
}

if (!$scope.disableColumnOffset && $scope.colContainer.currentFirstColumn !== 0) {
styles['margin-left'] = $scope.colContainer.columnOffset + 'px';
if ($scope.grid.isRTL()) {
styles['margin-right'] = $scope.colContainer.columnOffset + 'px';
}
else {
styles['margin-left'] = $scope.colContainer.columnOffset + 'px';
}
}

return styles;
Expand All @@ -242,7 +252,12 @@
if (index === 0 && $scope.colContainer.currentFirstColumn !== 0) {
var offset = $scope.colContainer.columnOffset;

return { 'margin-left': offset + 'px' };
if ($scope.grid.isRTL()) {
return { 'margin-right': offset + 'px' };
}
else {
return { 'margin-left': offset + 'px' };
}
}
}

Expand Down
9 changes: 6 additions & 3 deletions src/js/core/directives/ui-grid-viewport.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
(function(){
'use strict';

angular.module('ui.grid').directive('uiGridViewport', ['$log',
function($log) {
angular.module('ui.grid').directive('uiGridViewport', ['$log', 'gridUtil',
function($log, gridUtil) {
return {
replace: true,
scope: {},
Expand Down Expand Up @@ -30,7 +30,10 @@

$elm.on('scroll', function (evt) {
var newScrollTop = $elm[0].scrollTop;
var newScrollLeft = $elm[0].scrollLeft;
// var newScrollLeft = $elm[0].scrollLeft;
var newScrollLeft = gridUtil.normalizeScrollLeft($elm);

// Handle RTL here

if (newScrollLeft !== colContainer.prevScrollLeft) {
var xDiff = newScrollLeft - colContainer.prevScrollLeft;
Expand Down
6 changes: 5 additions & 1 deletion src/js/core/directives/ui-grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -242,9 +242,13 @@
$scope.$broadcast(eventName, args);
};

self.innerCompile = function (elm) {
self.innerCompile = function innerCompile(elm) {
$compile(elm)($scope);
};

$scope.grid.isRTL = self.isRTL = function isRTL() {
return $elm.css('direction') === 'rtl';
};
}]);

/**
Expand Down
2 changes: 1 addition & 1 deletion src/js/core/factories/Grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -957,7 +957,7 @@ angular.module('ui.grid')
return self.cellValueGetterCache[col.colDef.name](row);
};

// Reset all sorting on the grid

Grid.prototype.getNextColumnSortPriority = function getNextColumnSortPriority() {
var self = this,
p = 0;
Expand Down
14 changes: 12 additions & 2 deletions src/js/core/factories/GridRenderContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,12 @@ angular.module('ui.grid')
}

if (self.currentFirstColumn !== 0) {
styles['margin-left'] = self.columnOffset + 'px';
if (self.grid.isRTL()) {
styles['margin-right'] = self.columnOffset + 'px';
}
else {
styles['margin-left'] = self.columnOffset + 'px';
}
}

return styles;
Expand All @@ -407,7 +412,12 @@ angular.module('ui.grid')
if (index === 0 && self.currentFirstColumn !== 0) {
var offset = self.columnOffset;

return { 'margin-left': offset + 'px' };
if (self.grid.isRTL()) {
return { 'margin-right': offset + 'px' };
}
else {
return { 'margin-left': offset + 'px' };
}
}

return null;
Expand Down
115 changes: 115 additions & 0 deletions src/js/core/services/ui-grid-util.js
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,121 @@ module.service('gridUtil', ['$log', '$window', '$document', '$http', '$templateC
}
};

// http://stackoverflow.com/a/22948274/888165
// TODO: Opera? Mobile?
s.detectBrowser = function detectBrowser() {
var userAgent = $window.navigator.userAgent;

var browsers = {chrome: /chrome/i, safari: /safari/i, firefox: /firefox/i, ie: /internet explorer/i};

for (var key in browsers) {
if (browsers[key].test(userAgent)) {
return key;
}
}

return 'unknown';
};

/**
* @ngdoc method
* @name normalizeScrollLeft
* @methodOf ui.grid.service:GridUtil
*
* @param {element} element The element to get the `scrollLeft` from.
*
* @returns {int} A normalized scrollLeft value for the current browser.
*
* @description
* Browsers currently handle RTL in different ways, resulting in inconsistent scrollLeft values. This method normalizes them
*/
s.normalizeScrollLeft = function normalizeScrollLeft(element) {
if (typeof(element.length) !== 'undefined' && element.length) {
element = element[0];
}

var browser = s.detectBrowser();

var scrollLeft = element.scrollLeft;

var dir = angular.element(element).css('direction');

// IE stays normal in RTL
if (browser === 'ie') {
return scrollLeft;
}
// Chrome doesn't alter the scrollLeft value. So with RTL on a 400px-wide grid, the right-most position will still be 400 and the left-most will still be 0;
else if (browser === 'chrome') {
if (dir === 'rtl') {
// Get the max scroll for the element
var maxScrollLeft = element.scrollWidth - element.clientWidth;

// Subtract the current scroll amount from the max scroll
return maxScrollLeft - scrollLeft;
}
else {
return scrollLeft;
}
}
// Firefox goes negative!
else if (browser === 'firefox') {
return Math.abs(scrollLeft);
}
else {
// TODO(c0bra): Handle other browsers? Android? iOS? Opera?
return scrollLeft;
}
};

/**
* @ngdoc method
* @name normalizeScrollLeft
* @methodOf ui.grid.service:GridUtil
*
* @param {element} element The element to normalize the `scrollLeft` value for
* @param {int} scrollLeft The `scrollLeft` value to denormalize.
*
* @returns {int} A normalized scrollLeft value for the current browser.
*
* @description
* Browsers currently handle RTL in different ways, resulting in inconsistent scrollLeft values. This method denormalizes a value for the current browser.
*/
s.denormalizeScrollLeft = function denormalizeScrollLeft(element, scrollLeft) {
if (typeof(element.length) !== 'undefined' && element.length) {
element = element[0];
}

var browser = s.detectBrowser();

var dir = angular.element(element).css('direction');

// IE stays normal in RTL
if (browser === 'ie') {
return scrollLeft;
}
// Chrome doesn't alter the scrollLeft value. So with RTL on a 400px-wide grid, the right-most position will still be 400 and the left-most will still be 0;
else if (browser === 'chrome') {
if (dir === 'rtl') {
// Get the max scroll for the element
var maxScrollLeft = element.scrollWidth - element.clientWidth;

// Subtract the current scroll amount from the max scroll
return maxScrollLeft - scrollLeft;
}
else {
return scrollLeft;
}
}
// Firefox goes negative!
else if (browser === 'firefox') {
return scrollLeft * -1;
}
else {
// TODO(c0bra): Handle other browsers? Android? iOS? Opera?
return scrollLeft;
}
};

return s;
}]);

Expand Down
38 changes: 0 additions & 38 deletions src/templates/ui-grid/ui-grid.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,6 @@
/* Styles for the grid */
}

/*.grid{{ grid.id }} .ui-grid-header {
width: {{ grid.getHeaderViewportWidth() }}px;
}*/

/*.grid{{ grid.id }} .ui-grid-header-canvas {
width: {{ grid.getCanvasWidth() }}px;
}*/

/*.grid{{ grid.id }} .ui-grid-body {
height: {{ grid.getBodyHeight() }}px;
}

.grid{{ grid.id }} .ui-grid-viewport {
height: {{ grid.getViewportHeight() }}px;
width: {{ grid.getViewportWidth() }}px;
}

.grid{{ grid.id }} .ui-grid-canvas {
height: {{ grid.getCanvasHeight() }}px;
width: {{ grid.getCanvasWidth() }}px;
}*/

.grid{{ grid.id }} .ui-grid-row, .grid{{ grid.id }} .ui-grid-cell, .grid{{ grid.id }} .ui-grid-cell .ui-grid-vertical-bar {
height: {{ grid.options.rowHeight }}px;
}
Expand All @@ -35,14 +13,6 @@
border-bottom-width: {{ ((grid.getTotalRowHeight() < grid.getViewportHeight()) && '1') || '0' }}px;
}

/*{{ rowStyles }}

{{ columnStyles }}*/

/*.grid{{ grid.id }} .ui-grid-body .ui-grid-cell:first-child, .grid{{ grid.id }} .ui-grid-header .ui-grid-header-cell:first-child {
margin-left: {{ grid.columnOffset || 0 }}px;
}*/

{{ grid.verticalScrollbarStyles }}
{{ grid.horizontalScrollbarStyles }}

Expand All @@ -60,14 +30,6 @@
{{ grid.customStyles }}
</style>

<!-- <div ui-grid-header></div>
<div ui-grid-body>
<div class="ui-grid-no-row-overlay" ng-show="!grid.renderedRows.length">
<span>No Rows</span>
</div>
</div> -->

<div ui-grid-render-container container-id="'body'" col-container-name="'body'" row-container-name="'body'" bind-scroll-horizontal="true" bind-scroll-vertical="true" enable-scrollbars="true"></div>

<div ui-grid-footer></div>
Expand Down

0 comments on commit d5a9982

Please sign in to comment.