How to auto size column width in AngularJS ui-grid
Asked Answered
S

12

15

In AngularJS ui-grid , how can I configure the grid so that it can auto adjust the width of the columns according to the contents when it render?

I know there is a tutorial showing the auto size function, but that works only when you double click the column, I wish it could happen when the grid is initiated.

Standford answered 21/5, 2015 at 20:36 Comment(1)
So where is the code from what you have tried?Historiography
L
6

use an asterisk in your column definition:

width:"*";
Liam answered 21/5, 2015 at 22:40 Comment(5)
Well this doesn't throw any errors, but it doesn't seem to work. Columns still only seem to resize with manual intervention.Androsphinx
Post your column defs, so that I can see.Liam
Here are my columnDefs: gist.github.com/charlesroper/726d2df8d769920966ee. The first three columns should auto-resize, right? In my case, their width is equal to all of the others, and they the divider in the header can be double-clicked which resizes them accordingly. Is this a very new feature? If so, it could be I don't have the very latest version of ui-grid.Androsphinx
@CharlesRoper Did you get it to work? I can't get the columns to auto size. It drives me crazy.Lakes
@MatthiasMax No, I don't think I ever did.Androsphinx
C
6

There is a pluggin that do this: ui-grid-auto-fit-columns

GitHub: https://github.com/Den-dp/ui-grid-auto-fit-columns

Example: http://jsbin.com/tufazaw/edit?js,output

Usage:

<div ui-grid="gridOptions" ui-grid-auto-fit-columns></div>

angular.module('app', ['ui.grid', 'ui.grid.autoFitColumns'])
Carmel answered 13/4, 2017 at 14:37 Comment(0)
F
4

I dont think this feature exists at this point. The uiGridColumnResizer directive is registering event listeners on dblclick, mousedown and mouseup. The dblclick event is basically going thru all the rendered cells and calculating the maximum width and setting it as the column width. This will be a performance issue if you have a lot of rows rendered.

I would probably just set a maximum possible width based on the data the grid will have.

Or try to replicate the behaviour in the uiGridColumnResizer.

 $elm.on('dblclick', function(event, args) {
      event.stopPropagation();

      var col = uiGridResizeColumnsService.findTargetCol($scope.col, $scope.position, rtlMultiplier);

      // Don't resize if it's disabled on this column
      if (col.colDef.enableColumnResizing === false) {
        return;
      }

      // Go through the rendered rows and find out the max size for the data in this column
      var maxWidth = 0;
      var xDiff = 0;

      // Get the parent render container element
      var renderContainerElm = gridUtil.closestElm($elm, '.ui-grid-render-container');

      // Get the cell contents so we measure correctly. For the header cell we have to account for the sort icon and the menu buttons, if present
      var cells = renderContainerElm.querySelectorAll('.' + uiGridConstants.COL_CLASS_PREFIX + col.uid + ' .ui-grid-cell-contents');
      Array.prototype.forEach.call(cells, function (cell) {
          // Get the cell width
          // gridUtil.logDebug('width', gridUtil.elementWidth(cell));

          // Account for the menu button if it exists
          var menuButton;
          if (angular.element(cell).parent().hasClass('ui-grid-header-cell')) {
            menuButton = angular.element(cell).parent()[0].querySelectorAll('.ui-grid-column-menu-button');
          }

          gridUtil.fakeElement(cell, {}, function(newElm) {
            // Make the element float since it's a div and can expand to fill its container
            var e = angular.element(newElm);
            e.attr('style', 'float: left');

            var width = gridUtil.elementWidth(e);

            if (menuButton) {
              var menuButtonWidth = gridUtil.elementWidth(menuButton);
              width = width + menuButtonWidth;
            }

            if (width > maxWidth) {
              maxWidth = width;
              xDiff = maxWidth - width;
            }
          });
        });

      // check we're not outside the allowable bounds for this column
      col.width = constrainWidth(col, maxWidth);

      // All other columns because fixed to their drawn width, if they aren't already
      resizeAroundColumn(col);

      buildColumnsAndRefresh(xDiff);

      uiGridResizeColumnsService.fireColumnSizeChanged(uiGridCtrl.grid, col.colDef, xDiff);
    });
Felipafelipe answered 21/5, 2015 at 22:43 Comment(0)
B
3

So, this worked for me when I needed to shrink all columns except for one. I iterate through all columns after the grid is finished loading, and trigger a double click event on the resizer. Not the prettiest, so if anybody else has a better solution, I'd be very happy to hear it!

function resizeColumn(uid) {
    // document.querySelector might not be supported; if you have jQuery
    // in your project, it might be wise to use that for selecting this
    // element instead
    var resizer = document.querySelector('.ui-grid-col' + uid + ' .ui-grid-column-resizer.right');
    angular.element(resizer).triggerHandler('dblclick');
}

var gridOptions = {
    ...
    onRegisterApi: function (gridApi) {
        // why $interval instead of $timeout? beats me, I'm not smart enough
        // to figure out why, but $timeout repeated infinitely for me
        $interval(function() {
            var columns = gridApi.grid.columns;
            for(var i = 0; i < columns.length; i++) {
                // your conditional here
                if(columns[i].field !== 'name') {
                    resizeColumn(columns[i].uid)
                }
            }
        }, 0, 1);
    }
}
Bahner answered 21/11, 2016 at 19:2 Comment(2)
I ended up doing something very similar to this, but really feel like I should just be able to use columnDefs and the ui-grid directives to accomplish this...did you stick with this solution or did you manage to get it to work with the columnDefs/directives? I just noticed you posted this years ago...Yonah
we've since migrated from angularJS, but I don't believe this was ever changedBahner
M
2

you can use * as in the width property - is consider as auto you can see here

Magalymagan answered 26/6, 2016 at 6:7 Comment(0)
O
2

Using width : "*", will adjust all the columns in the available view port, which results in columns to get compressed.

Specifying minWidth: "somevalue" and width: "*" makes your ui-grid look better

Obese answered 14/2, 2017 at 8:19 Comment(0)
A
1

You can use following code:

<div ui-grid="gridOptions" class="grid" ui-grid-auto-resize></div>

var app = angular.module('app', ['ui.grid', 'ui.grid.autoResize']);

For reference you check the ui-grid documentation here.

Arakawa answered 23/2, 2022 at 14:52 Comment(1)
this code resizes the entire grid, not individual columnsSweetbrier
A
0

add the following to the gridoptions

                    init: function (gridCtrl, gridScope) {
                        gridScope.$on('ngGridEventData', function () {
                            $timeout(function () {
                                angular.forEach(gridScope.columns, function (col) {
                                    gridCtrl.resizeOnData(col);
                                });
                            });
                        });
                    }

Make sure you have a width of any random number on each column definition

width: 100 

is fine.

Alwitt answered 21/6, 2016 at 8:0 Comment(1)
As of version 3, init is no longer supported.Brott
P
0

I did not find any implementation for this so this is what I've done

  1. Iterated through the first 10 records.

  2. Found the max size of data for each column.

  3. Then created a span tag on the fly and wrapped it with that data.

  4. Measured the width of the tag and that would be your approx width required for the column (might need to append some more constant width due to CSS effect etc).

  5. If first 10 records are null then do the same process but this time with column header.

Perigee answered 7/7, 2016 at 10:1 Comment(0)
D
0

Best solution I can come up with is to:

  1. set the grid width to 100%
  2. set the maxWidth: attribute on the columnDefs you don't want to size to some small number
  3. let the grid size itself

html:

ui-grid="gridOptions" class="myuigrid" ui-ui-grid-resize-columns ui-grid-ui-grid-auto-resize></div>

css:

.myuigrid {
   width: 100%;
 }

js

            columnDefs: [
              { name: 'Id', maxWidth:80 },
              { name: 'Name', maxWidth: 280 },
              { name: 'LongName'},
            ],

I know this won't work in every case but a lot of the time most of your columns are more or less fixed and the variable ones which you know in advance are the ones to let resize.

Disenthrone answered 17/11, 2016 at 15:57 Comment(2)
"...you don't want to size to some small number" Did you mean minWidth?Gentlemanatarms
@JoshuaDrake my thinking was not to fix them but to stop them being picked for resize at the expense of other columns I think would be a better choice to resize.Disenthrone
P
0

I found some issues with width solution. We should use the property 'cellClass' in ui-grid columns object to enable this class.

.ui-grid-cell-contents-auto {
     /* Old Solution */
    /*min-width: max-content !important;*/

    /* New Solution */
    display: grid;
    grid-auto-columns: max-content;

    /* IE Solution */
    display: -ms-grid;
    -ms-grid-columns: max-content;
}

then you should use the property cellClass in ui-grid columns object to enable this class on your grid (something like this):

columns: [{ field: 'search_name', displayName: '', cellClass: 'ui-grid-cell-contents-auto'}]

You can refer to nekhaly's answer detailed description. https://github.com/angular-ui/ui-grid/issues/3913

Photogravure answered 12/3, 2018 at 6:22 Comment(0)
D
-2

try using 'width: auto' ..apparently using this was an issue in a previous release of ui-grid, it should work now, its part of their docs here: defining columns

EDIT: reference link to closed issue #565 page

Dahle answered 21/5, 2015 at 21:45 Comment(2)
That's for the old ng-grid. I'm pretty sure Tony is after a solution for the newer ui-grid. I've just checked and width: 'auto' doesn't work in ui-grid.Androsphinx
For future reference, it's a '*' not 'auto'.Lanalanae

© 2022 - 2024 — McMap. All rights reserved.