is there a way to auto adjust widths in ng-grid?

Riz picture Riz · Jun 18, 2013 · Viewed 41.2k times · Source

I'm having trouble with widths of my columns. I don't know what width they will be beforehand, nor do I want to specify each column's width. Is there an attribute that I can use that auto adjusts all the column widths based on the content (including the column header)?

Answer

Jess picture Jess · Sep 19, 2013

Woot! I came up with a pretty cool answer! Setting the width to "auto" was really not working for me. Maybe it is because I'm using an ng-view? Not sure. So I created 2 new functions you can put in your controller.js. Using them like this will give you computed column widths! Read the code comments; there are some caveats.

Example usage, controllers.js:

var colDefs = makeColDefs(rows[0]);
colDefs = autoColWidth(colDefs, rows[0]);

$scope.phones = rows;
$scope.gridOptions = {
    data : 'phones',
    showFilter : true,
    enableColumnResize : true,
    columnDefs : colDefs
};

The code, controllers.js:

/**
 * Create a colDefs array for use with ng-grid "gridOptions". Pass in an object
 * which is a single row of your data!
 */
function makeColDefs(row) {
    var colDefs = [];
    for ( var colName in row) {
        colDefs.push({
            'field' : colName
        });
    }
    return colDefs;
}

/**
 * Return a colDefs array for use with ng-grid "gridOptions". Work around for
 * "auto" width not working in ng-grid. colDefs array will have percentage
 * widths added. Pass in an object which is a single row of your data! This
 * function does not do typeface width! Use a fixed width font. Pass in an
 * existing colDefs array and widths will be added!
 */
function autoColWidth(colDefs, row) {
    var totalChars = 0;
    for ( var colName in row) {
        // Convert numbers to strings here so length will work.
        totalChars += (new String(row[colName])).length;
    }
    colDefs.forEach(function(colDef) {
        var numChars = (new String(row[colDef.field])).length;
        colDef.width = (numChars / totalChars * 100) + "%";
    });
    return colDefs;
}

Jasmine test, controllerSpec.js:

'use strict';

var ROW = {
    'col1' : 'a',
    'col2' : 2,
    'col3' : 'cat'
};
var COLUMN_DEF = [ {
    field : 'col1'
}, {
    field : 'col2'
}, {
    field : 'col3'
} ];
var COLUMN_DEF2 = [ {
    field : 'col1',
    width : '20%'
}, {
    field : 'col2',
    width : '20%'
}, {
    field : 'col3',
    width : '60%'
} ];

/* jasmine specs for controllers go here */

describe('controllers', function() {
    beforeEach(module('myApp.controllers'));

    it('should make an ng-grid columnDef array from a row of data.',
            function() {
                expect(makeColDefs(ROW)).toEqual(COLUMN_DEF);
            });

    it('should return an ng-grid columnDef array with widths!', function() {
        var colDefs = makeColDefs(ROW);
        expect(autoColWidth(colDefs, ROW)).toEqual(COLUMN_DEF2);
    });

});