Locked Columns

Locked (frozen or sticky) columns are the columns that are visible at all times while the user scrolls the Grid horizontally.

By default, the columns of the Grid are not locked. The locked columns require all columns to have a fixed width.

import React from 'react';
import ReactDOM from 'react-dom';
import { Grid, GridColumn as Column } from '@progress/kendo-react-grid';
import { Button } from '@progress/kendo-react-buttons';
import products from './products.json';

class App extends React.Component {
    state = {
        locked: false
    }

    handleClick = () => {
        this.setState({ locked: !this.state.locked });
    }

    render() {
        return (
            <div>
                <div className="mb-3">
                    <div className="mb-2">
                        <Button primary="true"
                            onClick={this.handleClick}>
                            Lock / Unlock Additional details Column
                        </Button>
                    </div>

                    <div className={'w-50 alert ' + (this.state.locked ? 'alert-success' : 'alert-danger')}>
                        The Additional details Column is
                        <strong className="text-muted">
                            {this.state.locked ? " Frozen" : " Unfrozen"}
                        </strong>
                    </div>
                </div>
                <Grid
                    style={{ height: 350 }}
                    data={products}
                    reorderable={true}
                >
                    <Column field="ProductID" title="ID" width="45px" locked={true} />
                    <Column field="ProductName" title="Name" width="250px" />
                    <Column field="Category.CategoryName" title="CategoryName" width="250px" locked={true} />
                    <Column field="UnitPrice" title="Price" width="90px" />
                    <Column field="UnitsInStock" title="In stock" width="90px" />
                    <Column field="UnitsOnOrder" title="On order" width="90px" />
                    <Column field="Discontinued" width="120px" />
                    <Column field="QuantityPerUnit" title="Additional details" width="250px" locked={this.state.locked} />
                </Grid>
            </div>
        );
    }
}

ReactDOM.render(
    <App />,
    document.querySelector('my-app')
);

Locked Columns With Column Menu

The [columnMenu]({ slug column_menu_grid }) can be used to render buttons that will lock and unlock a specific column on click.

In the following example we:

  1. Render a custom component inside the column menu that will locked and unlocked the column.
  2. Update the columns collection when a column is locked/unlocked.
  3. Sort them by the locked field to show all locked columns on the left.
import React from "react";
import ReactDOM from "react-dom";
import { Grid, GridColumn as Column } from "@progress/kendo-react-grid";

import { CustomColumnMenu } from "./customColumnMenu.jsx";

import products from "./products.json";
import columns from "./lockedColumns.js";

import { orderBy, process } from "@progress/kendo-data-query";

class App extends React.Component {
    state = {
        columns: columns,
        dataState: {
            take: 8,
            skip: 0
        }
    };

    dataStateChange = event => {
        this.setState({ dataState: event.data });
    };

    handleColumnLockToggle = (columnField, state) => {
        this.setState({
            columns: this.state.columns.map(column => {
                if (column.field === columnField) {
                    column.locked = state
                }
                return column
            })
        });
    };

    render() {
        // place all locked columns first
        let sortedColumns = orderBy(this.state.columns, [
            { field: "locked", dir: "desc" }
        ]);
        return (
            <div>
                <Grid
                    data={process(products, this.state.dataState)}
                    {...this.state.dataState}
                    onDataStateChange={this.dataStateChange}
                    sortable={true}
                    pageable={{ type: 'input' }}
                    pageSize={8}
                    style={{height: 450}}
                >
                    {sortedColumns.map((column, idx) => (
                        <Column
                            key={idx}
                            field={column.field}
                            title={column.title}
                            filter={column.filter}
                            locked={column.locked}
                            width={column.width}
                            columnMenu={props => (
                                <CustomColumnMenu
                                    {...props}
                                    onColumnLockToggle={this.handleColumnLockToggle}
                                    locked={column.locked}
                                />
                            )}
                        />
                    ))}
                </Grid>
                <br />
            </div>
        );
    }
}

ReactDOM.render(<App />, document.querySelector("my-app"));

Locked Column With Custom Cell

When using the locked columns with a custom cell the specific styles and classes have to be added to the td elements. The classes and the styles will be part of the cell props.