Grid columns

This guide describes the basics on how to configure and manipulate grid columns.

Setting up columns

To configure which columns to use in a Grid you use the grid configurations columns property:

const grid = new Grid({
    columns : [
        { text : 'Name', field : 'name', flex : 1 },
        { text : 'City', field : 'city', width : 100 }
    ]
});

The snippet above shows a grid with two columns using minimal configuration:

  • text - Text to display in the column header
  • field - Data field from which column contents are fetched
  • flex - Proportional width, the width remaining after any fixed width columns is shared between flex columns
  • width - Fixed width, in pixels if nothing else is specified

Result:

Setting up columns
//<code-header>
fiddle.title = 'Setting up columns';
//</code-header>
const grid = new Grid({
    appendTo : targetElement,

    autoHeight : true,

    data : DataGenerator.generateData(2),

    columns : [
        { field : 'name', text : 'Name', flex : 1 },
        { field : 'city', text : 'City', width : 100 }
    ]
});

Column types

Grid supports different column types. These types affect how data in the column is formatted and edited. You specify which type a column has in its configuration object:

{ 
    type : 'columntype',
    text : 'Header',
    // other properties
} 

This snippet has one column per type:

const grid = new Grid({
    columns : [
        { type : 'rownumber' },
        { type : 'check', text : 'CheckColumn', field : 'done', flex : 1 },
        { type : 'date', text : 'DateColumn', field : 'start', flex : 1 },
        { type : 'number', text : 'NumberColumn', field : 'rank', flex : 1 },
        { type : 'percent', text : 'PercentColumn', field : 'percent', flex : 1 },
        { type : 'rating', text : 'RatingColumn', field : 'rating', flex : 1 },
        {
            type     : 'template', 
            text     : 'TemplateColumn', 
            field    : 'city', 
            flex     : 1,
            template : ({ value }) => `Lives in ${value}`
        },
        {
            type    : 'widget', 
            text    : 'Widget', 
            field   : 'color', 
            flex    : 1,
            widgets : [{ 
                type : 'button', 
                text : 'Click' 
            }]
        }
    ]
});

Result:

Column types
//<code-header>
fiddle.title = 'Column types';
//</code-header>
const grid = new Grid({
    appendTo : targetElement,

    autoHeight : true,

    data : DataGenerator.generateData(2),

    columns : [
        { type : 'rownumber' },
        { type : 'check', text : 'Check', field : 'done', width : 80 },
        { type : 'date', text : 'Date', field : 'start', flex : 1 },
        { type : 'number', text : 'Number', field : 'rank', flex : 1 },
        { type : 'percent', text : 'Percent', field : 'percent', flex : 1 },
        { type : 'rating', text : 'Rating', field : 'rating', flex : 1 },
        { type : 'template', text : 'Template', field : 'city', flex : 1, template : ({ value }) => `Lives in ${value}` },
        { type : 'widget', text : 'Widget', field : 'color', flex : 1, widgets : [{ type : 'button', rendition : 'filled', text : 'Click' }] }
    ]
});

To learn more about each column type, please read the API docs for them found under Grid/columns.

Column settings

Different column types support different settings, but there is a common base for all of them inherited from the class Column. This list contains some of most common settings that apply to all columns:

SettingsExplanation
rendererA function that can affect styling and contents of a cell, more information below
afterRenderCellA function called after a cell has been rendered, use it to style the row, cell or contents
editorType of editor to use when editing cell contents
alignText align: left, center or right
hiddenSet to true to hide the column initially, can be shown using the column picker
lockedSet to true to lock/freeze the column
htmlEncodeSet to false to treat html in the cell content as html and not text
clsCSS class to add to this columns header
cellClsCSS class to add to each cell in this column

This snippet shows some of the settings:

const grid = new Grid({
    columns : [
        { field : 'firstName', text : 'First name' },
        { field : 'surName', text : 'Surname', hidden : true },
        { field : 'age', text : 'Age', align : 'right' },
        { field : 'city', text : 'City', editor : false }
    ]
});

Result:

Column config
//<code-header>
fiddle.title = 'Column config';
//</code-header>
const grid = new Grid({
    appendTo : targetElement,

    autoHeight : true,

    data : DataGenerator.generateData(2),

    columns : [
        { field : 'firstName', text : 'First name' },
        { field : 'surName', text : 'Surname', hidden : true },
        { field : 'age', text : 'Age', align : 'right' },
        { field : 'city', text : 'City', editor : false }
    ]
});

For a complete list of Column configuration settings, see Column in API docs.

Using renderers

Renderers are functions used to determine what is shown in a column. You can define a renderer in your column config:

const grid = new Grid({
    columns : [
        { 
            text : 'Name',
            field : 'name',
            flex : 1,
            renderer : ({ value }) => value
        }
    ]
});

The renderer defined above only returns the value which it is given (name). Usually you use the renderer to apply some formatting or CSS. Because of how the grid is rendered, renderers is the only place where it can be considered safe to programmatically add styling. A renderer is called with a single parameter having the following properties:

ParameterExplanation
cellElementGives direct access to the cells DOM element, for adding styles or setting CSS classes
valueThe value which would be displayed in the cell if no renderer was used
recordThe data record for the current row.
sizeAn object used to control row height, set size.height to specify
gridGrid instance
columnColumn instance for the current cell
rowRow instance for the current cell. Use the Row's API to manipulate CSS classes
You should never modify any records inside this method.

This snippet defines a couple of more complex renderers:

const grid = new Grid({
    columns : [
        {
            field : 'name',
            text  : 'Name',
            flex  : 1,
            renderer({ cellElement, record, row }) {
                // Add/remove classNames on the row
                row.assignCls({
                    private    : record.access === 'private',
                    deprecated : record.deprecated
                });
                cellElement.style.backgroundColor = record.color;
                cellElement.style.color = '#fff';
                return record.name;
            }
        },
        {
            field      : 'color',
            text       : 'Color',
            flex       : 1,
            htmlEncode : false,
            renderer({ value }) {
                return `
                    <div style="
                        width: 1em;
                        height: 1em;
                        border-radius: 3px;
                        background-color: ${value};
                        margin-right: .5em"></div>
                    ${value}
                `;
            }
        }
    ]
});

Result:

Column renderer
//<code-header>
fiddle.title = 'Column renderer';
//</code-header>
const grid = new Grid({
    appendTo : targetElement,

    autoHeight : true,

    data : [
        { id : 1, name : 'Don Taylor', color : 'blue' },
        { id : 2, name : 'John Adams', color : 'pink' },
        { id : 3, name : 'Linda Moore', color : 'lime' }
    ],

    columns : [
        {
            field : 'name',
            text  : 'Name',
            flex  : 1,
            renderer({ cellElement, record }) {
                cellElement.style.backgroundColor = `color-mix(in srgb, var(--b-color-${record.color}), var(--b-mix) 90%)`;
                cellElement.style.color           = `color-mix(in srgb, var(--b-color-${record.color}), var(--b-opposite) 20%)`;
                return record.name;
            }
        },
        {
            field      : 'color',
            text       : 'Color',
            flex       : 1,
            htmlEncode : false,
            renderer({ value }) {
                return `
                        <div style="
                            width: 1em;
                            height: 1em;
                            border-radius: 3px;
                            background-color: var(--b-color-${value});
                            margin-right: .5em"></div>
                        ${value}
                    `;
            }
        }
    ]
});

If you want to customize the display of predefined columns (such as DateColumn, NumberColumn) but do not want to affect the output, you can use the afterRenderCell method to assign CSS classes to the cell / row.

const grid = new Grid({
    columns : [
        {
            text  : 'Date', // Can be any column to style rows
            type  : 'date',
            field : 'date',
            width : 100,
            afterRenderCell({ row, record, cellElement, value }) {
                // Add "past" CSS class to dates in the past
                cellElement.classList.toggle('past', value < Date.now());
            }
        }
    ]
});

For more formatting options, check the renderers demo.

Manipulating columns

Grid stores it columns as records in a store, allowing for easy reactive manipulation. The store (a ColumnStore) can be accessed using the grid.columns property:

// The ColumnStore
grid.columns;

// Get first column
const first = grid.columns.first;

// Get column by field
const age = grid.columns.get('age');

// If you are using multiple columns for the same field, it is safer to access them using id
const name = grid.columns.getById('idOfNameColumn');

The column records/instances can be used to manipulate the columns. For example:

// Change width
grid.columns.first.width = 100;

// Hide a column
ageColumn.hidden = true;

For available properties, see Column in API docs.