diff --git a/plugins/ng-grid-flexible-height.js b/plugins/ng-grid-flexible-height.js index b19bd23180..25b50f3005 100644 --- a/plugins/ng-grid-flexible-height.js +++ b/plugins/ng-grid-flexible-height.js @@ -2,7 +2,8 @@ function ngGridFlexibleHeightPlugin (opts) { var self = this; self.grid = null; self.scope = null; - self.init = function (scope, grid) { + self.init = function (scope, grid, services) { + self.domUtilityService = services.DomUtilityService; self.grid = grid; self.scope = scope; var recalcHeightForData = function () { setTimeout(innerRecalcForData, 1); }; @@ -11,27 +12,29 @@ function ngGridFlexibleHeightPlugin (opts) { var footerPanelSel = '.' + gridId + ' .ngFooterPanel'; var extraHeight = self.grid.$topPanel.height() + $(footerPanelSel).height(); var naturalHeight = self.grid.$canvas.height() + 1; - if (scope.baseViewportHeight == null || scope.baseViewportHeight === 0) { - scope.baseViewportHeight = self.grid.$viewport.height(); - } - if (scope.baseViewportHeight > naturalHeight) { - if (opts != null) { - if (opts.minHeight != null && (naturalHeight + extraHeight) < opts.minHeight) { - naturalHeight = opts.minHeight - extraHeight - 2; - } + if (opts != null) { + if (opts.minHeight != null && (naturalHeight + extraHeight) < opts.minHeight) { + naturalHeight = opts.minHeight - extraHeight - 2; } - self.grid.$viewport.css('height', (naturalHeight + 2) + 'px'); - self.grid.$root.css('height', (naturalHeight + extraHeight + 2) + 'px'); } - self.grid.refreshDomSizes(); + + var newViewportHeight = naturalHeight + 2; + if (!self.scope.baseViewportHeight || self.scope.baseViewportHeight !== newViewportHeight) { + self.grid.$viewport.css('height', newViewportHeight + 'px'); + self.grid.$root.css('height', (newViewportHeight + extraHeight) + 'px'); + self.scope.baseViewportHeight = newViewportHeight; + self.domUtilityService.UpdateGridLayout(self.scope, self.grid); + } }; - scope.catHashKeys = function () { + self.scope.catHashKeys = function () { var hash = '', idx; - for (idx in scope.renderedRows) { hash += scope.renderedRows[idx].$$hashKey; } + for (idx in self.scope.renderedRows) { + hash += self.scope.renderedRows[idx].$$hashKey; + } return hash; }; - scope.$watch('catHashKeys()', innerRecalcForData); - scope.$watch(grid.config.data, recalcHeightForData); + self.scope.$watch('catHashKeys()', innerRecalcForData); + self.scope.$watch(self.grid.config.data, recalcHeightForData); }; } diff --git a/plugins/ng-grid-layout.js b/plugins/ng-grid-layout.js index aa430eb756..34d1839d4b 100644 --- a/plugins/ng-grid-layout.js +++ b/plugins/ng-grid-layout.js @@ -6,11 +6,20 @@ function ngGridLayoutPlugin () { self.domUtilityService = services.DomUtilityService; self.grid = grid; self.scope = scope; + + // Register for column rearranging events + scope.$parent.$on('ngGridEventColumns', self.updateGridLayout); }; this.updateGridLayout = function () { - self.scope.$apply(function(){ + if (!self.scope.$$phase) { + self.scope.$apply(function(){ + self.domUtilityService.RebuildGrid(self.scope, self.grid); + }); + } + else { + // $digest or $apply already in progress self.domUtilityService.RebuildGrid(self.scope, self.grid); - }); + } }; } diff --git a/src/classes/grid.js b/src/classes/grid.js index 9a0bb5576b..a988316e62 100644 --- a/src/classes/grid.js +++ b/src/classes/grid.js @@ -372,57 +372,75 @@ var ngGrid = function ($scope, options, sortService, domUtilityService, $filter, } }; self.configureColumnWidths = function() { - var cols = self.config.columnDefs; - var indexOffset = self.config.showSelectionCheckbox ? $scope.configGroups.length + 1 : $scope.configGroups.length; - - var numOfCols = cols.length + indexOffset, - asterisksArray = [], + var asterisksArray = [], percentArray = [], asteriskNum = 0, totalWidth = 0; totalWidth += self.config.showSelectionCheckbox ? 25 : 0; - angular.forEach(cols, function(col, i) { - i += indexOffset; + // When rearranging columns, their index in $scope.columns will no longer match the original column order from columnDefs causing + // their width config to be out of sync. We can use "originalIndex" on the ngColumns to get hold of the correct setup from columnDefs, but to + // avoid O(n) lookups in $scope.columns per column we setup a map. + var indexMap = {}; + // Build a map of columnDefs column indices -> ngColumn indices (via the "originalIndex" property on ngColumns). + angular.forEach($scope.columns, function(ngCol, i) { + // Disregard columns created by grouping (the grouping columns don't match a column from columnDefs) + if (!$utils.isNullOrUndefined(ngCol.originalIndex)) { + var origIndex = ngCol.originalIndex; + if (self.config.showSelectionCheckbox) { + // The originalIndex will be offset 1 when including the selection column + origIndex--; + } + indexMap[origIndex] = i; + } + }); + + angular.forEach(self.config.columnDefs, function(colDef, i) { + // Get the ngColumn that matches the current column from columnDefs + var ngColumn = $scope.columns[indexMap[i]]; + + colDef.index = i; + var isPercent = false, t; //if width is not defined, set it to a single star - if ($utils.isNullOrUndefined(col.width)) { - col.width = "*"; + if ($utils.isNullOrUndefined(colDef.width)) { + colDef.width = "*"; } else { // get column width - isPercent = isNaN(col.width) ? $utils.endsWith(col.width, "%") : false; - t = isPercent ? col.width : parseInt(col.width, 10); + isPercent = isNaN(colDef.width) ? $utils.endsWith(colDef.width, "%") : false; + t = isPercent ? colDef.width : parseInt(colDef.width, 10); } + // check if it is a number if (isNaN(t)) { - t = col.width; + t = colDef.width; // figure out if the width is defined or if we need to calculate it if (t === 'auto') { // set it for now until we have data and subscribe when it changes so we can set the width. - $scope.columns[i].width = col.minWidth; - totalWidth += $scope.columns[i].width; - var temp = $scope.columns[i]; - $timeout(function () { - self.resizeOnData(temp, true); + ngColumn.width = ngColumn.minWidth; + totalWidth += ngColumn.width; + var temp = ngColumn; + + $scope.$on("ngGridEventData", function () { + self.resizeOnData(temp); }); return; } else if (t.indexOf("*") !== -1) { // we need to save it until the end to do the calulations on the remaining width. - if (col.visible !== false) { + if (ngColumn.visible !== false) { asteriskNum += t.length; } - col.index = i; - asterisksArray.push(col); + asterisksArray.push(colDef); return; } else if (isPercent) { // If the width is a percentage, save it until the very last. - col.index = i; - percentArray.push(col); + percentArray.push(colDef); return; } else { // we can't parse the width so lets throw an error. throw "unable to parse column width, use percentage (\"10%\",\"20%\", etc...) or \"*\" to use remaining width of grid"; } - } else if (col.visible !== false) { - totalWidth += $scope.columns[i].width = parseInt(col.width, 10); + } else if (ngColumn.visible !== false) { + totalWidth += ngColumn.width = parseInt(colDef.width, 10); } }); + // check if we saved any asterisk columns for calculating later if (asterisksArray.length > 0) { @@ -437,23 +455,55 @@ var ngGrid = function ($scope, options, sortService, domUtilityService, $filter, } // calculate the weight of each asterisk rounded down var asteriskVal = Math.floor(remainingWidth / asteriskNum); + // set the width of each column based on the number of stars - angular.forEach(asterisksArray, function(col, i) { + angular.forEach(asterisksArray, function(colDef, i) { + // Get the ngColumn that matches the current column from columnDefs + var ngColumn = $scope.columns[indexMap[colDef.index]]; var isLast = (i === (asterisksArray.length - 1)); - var t = col.width.length; - $scope.columns[col.index].width = asteriskVal * t; - $scope.columns[col.index].width -= isLast ? 0 : 2; - if (col.visible !== false) { - totalWidth += $scope.columns[col.index].width; + ngColumn.width = asteriskVal * colDef.width.length; + ngColumn.width -= isLast ? 0 : 1; + if (ngColumn.visible !== false) { + totalWidth += ngColumn.width; } }); } + // Now we check if we saved any percentage columns for calculating last if (percentArray.length > 0) { + // If any columns with % widths have been hidden, then let other % based columns use their width + var percentWidth = 0; // The total % value for all columns setting their width using % (will e.g. be 40 for 2 columns with 20% each) + var hiddenPercent = 0; // The total % value for all columns setting their width using %, but which have been hidden + angular.forEach(percentArray, function(colDef) { + // Get the ngColumn that matches the current column from columnDefs + var ngColumn = $scope.columns[indexMap[colDef.index]]; + var t = colDef.width; + var percent = parseInt(t.slice(0, -1), 10) / 100; + percentWidth += percent; + + if (!ngColumn.visible) { + hiddenPercent += percent; + } + }); + var percentWidthUsed = percentWidth - hiddenPercent; + // do the math - angular.forEach(percentArray, function(col) { - var t = col.width; - $scope.columns[col.index].width = Math.floor(self.rootDim.outerWidth * (parseInt(t.slice(0, -1), 10) / 100)); + angular.forEach(percentArray, function(colDef) { + // Get the ngColumn that matches the current column from columnDefs + var ngColumn = $scope.columns[indexMap[colDef.index]]; + + // Calc the % relative to the amount of % reserved for the visible columns (that use % based widths) + var t = colDef.width; + var percent = parseInt(t.slice(0, -1), 10) / 100; + if (hiddenPercent > 0) { + percent = percent / percentWidthUsed; + } + else { + percent = percent / percentWidth; + } + + var pixelsForPercentBasedWidth = self.rootDim.outerWidth * percentWidth; + ngColumn.width = Math.floor(pixelsForPercentBasedWidth * percent); }); } }; diff --git a/src/i18n/da.js b/src/i18n/da.js new file mode 100644 index 0000000000..60a81a6ada --- /dev/null +++ b/src/i18n/da.js @@ -0,0 +1,14 @@ +window.ngGrid.i18n['da'] = { + ngAggregateLabel: 'artikler', + ngGroupPanelDescription: 'Grupér rækker udfra en kolonne ved at trække dens overskift hertil.', + ngSearchPlaceHolder: 'Søg...', + ngMenuText: 'Vælg kolonner:', + ngShowingItemsLabel: 'Viste rækker:', + ngTotalItemsLabel: 'Rækker totalt:', + ngSelectedItemsLabel: 'Valgte rækker:', + ngPageSizeLabel: 'Side størrelse:', + ngPagerFirstTitle: 'Første side', + ngPagerNextTitle: 'Næste side', + ngPagerPrevTitle: 'Forrige side', + ngPagerLastTitle: 'Sidste side' +}; \ No newline at end of file