v7.3.0

Upgrade guides for Grid v5.0.0+

Grid v5.0.0

Grid's selectionMode config

The selectionMode config controlling row / cell selection behavior is now merged with the config object you provide (previously the outside config object overwrote the default settings).

Pre 5.0 code

const grid = new Grid({
    selectionMode : {
        multiSelect : false
    }
})

// The code object resulted in a selectionMode object with only a `multiSelect` property.

Post 5.0 code

const grid = new Grid({
    selectionMode : {
        multiSelect : false
    }
})

/* In 5.0 - the same code results in merge of the outside config and the defaults, i.e.:
selectionMode : {
    row                              : true,
    cell                             : true,
    rowCheckboxSelection             : false,
    multiSelect                      : false,
    checkbox                         : false,
    showCheckAll                     : false,
    deselectFilteredOutRecords       : false,
    includeChildren                  : false,
    preserveSelectionOnPageChange    : false,
    preserveSelectionOnDatasetChange : true,
    deselectOnClick                  : false
}
*/

Store remove method now always returns Array

Previously it returned null if no records were removed. In 5.0, the return value is always an array.

Store beforeRemove and remove events fired in batch

For tree store, previously the store fired one beforeRemove and remove event for every removed record when removing multiple. This caused performance issues when removing many nodes. In 5.0, removing multiple nodes in a tree triggers a batch event similar to how a flat store works.

Pre 5.0 code

const store = new Store({
    tree : true,
    listeners : {
        remove({ parent, index, isChild, allRecords, isMove, records }) {

        }
    }
})

// Triggers 1 remove event for every removed node
store.remove([store.getById(1), store.getById(2)]);

Post 5.0 code

In 5.0, when removing multiple records, the parent and index parameters are omitted.

const store = new Store({
    tree : true,
    listeners : {
        remove({ isChild, allRecords, isMove, records }) {

        }
    }
})

// Will trigger just 1 remove event
store.remove([store.getById(1), store.getById(2)]);

TextAreaField split into two classes

TextAreaField was split into two classes. The old TextAreaField was renamed to TextAreaPickerField and is intented for use as a column cell editor and TextAreaField for use in an "inline" form type context. NoteColumn in Gantt has been updated to use TextAreaPickerField and the TaskEditor NotesTab is using the TextAreaField.

If you relied on the inline flag of the old TextAreaField, you should refactor your code to use one of classes above.

Old code:

const field = new TextAreaField({
    inline : false
});

New code:

const field = new TextAreaPickerField({
    // ...
});

React wrappers now use module bundle

The React wrappers previously used the UMD bundle to import required classes:

Old code:

import { Model } from '@bryntum/grid/grid.umd.js';

UMD bundle is not used anymore in the wrappers so the import line in the above code needs to be changed:

New code:

import { Model } from '@bryntum/grid';

Imports from @bryntum/grid-react remain same.

WidgetColumn behaviour changes

WidgetColumn supports two-way binding since version 4.3.0. It uses the defaultBindProperty config of Widgets contained in it to determine how to apply a value. For fields the new behaviour should be straightforward to use, but if you are using a Button in it and are relying on the cell value being shown on the button you will have to adjust your code to use defaultBindProperty: 'text'.

Old code:

const grid = new Grid({
    columns : [{
        text  : 'Button',
        type  : 'widget',
        field : 'age',
        widgets : [
            {
                type     : 'button',
                icon     : 'b-fa b-fa-plus',
                onAction : () => {}
            }
        ]
    }]
});

New code:

const grid = new Grid({
    columns : [{
        text  : 'Button',
        type  : 'widget',
        field : 'age',
        widgets : [
            {
                type                : 'button',
                icon                : 'b-fa b-fa-plus',
                defaultBindProperty : 'text',
                onAction            : () => {}
            }
        ]
    }]
});

Grid v5.0.2

Widget.showByPoint() was deprecated

It has been replaced by Widget.showBy(), which can be called with the same signature as showByPoint(). Please update any usages in your code accordingly, the function will be removed in version 6.0.

Old code:

popup.showByPoint(100, 50);

New code:

popup.showBy(100, 50);

Grid v5.0.3

New Vue wrapper config option relayStoreEvents

This option was introduced to allow relaying of store events to the Grid instance. It defaults to false (no events relayed) which changes the default behavior so if your application relies on relayed events, configure it as true.

Example:

<bryntum-grid
    :relayStoreEvents="true"
>

The config option applies to both Vue 2 and Vue 3.

Grid v5.1.0

Responsive Mixin breakpoints Config is Deprecated

The breakpoints config was used to dynamically calculate config properties based on the widget's size. This config has been superseded by the responsive config.

Old code:

class ResponsiveButton extends Button.mixin(Responsive) {}

const button = new ResponsiveButton({
    breakpoints : {
        width : {
            // When width drops to 50 or below, hide text and show icon
            50 : {
                name    : 'small',
                configs : { text : null, icon : 'b-fa b-fa-plus' }
            },

            // When width is above 50, hide icon and show text
            '*' : {
                 name    : 'large',
                 configs : { text : 'Add', icon : null }
            }
        }
    }
});

New code:

class ResponsiveButton extends Button.mixin(Responsive) {}

const button = new ResponsiveButton({
    responsive : {
        // When width drops to 50 or below, hide text and show icon
        small : {
            when : 50,
            text : null,
            icon : 'b-fa b-fa-plus'
        },

        // When width is above 50, hide icon and show text
        '*' : {
            text : 'Add',
            icon : null
        }
    }
});

Responsive Mixin responsiveWidthChange and responsiveHeightChange Events are Deprecated

Along with the deprecation of the associated breakpoints config, these events have been replaced by the new responsiveStateChange event

Old code:

class ResponsiveButton extends Button.mixin(Responsive) {}

const button = new ResponsiveButton({
    breakpoints : {
        width : {
            // When width drops to 50 or below, hide text and show icon
            50 : {
                name    : 'small',
                configs : { text : null, icon : 'b-fa b-fa-plus' }
            },

            // When width is above 50, hide icon and show text
            '*' : {
                 name    : 'large',
                 configs : { text : 'Add', icon : null }
            }
        }
    },
    listeners : {
        responsiveWidthChange({ source, breakpoint, prevBreakpoint }) {
            // ...
        }
    }
});

New code:

class ResponsiveButton extends Button.mixin(Responsive) {}

const button = new ResponsiveButton({
    responsive : {
        // When width drops to 50 or below, hide text and show icon
        small : {
            when : 50,
            text : null,
            icon : 'b-fa b-fa-plus'
        },

        // When width is above 50, hide icon and show text
        '*' : {
            text : 'Add',
            icon : null
        }
    },
    listeners : {
        responsiveStateChange({ source, state, oldState }) {
            // ...
        }
    }
});

New module bundle for Angular

Bryntum Grid is now delivered with new ES Module bundle without WebComponents. This was done to avoid conflicts with Angular which also uses WebComponents for applications.

Angular wrappers use grid.module.js bundle in favor of removed grid.lite.umd.js one.

Your Angular applications should be upgraded to use the new grid.module.js bundle which is set as main for @bryntum/grid NPM package.

Replace all application imports from Bryntum packages as shown below:

Old code:

import { Grid } from '@bryntum/grid/grid.lite.umd.js';

New code:

import { Grid } from '@bryntum/grid';

New module bundle with WebComponents

Bryntum Grid is now delivered with new grid.wc.module.js ES Module bundle with WebComponents.

Your applications which use WebComponents and modules bundle should be upgraded to import from new grid.wc.module.js instead of grid.module.js.

Grid v5.2.0

Deprecated DomHelper.up()

The DomHelper.up() function was deprecated, since all supported browsers has native element.closest() which accomplishes the same thing.

Old code:

const rowElement = DomHelper.up(cellElement, '.b-grid-row');

New code:

const rowElement = cellElement.closest('.b-grid-row');

Asynchronous cell editing

CellEdit feature startEditing and finishEditing methods are now async.

finishEditing and cancelEditing methods are now exposed on Grid.

Old code:

if (grid.startEditing(...)) {
    // Do something
}
if (grid.features.cellEdit.finishEditing()) {
    // Do something
}

New code:

if (await grid.startEditing(...)) {
    // Do something
}
if (await grid.finishEditing()) {
    // Do something
}

Grid v5.2.0

The behaviour of the store.data getter will change in 6.0

Currently, it returns the initial raw dataset. For example:

const store = new Store({
    data : [
        { id : 1, name : 'Foo' },
        { id : 2, name : 'Bar' }
    ]
});

store.first.name = 'Baz';
store.last.remove();

// store.data returns the initial data
console.log(store.data); // [{ id : 1, name : 'Foo' }, { id : 2, name : 'Bar' }]

In 6.0 it will be changed to have the more expected behaviour of returning the data objects for the current state instead. The example above would instead log:

// [{ id : 1, name : 'Baz' }]

Grid v5.2.5

The default behaviour of the column renderer will change in 6.0

Currently, if a column defined renderer return undefined (or has no return statement) this will prevent the cell element content from being updated. This is useful if the cell element is mutated inside the renderer, which would otherwise be overwritten by the internal rendering later on.

Example of current default behaviour:

new Grid({
    columns : [{
        renderer({ record, cellElement }) {
            cellElement.appendChild(someElement);
            return undefined; // The return statement can also be omitted
        }
    }]
});

In 6.0, the cell content will by default always be updated after the renderer call. This means that there is no need for undefined checks like it was before.

const oldColumnConfig = { renderer : ({ record }) => record.myProperty ?? '' }
const newColumnConfig = { renderer : ({ record }) => record.myProperty }

For those cases when the cellElement content is directly manipulated inside the renderer simply set the new alwaysClearCell to false on the column. This config is available as of 5.2.5 and defaults to false. From 6.0 it will default to true. We recommend to set alwaysClearCell to false on every column that relies on the current default behaviour when updating to >= 5.2.5.

Example of future default behaviour:

new Grid({
    columns : [{
        alwaysClearCell : false,
        renderer({ record, cellElement }) {
            cellElement.appendChild(someElement);
            return undefined; // The return statement can also be ommitted
        }
    }]
});

Grid v5.3.0

Button, Checkbox, Radio, SlideToggle & Toast CSS changes

The CSS for these widgets was changed - instead of letting SASS generate CSS for the built-in color variations it now uses internal CSS variables.

The upside of this change is that it removes thousands of lines of CSS, while also making it easier for us to add more colors in the future.

We don't expect it to affect the styling of existing applications much, but if your application use custom styling for these widgets you might need to adjust the specificity of some selectors.

With the change, the following SCSS variables are no longer used and was removed:

$button-hover-lightness$button-pressed-lightness$button-active-lightness$button-pressed-hover-lightness$button-active-hover-lightness$button-pressed-active-lightness$button-pressed-active-hover-lightness$checkbox-checked-box-color$checkbox-checked-box-background-color$checkbox-checked-box-border-color$radio-background-color$radio-border-color$radio-dot-color$radio-checked-dot-color$radio-checked-border-color$radio-checked-background-color$radio-disabled-background-color
$radio-disabled-border-color

There is not a 1-1 mapping to anything in the updated CSS, therefor if you are using any of these SCSS variables we recommend checking the corresponding CSS files to figure out what to use instead (see button.scss, checkbox.scss, radio.scss). Or post a question on the forum.

Localization update

LocaleManager.registerLocale has been deprecated. LocaleHelper.publishLocale should be used instead.

Old code:

LocaleManager.registerLocale('Es', {
    desc : 'Spanish', locale : {
        localeName : 'Es',
        localeDesc : 'Spanish',
        locale     : {
            /* localization */
        }
    }
});

New code:

LocaleHelper.publishLocale({
    localeName : 'Es',
    localeDesc : 'Spanish',
    localeCode : 'es',
    /* localization */
});

LocaleManager.extendLocale has been deprecated. LocaleManager.applyLocale should be used instead.

Old code:

LocaleManager.extendLocale('Es', {
    desc : 'Spanish', locale : {
        locale : {
            /* localization */
        }
    }
});

New code:

LocaleManager.applyLocale({
    localeName : 'Es',
    localeDesc : 'Spanish',
    localeCode : 'es',
    /* localization */
});

Check our localization guide for the details.

Grid selectionMode changes

With the introduction of cell selection, Grid's selectionMode config no longer has the row setting. Instead, it is the default mode and can be omitted. Specifying cell : true will enable cell selection and disable row selection - both cannot be used at the same time.

While you don't actually have to change your code, the row setting no longer has any effect and can be removed:

Old code:

new Grid({
    selectionMode : {
        row : false,
        cell : true
    }
});

New code:

new Grid({
    selectionMode : {
        cell : true
    }
});

The rowCheckboxSelection setting of Grid's selectionMode config was renamed to checkboxOnly, to better indicate its purpose. Please update your code accordingly:

Old code:

new Grid({
    selectionMode : {
        rowCheckboxSelection : true
    }
});

New code:

new Grid({
    selectionMode : {
        checkboxOnly : true
    }
});

Deprecated menuContext.event

The event property available on the menuContext property of context menu features has been deprecated in favor of the domEvent property, to reduce risk of confusion with a Bryntum event object or an event record in Scheduler. If you are using it, please change your code to use domEvent instead.

Old code:

console.log(grid.features.cellMenu.menuContext.event);

New code:

console.log(grid.features.cellMenu.menuContext.domEvent);

GridFieldFilterPicker fields configuration type change

The type of the fields config for GridFieldFilterPicker and GridFieldFilterPickerGroup widgets has changed from array of FieldOptions to Object map of FieldOptions keyed by field name. The array type is now deprecated. The fields supplied in this config (if any) will now be merged with fields found in the configured grid's columns, instead of overwriting them.

Old code:

new GridFieldFilterPickerGroup({
    fields : [{
        name  : 'myStringField',
        type  : 'string'
    }, {
        name  : 'myNumberField',
        type  : 'number',
        title : 'MyNumber'
    }]
});

New code:

new GridFieldFilterPickerGroup({
    fields : {
        myStringField : {
            type  : 'string'
        },
        myNumberField : {
            type  : 'number',
            title : 'MyNumber'
        }
    }
});

Grid v5.3.3

RowReorder events are now fired on the Grid instance

Old code:

const grid = new Grid({
    appendTo : 'container',
    features : {
        rowReorder : {
            showGrip  : true,
            listeners : {
                gridRowBeforeDropFinalize : async({ context }) => {
                    if (grid.widgetMap.confirmationButton.checked) {
                        const result = await MessageDialog.confirm({
                            title   : 'Please confirm',
                            message : 'Did you want the row here?'
                        });

                        // Return true to accept the drop or false to reject it
                        return result === MessageDialog.yesButton;
                    }
                }
            }
        }
    }
})

New code:

const grid = new Grid({
    appendTo : 'container',
    features : {
        rowReorder : {
            showGrip  : true
        }
    },
    listeners : {
        gridRowBeforeDropFinalize : async({ context }) => {
            if (grid.widgetMap.confirmationButton.checked) {
                const result = await MessageDialog.confirm({
                    title   : 'Please confirm',
                    message : 'Did you want the row here?'
                });

                // Return true to accept the drop or false to reject it
                return result === MessageDialog.yesButton;
            }
        }
    }
})

Angular View Engine wrappers

New @bryntum/grid-angular-view is designed to work with Angular 11 and older versions, which use the View Engine for rendering. If you are using one of the legacy Angular versions, please follow these steps to use the package:

Install the package using npm:

npm install @bryntum/grid-angular-view@5.3.3

Import the component in your Angular application:

import { BryntumGridComponent } from '@bryntum/grid-angular-view';

Do not forget to remove previously used @bryntum/grid-angular package which requires Angular 12 or newer version.

Please check Angular integration guide for additional information.

Grid v5.3.7

Sort feature now creates sorting icon element in header cell.

The CSS to create and show the arrow icon to indicate sort direction is now a :before pseudo element of a child element of the header text element. There is now an addressable .b-sort-icon node inside the cell which may be targeted by application CSS.

In previous versions, the arrow icon was a :before pseudo element of the header text element and not addressable by application code or CSS.

Grid v5.3.8

RowExpander feature auto scrolling now defaults to false

Previously, when expanding a row and the expanded body element is not completely in view, the RowExpander feature would scroll that element into view automatically. Now, this behaviour will need to be activated by setting the autoScroll config on the RowExpander feature to true.

Grid v5.4.0

RowCopyPaste has been made asynchronous

The RowCopyPaste feature's copyRows and pasteRows has been made asynchronous. This makes the beforeCopy and beforePaste events asynchronously preventable and allows for native Clipboard API support.

If your code relies on a copy or paste action to complete, you will need to wait for the promise to be resolved.

Old code:

function copyPaste()
{
    grid.copyRows();
    doSomethingElse();
    grid.pasteRows();
    finishDoingSomethingElse();
}

New code:

async function copyPaste()
{
    await grid.copyRows();
    doSomethingElse();
    await grid.pasteRows();
    finishDoingSomethingElse();
}

…or…

function copyPaste()
{
    return grid.copyRows().then(() => {
        doSomethingElse();
        grid.pasteRows().then(() => {
            finishDoingSomethingElse();
            return true;
        });
    });
}

Grid v5.5.5

The autoClose config of PickerField was deprecated

The autoClose config of PickerField controls if the picker is hidden when the user clicks outside of the picker. Setting it to false leads to a non-intuitive behavior, which we no longer want to support. The config has been deprecated and will be removed in 6.0

Grid v5.6.0

New location for Core.util.helper.Point class

The Core.util.helper.Point class has been moved to solve circular module dependencies. It is now a named (Point) export of the Core.util.helper.Rectangle module.

Changes are required if you are directly importing the class from sources:

Old code:

import Point from 'path-to-lib/Core/helper/util/Point.js';

New code:

import { Point } from 'path-to-lib/Core/helper/util/Rectangle.js';

Note: No changes required for importing from module or umd bundles.

Export dialog values API has changed

Earlier implementation of values API applied transformation to the field names: orientationField -> orientation. We rolled it back to default implementation used by Container and solved this task by providing a name field on every default widget. If you added more widgets to the default dialog, check the values object of the dialog, you might need to configure name.

Filter feature changed to multi-filter by default

The Filter feature has changed to use the new FieldFilterPicker-based UI in its popup by default. (This mode was previously accessible using the isMulti flag, which is now deprecated.)

The feature's context menus have also changed. Now, when right-clicking a grid cell or column header, the filtering options are under a new Filter sub-menu. The available filter operators have also changed to match the ones available in the FieldFilterPicker for the column's data type.

To provide custom configuration for the GridFieldFilterPickerGroup used in the popup UI, pass the new pickerConfig config to the Filter feature.

If you are using the isMulti flag in your Filter feature config, you can remove it as this mode is now the default.

  • Old isMulti feature configuration:
{
  features : {
    filter : { isMulti : true }
  }
}
  • New feature configuration (isMulti flag no longer required):
{
  features : {
    filter : true
  }
}

To use the old UI instead, configure legacyMode : true on the Filter feature.

  • Old feature configuration:
{
  features : {
    filter : true
  }
}
  • New feature configuration (to opt out of new UI and keep the old):
{
  features : {
    filter : {
      legacyMode : true
    }
  }
}

Grid v5.6.4

DomHelper.focusWithoutScrolling deprecated

DomHelper.focusWithoutScrolling is deprecated because the native Element focus method now supports the preventScroll option on all platforms.

DomHelper.focusWithoutScrolling(myElement);

Should be changed to

myElement.focus({ preventScroll : true });

Contents