Skip to content

Nested Grid - Display Hierarchical Data

The Nested Grid allows you to display hierarchical data by embedding RevoGrids inside cells. This is particularly useful when you need to show detailed, structured data within a cell, such as project details, task lists, or any other nested data structure.

Live Demo

Here’s a live example showing how nested grids can be used to display project tasks, along with row expansion capabilities:

Row Expansion

The Nested Grid combined with the Row Expansion plugin to provide a more interactive experience. Row expansion allows users to expand a row to reveal additional details or nested grids.

Enabling Row Expansion

To enable row expansion, you can configure the grid as follows:

import { RowExpandPlugin } from '@revolist/revogrid-pro';
grid.plugins = [RowExpandPlugin];

Example Configuration

Here’s an example of how to set up row expansion with nested grids:

grid.columns = [
{ prop: 'id', name: 'ID', expand: true }, // Enable row expansion for this column
{ prop: 'name', name: 'Name' },
{
prop: 'details',
name: 'Details',
}
];
// Additional configuration for row expansion
grid.additionalData = {
rowExpand: {
expandedRows: new Set([1]), // Example of expanded rows
expandedRowHeight: 200, // Height for the expanded row
// Hide expand toggle based on row data
hideExpand: (rowIndex, model) => {
// Example: Hide expand toggle for rows without tasks
return !model.tasks || model.tasks.length === 0;
},
template: (h, props) => {
return h('revo-grid', {
key: 'nested-grid',
class: 'mt-1',
style: {
height: '100%',
maxHeight: '90%',
maxWidth: '95%',
},
theme: isDark() ? 'darkCompact' : 'compact',
resize: true,
readonly: true,
columns: [
{ prop: 'id', name: '#', size: 50 },
{ prop: 'task', name: 'Task', size: 220 },
{
prop: 'status',
name: 'Status',
size: 150,
cellProperties: ({ value }) => ({
style: {
color: '#fff',
backgroundColor: value === 'Complete' ? '#00c874' : value === 'In Progress' ? '#fdaa3d' : '#e2435c',
},
}),
},
],
source: props.model.tasks, // Source data for the nested grid
hideAttribution: true,
});
},
},
};

Configuration Options

The nested grid configuration supports all standard RevoGrid properties. Here are some commonly used options:

  • columns: Array of column definitions for the nested grid
  • source: Function that returns the data array for the nested grid
  • theme: Theme to apply to nested grids
  • readonly: Whether the nested grid should be read-only
  • rowSize: Height of rows in the nested grid
  • resize: Enable column resizing in nested grid
  • Any other RevoGrid properties you want to apply to nested grids

Row Expansion Options

The row expansion configuration supports several options to control expansion behavior:

  • expandedRows: Set of row IDs that should be expanded by default
  • expandedRowHeight: Height for expanded rows (in pixels)
  • hideExpand: Controls visibility of expand toggle buttons, can be:
    • A boolean: true to hide all expand toggles
    • A function: (rowIndex: number, model: any) => boolean for conditional control

Example of conditional expand toggle visibility:

grid.additionalData = {
rowExpand: {
// Hide expand toggle for rows that don't have nested data
hideExpand: (rowIndex, model) => {
return !model.hasNestedData || model.tasks?.length === 0;
},
// ... other configuration options
}
};

Best Practices

  1. Data Structure: Organize your data hierarchically with clear parent-child relationships.
  2. Performance: Consider the following for optimal performance:
    • Limit the number of nested grids visible at once
    • Keep nested data sets reasonably sized
    • Use read-only mode for nested grids if editing isn’t required
  3. Responsive Design: Ensure columns with nested grids have sufficient width.
  4. User Experience: Use row expansion judiciously to enhance user interaction without overwhelming them with too much information at once.

Advanced Usage

Custom Cell Templates

You can combine nested grids with custom cell templates for rich data visualization:

{
prop: 'progress',
name: 'Progress',
cellTemplate: (h, props) => {
const progress = props.model[props.prop] || 0;
return h('div', {
style: {
width: '100%',
height: '100%'
}
}, [
h('div', {
style: {
width: `${progress}%`,
backgroundColor: progress === 100 ? '#4CAF50' : '#2196F3'
}
})
]);
}
}