All Components

Master-Detail Grids

The Grid provides options for visualizing the relations between its parent and child records by displaying the table data in a hierarchical order.

To apply a hierarchical order to the desired records, use the detail property of the master Grid. The feature allows you to load the detail component which contains the corresponding child Grid records that are filtered by the parent key field value.

import React from 'react';
import ReactDOM from 'react-dom';
import { Grid, GridColumn as Column, GridDetailRow } from '@progress/kendo-react-grid';

class DetailComponent extends GridDetailRow {
    render() {
        return (
            <Grid data={this.props.dataItem.details}>
                <Column field="ProductID" title="Product ID" width="120px" />
                <Column field="ProductName" title="Product Name" />
                <Column field="UnitPrice" title="Unit Price" format="{0:c}" />
            </Grid>
        );
    }
}

class App extends React.Component {
    baseUrl = `https://odatasampleservices.azurewebsites.net/V4/Northwind/Northwind.svc/`;
    init = { method: 'GET', accept: 'application/json', headers: {} };

    constructor(props) {
        super(props);
        this.state = {
            categories: []
        };
        this.expandChange = this.expandChange.bind(this);
    }

    expandChange(event) {
        let dataItem = event.dataItem;
        dataItem.expanded = !dataItem.expanded;
        this.forceUpdate();
        if (!dataItem.expanded) {
            return;
        }
        fetch(this.baseUrl + `Products?$filter=CategoryID%20eq%20` + dataItem.CategoryID, this.init)
            .then(response => response.json())
            .then(json => {
                let data = this.state.categories.slice();
                let index = data.findIndex(d => d.CategoryID === dataItem.CategoryID);
                data[index].details = json.value;
                this.setState({ categories: data });
            });
    }

    componentDidMount() {
        fetch(this.baseUrl + `Categories`, this.init)
            .then(response => response.json())
            .then(json => this.setState({ categories: json.value }));
    }

    render() {
        return (
            <div>
                <Grid
                    style={{ height: '550px' }}
                    data={this.state.categories}
                    detail={DetailComponent}
                    expandField="expanded"
                    expandChange={this.expandChange}
                >
                    <Column field="CategoryID" title="ID" width="50px" />
                    <Column field="CategoryName" width="200px" title="Category Name" />
                    <Column field="Description" />
                </Grid>
            </div>
        );
    }
}

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