diff --git a/src/js/core/factories/GridRenderContainer.js b/src/js/core/factories/GridRenderContainer.js index cb471ee26c..18cfe24a9a 100644 --- a/src/js/core/factories/GridRenderContainer.js +++ b/src/js/core/factories/GridRenderContainer.js @@ -609,7 +609,10 @@ angular.module('ui.grid') asteriskNum = 0, usedWidthSum = 0, ret = '', - pinRightColumn = false; + pinRightColumn = false, + fixedNumberArray = [], + percentageArray = [], + totalPercentage = 0; // Get the width of the viewport var availableWidth = self.grid.getViewportWidth() - self.grid.scrollbarWidth; @@ -617,12 +620,12 @@ angular.module('ui.grid') // get all the columns across all render containers, we have to calculate them all or one render container // could consume the whole viewport var columnCache = []; - angular.forEach(self.grid.renderContainers, function( container, name){ + angular.forEach(self.grid.renderContainers, function (container, name) { columnCache = columnCache.concat(container.visibleColumnCache); }); // look at each column, process any manual values or %, put the * into an array to look at later - columnCache.forEach(function(column, i) { + columnCache.forEach(function (column, i) { var width = 0; // Skip hidden columns if (!column.visible) { return; } @@ -641,21 +644,26 @@ angular.module('ui.grid') usedWidthSum = usedWidthSum + width; column.drawnWidth = width; + fixedNumberArray.push(column); } else if (gridUtil.endsWith(column.width, "%")) { // percentage width, set to percentage of the viewport // round down to int - some browsers don't play nice with float maxWidth - width = parseInt(parseInt(column.width.replace(/%/g, ''), 10) / 100 * availableWidth); + var percentageIntegerValue = parseInt(column.width.replace(/%/g, ''), 10); + width = parseInt(percentageIntegerValue / 100 * availableWidth); - if ( width > column.maxWidth ){ + if (width > column.maxWidth) { width = column.maxWidth; } - if ( width < column.minWidth ){ + if (width < column.minWidth) { width = column.minWidth; } usedWidthSum = usedWidthSum + width; column.drawnWidth = width; + + totalPercentage = totalPercentage + percentageIntegerValue; + percentageArray.push(column); } else if (angular.isString(column.width) && column.width.indexOf('*') !== -1) { // is an asterisk column, the gridColumn already checked the string consists only of '****' asteriskNum = asteriskNum + column.width.length; @@ -672,15 +680,15 @@ angular.module('ui.grid') // the width that each asterisk value would be assigned (this can be negative) var asteriskVal = remainingWidth / asteriskNum; - asterisksArray.forEach(function( column ){ + asterisksArray.forEach(function (column) { var width = parseInt(column.width.length * asteriskVal, 10); - if ( width > column.maxWidth ){ - width = column.maxWidth; + if (width > column.maxWidth) { + width = column.maxWidth; } - if ( width < column.minWidth ){ - width = column.minWidth; + if (width < column.minWidth) { + width = column.minWidth; } usedWidthSum = usedWidthSum + width; @@ -688,46 +696,57 @@ angular.module('ui.grid') }); } - // If the grid width didn't divide evenly into the column widths and we have pixels left over, or our - // calculated widths would have the grid narrower than the available space, - // dole the remainder out one by one to make everything fit - var processColumnUpwards = function(column){ - if ( column.drawnWidth < column.maxWidth && leftoverWidth > 0) { - column.drawnWidth++; - usedWidthSum++; - leftoverWidth--; - columnsToChange = true; - } - }; + // If there are no columns with asterisk widths then check if there are any with % widths and + // use them as a fallback for adjusting column widths up or down if we have remaining grid width + // or need to claw some width back + var variableWidthColumnArray; + if (asterisksArray.length > 0) { + variableWidthColumnArray = asterisksArray; + } else if (percentageArray.length > 0 && fixedNumberArray.length === 0 && totalPercentage === 100) { + variableWidthColumnArray = percentageArray; + } - var leftoverWidth = availableWidth - usedWidthSum; - var columnsToChange = true; + if (!angular.isUndefined(variableWidthColumnArray)) { + // If the grid width didn't divide evenly into the column widths and we have pixels left over, or our + // calculated widths would have the grid narrower than the available space, + // dole the remainder out one by one to make everything fit + var processColumnUpwards = function (column) { + if (column.drawnWidth < column.maxWidth && leftoverWidth > 0) { + column.drawnWidth++; + usedWidthSum++; + leftoverWidth--; + columnsToChange = true; + } + }; - while (leftoverWidth > 0 && columnsToChange) { - columnsToChange = false; - asterisksArray.forEach(processColumnUpwards); - } + var leftoverWidth = availableWidth - usedWidthSum; + var columnsToChange = true; - // We can end up with too much width even though some columns aren't at their max width, in this situation - // we can trim the columns a little - var processColumnDownwards = function(column){ - if ( column.drawnWidth > column.minWidth && excessWidth > 0) { - column.drawnWidth--; - usedWidthSum--; - excessWidth--; - columnsToChange = true; + while (leftoverWidth > 0 && columnsToChange) { + columnsToChange = false; + variableWidthColumnArray.forEach(processColumnUpwards); } - }; - var excessWidth = usedWidthSum - availableWidth; - columnsToChange = true; + // We can end up with too much width even though some columns aren't at their max width, in this situation + // we can trim the columns a little + var processColumnDownwards = function (column) { + if (column.drawnWidth > column.minWidth && excessWidth > 0) { + column.drawnWidth--; + usedWidthSum--; + excessWidth--; + columnsToChange = true; + } + }; + + var excessWidth = usedWidthSum - availableWidth; + columnsToChange = true; - while (excessWidth > 0 && columnsToChange) { - columnsToChange = false; - asterisksArray.forEach(processColumnDownwards); + while (excessWidth > 0 && columnsToChange) { + columnsToChange = false; + variableWidthColumnArray.forEach(processColumnDownwards); + } } - // all that was across all the renderContainers, now we need to work out what that calculation decided for // our renderContainer var canvasWidth = 0;