Grid features

Features are classes that add functionality to the Grid. The purpose of this guide is to give an overview of the features that ships with Grid and show how you can configure them.

Enabling/disabling and configuring features

Features are configured using Grids features-config. Some features are enabled by default, in which case you can disable them like this:

const grid = new Grid({
    features : {
        sort  : false,
        group : false
    }
});

Others require you to enable them:

const grid = new Grid({
    features : {
        filter    : true,
        quickFind : true
    }
});

Some features have configuration options (see the API docs for each feature for the options). In such cases you can specify an configuration object instead of true:

const grid = new Grid({
    features : {
        filter : { // Default filter, configuration object
            property : 'city',
            name     : 'Stockholm'
        },
        sort   : 'name' // Sort by name, configuration shortcut using string
    }
});

If you need to access a feature at runtime, they are available through the features property on Grid:

grid.features.search.gotoNextHit();

If you want to create a custom feature, head over to GridFeatureManager docs.

Built-in features

Grid itself has lots of built-in core functionality such rendering of cells, selection and keyboard navigation. On top of that, it ships with the features described below, some of which are enabled by default and others that have to be enabled manually.

AI (API docs)

This feature provides an AI agent for Grid which allows the user to use natural language to interact with the Grid in different ways. The feature and all its related components are marked as experimental and are subject to change.

This feature is disabled by default.

AIFilter (API docs)

Natural language filter tool

This feature is disabled by default.

CellCopyPaste (API Docs)

Allows using [Ctrl/CMD + C], [Ctrl/CMD + X] and [Ctrl/CMD + V] to cut, copy and paste cell or cell ranges. Also makes cut, copy and paste actions available via the cell context menu.

This feature is disabled by default.

CellEdit (API docs)

Inline editing of cell values.

This feature is enabled by default.

Double click a cell to start editing:

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

    // makes grid as high as it needs to be to fit rows
    autoHeight : true,

    features : {
        // cellEditing is enabled by default, so this is not necessary
        cellEdit : true
    },

    data : DataGenerator.generateData(2),

    columns : [
        // basic columns has a TextField as editor by default
        { field : 'name', text : 'Name', flex : 1 },
        // a custom editor can be specified
        {
            field  : 'city',
            text   : 'City',
            flex   : 1,
            editor : {
                type  : 'combo',
                items : ['Stockholm', 'New York', 'Montreal']
            }
        },
        // column types may specify an editor
        // NumberColumn for example uses a NumberField
        { type : 'number', field : 'score', text : 'Score', flex : 1 },
        // specify editor: false to make a column "readonly"
        { type : 'number', field : 'age', text : 'Age (readonly)', flex : 1, editor : false }
    ]
});

RowEdit (API docs)

Editing of a record in a side docked editing panel.

This feature is disabled by default.

Double click a cell to start editing:

Row editing guide
//<code-header>
fiddle.title = 'Row editing guide';
//</code-header>
// grid with row editing
const grid = new Grid({
    appendTo : targetElement,

    height : 600,

    features : {
        // cellEditing is enabled by default, so this is necessary
        cellEdit : false,
        rowEdit  : {
            // Dock the editor into the grid's element, not the browser viewport
            local : true
        }
    },

    showDirty : true,

    tbar : {
        items : {
            instantUpdate : {
                type     : 'checkbox',
                text     : 'Instant Update',
                tooltip  : 'Update record instantly after editing',
                value    : false,
                onChange : ({ checked }) => {
                    grid.features.rowEdit.instantUpdate = checked;
                }
            }
        }
    },

    data : DataGenerator.generateData(5),

    columns : [
        // basic columns has a TextField as editor by default
        {
            field            : 'name',
            text             : 'Name',
            flex             : 1,
            // Invoked on final edit of input field, typically after pressing enter or blurring the field.
            finalizeCellEdit : ({ value }) => {
                // returning true will accept the new value otherwise it shows the return statement as error message
                return value.trim().length < 5 ? 'Name should be at least 5 characters' : true;
            }
        },
        // a custom editor can be specified
        {
            field  : 'city',
            text   : 'City',
            flex   : 1,
            editor : {
                type  : 'combo',
                items : ['Stockholm', 'New York', 'Montreal']
            }
        },
        // column types may specify an editor
        // NumberColumn for example uses a NumberField
        {
            type             : 'number',
            field            : 'score',
            text             : 'Score',
            flex             : 1,
            finalizeCellEdit : ({ value, record }) => {

                // record contains sibling column's data
                const { city } = record;

                // Perform validation based on a sibling column
                if (city == 'Paris' && value > 999) {
                    return "Score can't be higher than 999 for Paris";
                }
                return true;
            }
        },
        // specify editor: false to make a column "readonly"
        { type : 'number', field : 'age', text : 'Age (readonly)', flex : 1, readOnly : true }
    ]
});

CellTooltip (API docs)

Display per cell tooltips that can contain record data.

This feature is disabled by default.

Hover a cell below to see it in action:

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

    // makes grid as high as it needs to be to fit rows
    autoHeight : true,

    features : {
        // enable CellTooltip and configure a default renderer
        cellTooltip : {
            tooltipRenderer : ({ record, column }) => 'Value: ' + record[column.field],
            hoverDelay      : 200
        }
    },

    data : DataGenerator.generateData(2),

    columns : [
        { field : 'name', text : 'Name', flex : 1 },
        { field : 'score', text : 'Score', flex : 1 },
        { type : 'number', field : 'age', text : 'Age', flex : 1 }
    ]
});

Charts (API docs)

Design charts based on grid data.

This feature is disabled by default.

Hover a cell below to see it in action:

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

    // makes grid as high as it needs to be to fit rows
    autoHeight : true,

    features : {
        charts : true
    },

    data : DataGenerator.generateData(15),

    columns : [
        { field : 'name', text : 'Name', flex : 1 },
        { field : 'score', text : 'Score', flex : 1 },
        { type : 'number', field : 'age', text : 'Age', flex : 1 }
    ]
});

grid.selectAll();

ColumnAutoWidth (API Docs)

Enables the autoWidth config for a grid's columns.

This feature is enabled by default.

ColumnDragToolbar (API docs)

A toolbar on which column headers can be dropped to sort, group etc. Great on touch devices.

This feature is disabled by default, but automatically enabled on touch devices unless explicitly disabled.

Grab a column header and drag it down to show the toolbar:

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

    // makes grid as high as it needs to be to fit rows
    autoHeight : true,

    features : {
        // this feature is enabled by default,
        // so no need for this unless you have changed defaults
        columnDragToolbar : true,

        // disabling sort to limit amount of buttons in the toolbar,
        // since this demo has limited space
        sort : false
    },

    data : DataGenerator.generateData(5),

    columns : [
        { field : 'name', text : 'Name (drag down)', flex : 1 },
        { field : 'city', text : 'City (drag down)', flex : 1 },
        { field : 'food', text : 'Food (drag down)', flex : 1 }
    ]
});

ColumnPicker (API docs)

Adds item to grid header context menus to toggle column visibility.

This feature is enabled by default.

Right click a header to show the menu:

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

    autoHeight : true,

    features : {
        // this feature is enabled by default,
        // so no need for this unless you have changed defaults
        columnPicker : true,

        // disabling other features to keep menu short
        sort  : false,
        group : false
    },

    data : DataGenerator.generateData(2),

    columns : [
        { field : 'name', text : 'Name (right click)', flex : 1 },
        { field : 'score', text : 'Score', flex : 1 },
        { type : 'rating', field : 'rating', text : 'Rating', width : 180 }
    ]
});

ColumnRename (API Docs)

Allows user to rename columns by either right-clicking column header or using keyboard shortcuts when column header is focused.

This feature is disabled by default.

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

    // makes grid as high as it needs to be to fit rows
    autoHeight : true,

    features : {
        columnRename : true
    },

    data : DataGenerator.generateData(5),

    columns : [
        { field : 'firstName', text : 'First name', flex : 1 },
        { field : 'surName', text : 'Surname', flex : 1 },
        { type : 'date', field : 'start', text : 'Start', flex : 1 },
        { type : 'date', field : 'finish', text : 'Finish', flex : 1 }
    ]
});

ColumnReorder (API docs)

Allows reordering columns by dragging their headers.

This feature is enabled by default.

Drag a header to rearrange:

Column reorder guide
//<code-header>
fiddle.title = 'Column reorder guide';
//</code-header>
// grid with ColumnReorder enabled
const grid = new Grid({
    appendTo : targetElement,

    // makes grid as high as it needs to be to fit rows
    autoHeight : true,

    // features : {
    //     // this feature is enabled by default,
    //     // so no need for this unless you have changed defaults
    //     columnReorder : true
    // },

    data : DataGenerator.generateData(2),

    columns : [
        { field : 'firstName', text : 'First name (drag)', flex : 1 },
        { field : 'surName', text : 'Surname', flex : 1 },
        { type : 'date', field : 'start', text : 'Start', flex : 1 },
        { type : 'date', field : 'finish', text : 'Finish', flex : 1 }
    ]
});

ColumnResize (API docs)

Lets user resize columns by dragging their headers right hand edge.

This feature is enabled by default.

Try it in this demo:

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

    autoHeight : true,

    features : {
        // this feature is enabled by default,
        // so no need for this unless you have changed defaults
        columnResize : true
    },

    data : DataGenerator.generateData(2),

    columns : [
        { field : 'firstName', text : 'First name', headerRenderer : ({ column }) => `${column.text} <span style="position: absolute; right: 0; font-size: .6em; z-index: 1">Drag <i class="fa fa-arrow-right"></i></span>`, width : 150 },
        { field : 'surName', text : 'Surname', width : 150 },
        { field : 'city', text : 'City', flex : 1 }
    ]
});

CellMenu (API docs)

Handles context menu for cells. Other features supply items, additional items can be added in your code.

This feature is enabled by default.

Right click a cell in the demo below to show the menu:

Cell menu guide
//<code-header>
fiddle.title = 'Cell menu guide';
//</code-header>
// grid with CellMenu feature
const grid = new Grid({
    appendTo : targetElement,

    // makes grid as high as it needs to be to fit rows
    autoHeight : true,

    features : {
        // this feature is enabled by default,
        // so no need for this unless you have changed defaults
        cellMenu : true
    },

    data : DataGenerator.generateData(2),

    columns : [
        { field : 'name', text : 'Name (right click)', flex : 1 },
        { field : 'score', text : 'Score', flex : 1 }
    ]
});

HeaderMenu (API docs)

Handles context menu for headers. Other features supply items, additional items can be added in your code.

This feature is enabled by default.

Right click a header in the demo below to show the menu:

Header menu guide
//<code-header>
fiddle.title = 'Header menu guide';
//</code-header>
// grid with HeaderMenu feature
const grid = new Grid({
    appendTo : targetElement,

    // makes grid as high as it needs to be to fit rows
    autoHeight : true,

    features : {
        // this feature is enabled by default,
        // so no need for this unless you have changed defaults
        headerMenu : true
    },

    data : DataGenerator.generateData(2),

    columns : [
        { field : 'name', text : 'Name (right click)', flex : 1 },
        { field : 'score', text : 'Score', flex : 1 }
    ]
});

ExcelExporter (API Docs)

A feature that allows exporting Grid data to Excel or CSV without involving the server.

This feature is disabled by default.

FileDrop (API Docs)

An experimental feature that lets users drop files on a Widget. The widget fires an event when a file is dropped onto it. In the event, you get access to the raw files as strings, that were parsed by calling readAsBinaryString.

This feature is disabled by default.

FillHandle (API Docs)

This feature adds a fill handle to a Grid range selection, which when dragged, fills the cells being dragged over with values based on the values in the original selected range. This is similar to functionality normally seen in various spreadsheet applications.

This feature is disabled by default.

Fill handle
//<code-header>
fiddle.title = 'Fill handle';
//</code-header>
targetElement.innerHTML = '<p>Fill range of cells with values computed from current selection</p>';

// grid with basic configuration
const grid = new Grid({
    // makes grid as high as it needs to be to fit rows
    autoHeight : true,
    appendTo   : targetElement,
    features   : {
        fillHandle : true
    },
    selectionMode : {
        cell       : true,
        dragSelect : true
    },
    columns : [
        { field : 'number', text : 'Number', flex : 1, type : 'number' },
        { field : 'text',   text : 'Text',   flex : 1 },
        { field : 'date',   text : 'Date',   flex : 1, type : 'date' },
        { field : 'empty1', text : 'Empty',  flex : 1 },
        { field : 'empty2', text : 'Empty',  flex : 1 }
    ],

    data : [
        { id : 1, number : 1, text : 'Once',   date : new Date(2022, 0, 1), empty1 : null, empty2 : null },
        { id : 2, number : 2, text : 'upon',   date : new Date(2022, 0, 2) },
        { id : 3, number : 3, text : 'a time', date : new Date(2022, 0, 3) },
        { id : 4 },
        { id : 5 },
        { id : 6 },
        { id : 7 },
        { id : 8 },
        { id : 9 }
    ]
});

grid.selectCellRange({ id : 1, column : grid.columns.first }, { id : 3, column : grid.columns.first });

Filter (API docs)

Enables the user to filter rows, either by using the cell context menu or through headers.

This feature is disabled by default.

Right click a cell or click the icon in a header in the demo below to see the options:

Filter guide
//<code-header>
fiddle.title = 'Filter guide';
//</code-header>
const data = DataGenerator.generateData(5);

const grid = new Grid({
    appendTo : targetElement,

    autoHeight : true,

    features : {
        filter : {
            property : 'city',
            value    : data[0].city
        }
    },

    data,

    columns : [
        { field : 'name', text : 'Traveller', flex : 1 },
        { field : 'city', text : 'Visited', flex : 1 },
        { field : 'food', text : 'Ate', flex : 1 },
        { field : 'rating', text : 'Score', flex : 1 }
    ]
});

FilterBar (API docs)

Similar to the Filter feature, but displays fields for filtering directly in the headers.

This feature is disabled by default.

Try it out in this demo:

Filter bar guide
//<code-header>
fiddle.title = 'Filter bar guide';
//</code-header>
const data = DataGenerator.generateData(5);

const grid = new Grid({
    appendTo : targetElement,

    autoHeight : true,

    features : {
        // enable filterbar and apply a default filter
        filterBar : {
            filter : { property : 'food', value : data[0].food }
        }
    },

    data,

    columns : [
        { field : 'name', text : 'Traveller', flex : 1 },
        { field : 'city', text : 'Visited', flex : 1 },
        { field : 'food', text : 'Ate', flex : 1 },
        { field : 'rating', text : 'Score', flex : 1 }
    ]
});

Group (API docs)

Allows grouping of rows in the Grid. Groups consists of all rows with the same value in the column by which the Grid is being grouped.

This feature is enabled by default.

Click on group headers to expand/collapse the group:

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

    autoHeight : true,

    features : {
        // group by food
        group : 'food'
    },

    data : DataGenerator.generateData(5),

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

GroupSummary (API docs)

Used in combination with Group feature, displays a summary bar at the bottom of each group.

This feature is disabledby default.

This demo has it enabled:

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

    autoHeight : true,

    features : {
        group        : 'city',
        groupSummary : true
    },

    data : DataGenerator.generateData(5),

    columns : [
        { field : 'name', text : 'Name', flex : 1 },
        { field : 'city', text : 'City', flex : 1, summaries : [{ sum : 'count', label : 'Rows' }] },
        { field : 'score', text : 'Score', flex : 1, summaries : [{ sum : 'avg', label : 'Average' }] }
    ]
});

LockRows (API Docs)

A feature which pins records which fit certain criteria to the top of the grid.

This feature is disabled by default.

This demo has it enabled:

Lock rows guide
//<code-header>
fiddle.title = 'Lock rows guide';
//</code-header>
const data = DataGenerator.generateData(50);
data[0].fixed = true;

const grid = new Grid({
    appendTo : targetElement,

    height : '30em',

    features : {
        group    : false,
        lockRows : true
    },

    data,

    columns : [
        { field : 'firstName', text : 'First name', width : 150 },
        { field : 'fixed', text : 'Fixed', type : 'check' },
        { field : 'surName', text : 'Surname',  width : 150 },
        { field : 'city', text : 'City',  width : 150 },
        { type : 'date', field : 'start', text : 'Start',  width : 150 },
        { type : 'date', field : 'finish', text : 'Finish', width : 150 },
        { type : 'number', field : 'score', text : 'Score',  width : 150 },
        { type : 'number', field : 'age',  text : 'Age', width : 150 },
        { type : 'rating', field : 'rank',  text : 'Rank', width : 150 }
    ]
});

MergeCells (API Docs)

This feature merges cells that have the same value in sorted columns configured to mergeCells.

This feature is disabled by default.

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

    height : 320,

    features : {
        // Enable the feature
        mergeCells : true,
        // Sort the city column to enable merging cells in it
        sort       : 'city'
    },

    data : DataGenerator.generateData(15),

    columns : [
        { field : 'city', text : 'City', flex : 1, mergeCells : true },
        { field : 'name', text : 'Name', flex : 1 },
        { field : 'food', text : 'Favorite food', flex : 1, mergeCells : true }
    ]
});

PdfExport (API Docs)

Generates PDF/PNG files from the Grid component.

This feature is disabled by default.

PinColumns (API Docs)

This feature allows users to pin columns to the start or end of the Grid. This improves data visibility and navigation in wide datasets without requiring additional subGrid configuration. When enabled, a Pin columns option is added to both the column header and cell context menus.

This feature is disabled by default.

This demo has it enabled:

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

    height : 300,

    features : {
        pinColumns : true
    },

    // Small dataset: student grades across five subjects and their average
    data : [
        { id : 1, student : 'Alice Johnson', math : 88, science : 92, history : 81, english : 90, geography : 85, average : 87.20 },
        { id : 2, student : 'Ben Carter', math : 74, science : 79, history : 85, english : 78, geography : 80, average : 79.20 },
        { id : 3, student : 'Chloe Nguyen', math : 93, science : 87, history : 90, english : 91, geography : 88, average : 89.80 },
        { id : 4, student : 'Diego Morales', math : 66, science : 72, history : 69, english : 70, geography : 64, average : 68.20 },
        { id : 5, student : 'Elena Petrova', math : 82, science : 84, history : 88, english : 86, geography : 82, average : 84.40 },
        { id : 6, student : 'Farah Khan', math : 95, science : 91, history : 94, english : 94, geography : 96, average : 94.00 },
        { id : 7, student : 'George Smith', math : 70, science : 68, history : 73, english : 72, geography : 71, average : 70.80 },
        { id : 8, student : 'Hiro Tanaka', math : 89, science : 85, history : 92, english : 88, geography : 90, average : 88.80 }
    ],

    // First column is pinned to start, last column pinned to end
    columns : [
        { field : 'student', text : 'Student', width : 180, pinned : 'start' },
        { type : 'number', field : 'math', text : 'Math', width : 120 },
        { type : 'number', field : 'science', text : 'Science', width : 120 },
        { type : 'number', field : 'history', text : 'History', width : 120 },
        { type : 'number', field : 'english', text : 'English', width : 120 },
        { type : 'number', field : 'geography', text : 'Geography', width : 120 },
        { text : 'Average', field : 'average', width : 140, type : 'number', pinned : 'end' }
    ]
});

Print (API Docs)

Allows printing Grid contents using browser print dialog.

This feature is disabled by default.

QuickFind (API docs)

Quick searching within a column, just click a cell and start typing.

This feature is disabled by default.

Click any cell in this demo and type something:

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

    autoHeight : true,

    features : {
        // enable quickfind
        quickFind : true
    },

    data : DataGenerator.generateData(5),

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

RegionResize (API docs)

Displays a splitter that allows the user to resize the regions when using a grid with locked & normal columns.

This feature is disabled by default.

Drag the splitter to resize or click the icons in it to expand/collapse:

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

    autoHeight : true,

    features : {
        // enabled region resize
        regionResize : true
    },

    data : DataGenerator.generateData(2),

    columns : [
        { field : 'firstName', text : 'First name', width : 150, locked : true },
        { field : 'surName', text : 'Surname', width : 150, locked : true },
        { field : 'city', text : 'City', flex : 1 },
        { field : 'team', text : 'Team', flex : 1 },
        { field : 'score', text : 'Score', flex : 1 },
        { field : 'rank', text : 'Rank', flex : 1 }
    ]
});

RowCopyPaste (API Docs)

Allow using [Ctrl/CMD + C/X] and [Ctrl/CMD + V] to copy/cut and paste rows. Also makes cut, copy and paste actions available via the cell context menu.

This feature is enabled by default.

RowExpander (API Docs)

Enables expanding of Grid rows by either row click or double click, or by adding a separate Grid column which renders a button that expands or collapses the row.

This feature is disabled by default.

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

    height : 320,

    features : {
        // Enable the feature
        rowExpander : {
            columnPosition : 'last',
            renderer({ record }) {
                return `<div style="padding: 10px"><div style="font-weight: bold;margin-bottom:5px;">Introduction in Latin</div><div style="color:#555">${record.notes} ${record.notes}</div></div>`;
            }
        }
    },

    data : DataGenerator.generateData(15),

    columns : [
        { field : 'firstName', text : 'First name', flex : 1 },
        { field : 'surName', text : 'Surname', flex : 1 },
        { field : 'age', text : 'Age', flex : 1 }
    ]
});

grid.features.rowExpander.expand(grid.store.first);

RowReorder (API Docs)

Allows user to reorder rows by dragging them. To get notified about row reorder listen to change event on the grid store.

This feature is disabled by default.

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

    // makes grid as high as it needs to be to fit rows
    autoHeight : true,

    features : {
        // enable row reordering by dragging
        rowReorder : {
            showGrip : true
        }
    },

    data : DataGenerator.generateData(10),

    columns : [
        { field : 'firstName', text : 'First name', width : 150, locked : true },
        { field : 'surName', text : 'Surname', width : 150, locked : true },
        { field : 'city', text : 'City', flex : 1 },
        { field : 'team', text : 'Team', flex : 1 },
        { field : 'score', text : 'Score', flex : 1 },
        { field : 'rank', text : 'Rank', flex : 1 }
    ]
});

RowResize (API Docs)

Enables user to change row height by dragging the bottom row border.

This feature is disabled by default.

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

    // makes grid as high as it needs to be to fit rows
    autoHeight : true,

    features : {
        rowResize : true
    },

    data : DataGenerator.generateData(5),

    columns : [
        { field : 'firstName', text : 'First name', flex : 1 },
        { field : 'surName', text : 'Surname', flex : 1 },
        { type : 'date', field : 'start', text : 'Start', flex : 1 },
        { type : 'date', field : 'finish', text : 'Finish', flex : 1 }
    ]
});

Search (API docs)

Search has functionality for searching the grid, but it does not have any input UI. That needs to be supplied by the application.

This feature is disabled by default.

This demo uses a basic text field to search from:

Search guide
//<code-header>
fiddle.title = 'Search guide';
//</code-header>
const searchField = new TextField({
    appendTo : targetElement,
    label    : 'Search',
    icon     : 'b-icon b-icon-search',
    value    : 'on',
    style    : 'margin-bottom: 1em',
    onInput  : () => grid.features.search.search(searchField.value)
});

// grid with Search feature
const grid = new Grid({
    appendTo : targetElement,

    // makes grid as high as it needs to be to fit rows
    autoHeight : true,

    features : {
        // enable searching
        search : true
    },

    data : DataGenerator.generateData(5),

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

// initial search
grid.features.search.search(searchField.value);

Sort (API docs)

Sort by a single or multiple columns, either by clicking headers or by using their context menus.

This feature is enabled by default.

This demo has a default sorter defined:

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

    autoHeight : true,

    features : {
        // sorting by name
        sort : 'name'
    },

    data : DataGenerator.generateData(5),

    columns : [
        { field : 'name', text : 'Name', flex : 1 },
        { field : 'city', text : 'City', flex : 1 },
        { type : 'number', field : 'score', text : 'Score', flex : 1 },
        { type : 'number', field : 'age', text : 'Age (no sort)', flex : 1, sortable : false }
    ]
});

Split (API Docs)

This feature allows splitting the Grid into multiple views, either by using the cell context menu, or programmatically by calling split().

This feature is disabled by default.

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

    height : '30em',

    features : {
        // Enable the Split feature
        split : true
    },

    data : DataGenerator.generateData(50),

    columns : [
        { field : 'firstName', text : 'First name', width : 150 },
        { field : 'surName', text : 'Surname',  width : 150 },
        { field : 'city', text : 'City',  width : 150 },
        { type : 'date', field : 'start', text : 'Start',  width : 150 },
        { type : 'date', field : 'finish', text : 'Finish', width : 150 },
        { type : 'number', field : 'score', text : 'Score',  width : 150 },
        { type : 'number', field : 'age',  text : 'Age', width : 150 },
        { type : 'rating', field : 'rank',  text : 'Rank', width : 150 }
    ]
});

grid.split({ direction : 'vertical' });

StickyCells (API Docs)

A feature which pins configurable content from a grid row to the top of the grid while the row scrolls off the top but is still visible.

This feature is disabled by default.

Stripe (API docs)

Makes every other rows background have a different color, also hides bottom border of each row. This feature is disabled by default. Grid with striped rows:

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

    autoHeight : true,

    features : {
        // enable striping
        stripe : true
    },

    data : DataGenerator.generateData(3),

    columns : [
        { field : 'name', text : 'Name', flex : 1 },
        { field : 'team', text : 'Team', flex : 1 },
        { type : 'number', field : 'rank', text : 'Rank', flex : 1 }
    ]
});

Summary (API docs)

Summaries defined per column are displayed in a footer bar.

This feature is disabled by default.

Try changing some values, it will updated the summaries:

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

    autoHeight : true,

    features : {
        // enable summaries
        summary : true
    },

    data : DataGenerator.generateData(2),

    columns : [
        { field : 'name', text : 'Name', flex : 1 },
        { type : 'number', field : 'score', text : 'Score', flex : 1, sum : 'sum' },
        { type : 'number', field : 'rank', text : 'Rank', flex : 1, sum : 'average' }
    ]
});

Tree (API docs)

Turns the grid into a tree. Requires exactly one TreeColumn to be present.

This feature is disabled by default.

If you want to use this feature, we recommend that you use TreeGrid instead of Grid since it has what is needed included by default.

Tree grid guide
//<code-header>
fiddle.title = 'Tree grid guide';
//</code-header>
const tree = new TreeGrid({
    appendTo : targetElement,

    autoHeight : true,

    data : [
        {
            id       : 1,
            name     : 'ABBA',
            iconCls  : 'b-icon fa-users',
            born     : '',
            children : [
                { id : 11, name : 'Anni-Frid', born : 1945, iconCls : 'b-icon fa-user' },
                { id : 12, name : 'Bjorn', born : 1945, iconCls : 'b-icon fa-user' },
                { id : 13, name : 'Benny', born : 1946, iconCls : 'b-icon fa-user' },
                { id : 14, name : 'Agnetha', born : 1950, iconCls : 'b-icon fa-user' }
            ]
        },
        {
            id       : 2,
            name     : 'Roxette',
            iconCls  : 'b-icon fa-users',
            born     : '',
            children : [
                { id : 21, name : 'Per', born : 1959, iconCls : 'b-icon fa-user' },
                { id : 22, name : 'Marie', born : 1958, iconCls : 'b-icon fa-user' }
            ]
        }
    ],

    columns : [
        { type : 'tree', field : 'name', text : 'Name', flex : 1 },
        { type : 'number', field : 'born', text : 'Born', flex : 1 }
    ]
});

TreeGroup API Docs

A feature that allows transforming a flat dataset (or the leaves of a hierarchical) into a tree by specifying a record field per parent level. Parents are generated based on each leaf's value for those fields.

This feature is disabled by default.

Tree group
//<code-header>
fiddle.title = 'Tree group';
//</code-header>
const grid = new TreeGrid({
    appendTo : targetElement,

    // Makes grid as high as it needs to be to fit rows
    autoHeight : true,

    // Initial dataset, will be transformed by the TreeGroup feature
    store : {
        fields : [
            'name',
            'status',
            'prio'
        ],
        data : [
            {
                id       : 1,
                name     : 'Project 1',
                expanded : true,
                children : [
                    { id : 11, name : 'Task 11', status : 'WIP', prio : 'High' },
                    { id : 12, name : 'Task 12', status : 'Done', prio : 'Low' },
                    { id : 13, name : 'Task 13', status : 'Done', prio : 'High' }
                ]
            },
            {
                id       : 2,
                name     : 'Project 2',
                expanded : true,
                children : [
                    { id : 21, name : 'Task 21', status : 'WIP', prio : 'High' }
                ]
            }
        ]
    },

    columns : [
        { type : 'tree', field : 'name', text : 'Name', flex : 1 }
    ],

    features : {
        treeGroup : {
            levels : ['status'],
            // Customize the cell / row element or the value displayed using parentRenderer
            parentRenderer({ value, cellElement, row, grid }) {
                const cls = value === 'Done' ? 'check-circle' : 'clock';
                return `<i class="fa fa-${cls}" style="margin-inline-end:.5em;color:${cls === 'check-circle' ? 'green' : 'lightgray'}"></i>${value}`;
            }
        }
    },

    tbar : [
        {
            type        : 'buttongroup',
            toggleGroup : true,
            items       : [
                {
                    text    : 'Status',
                    pressed : true,
                    onToggle({ pressed }) {
                        pressed && grid.group(['status']);
                    }
                },
                {
                    text : 'Prio',
                    onToggle({ pressed }) {
                        pressed && grid.group(['prio']);
                    }
                },
                {
                    text : 'Status + Prio',
                    onToggle({ pressed }) {
                        pressed && grid.group(['status', 'prio']);
                    }
                },
                {
                    text : 'none',
                    onToggle({ pressed }) {
                        pressed && grid.clearGroups();
                    }
                }
            ]
        }
    ]
});

Importing features from sources

A feature is registered when the application imports it. When using the regular module/umd bundle, this is done automatically, as the bundle encapsulates all code inside. However, when utilizing sources or thin bundles, a feature might not be imported by default. For any feature not enabled by default, it is essential to ensure that you have imported it to be able to use it.

Example:

import Grid from 'PATH_TO_SOURCE/Grid/view/Grid.js';
import 'PATH_TO_SOURCE/Grid/feature/Filter.js';

const grid = new Grid({
    features : {
        filter : {
            // feature config
        }
    }
});