React Tree Grid Multi-Column Headers Overview
The Ignite UI for React Multi-Column Headers feature in React Tree Grid allows you to group columns by placing them under a common multi-header. Each multi-column headers group in the IgrTreeGrid
could be a representation of combinations between other groups or columns. This feature is particularly useful when dealing with large datasets where scrolling horizontally might be cumbersome.
React Tree Grid Multi-Column Headers Example
export class EmployeesFlatDetailsItem {
public constructor(init: Partial<EmployeesFlatDetailsItem>) {
Object.assign(this, init);
}
public Address: string;
public Age: number;
public City: string;
public Country: string;
public Fax: string;
public HireDate: string;
public ID: number;
public Name: string;
public ParentID: number;
public Phone: string;
public PostalCode: number;
public Title: string;
public LastName: string;
public FullAddress: string;
}
export class EmployeesFlatDetails extends Array<EmployeesFlatDetailsItem> {
public constructor(items: Array<EmployeesFlatDetailsItem> | number = -1) {
if (Array.isArray(items)) {
super(...items);
} else {
const newItems = [
new EmployeesFlatDetailsItem(
{
Address: `Obere Str. 57`,
Age: 55,
City: `Berlin`,
Country: `Germany`,
Fax: `030-0076545`,
HireDate: `2008-03-20`,
ID: 1,
Name: `Johnathan Winchester`,
ParentID: -1,
Phone: `030-0074321`,
PostalCode: 12209,
Title: `Development Manager`,
LastName: `Winchester`,
FullAddress: `Obere Str. 57, Berlin, Germany`
}),
new EmployeesFlatDetailsItem(
{
Address: `Avda. de la Constitución 2222`,
Age: 42,
City: `México D.F.`,
Country: `Mexico`,
Fax: `(51) 555-3745`,
HireDate: `2014-01-22`,
ID: 4,
Name: `Ana Sanders`,
ParentID: -1,
Phone: `(5) 555-4729`,
PostalCode: 5021,
Title: `CEO`,
LastName: `Sanders`,
FullAddress: `Avda. de la Constitución 2222, México D.F., Mexico`
}),
new EmployeesFlatDetailsItem(
{
Address: `Mataderos 2312`,
Age: 49,
City: `México D.F.`,
Country: `Mexico`,
Fax: `(5) 555-3995`,
HireDate: `2014-01-22`,
ID: 18,
Name: `Victoria Lincoln`,
ParentID: -1,
Phone: `(5) 555-3932`,
PostalCode: 5023,
Title: `Accounting Manager`,
LastName: `Lincoln`,
FullAddress: `Mataderos 2312, México D.F., Mexico`
}),
new EmployeesFlatDetailsItem(
{
Address: `120 Hanover Sq.`,
Age: 61,
City: `London`,
Country: `UK`,
Fax: `(171) 555-6750`,
HireDate: `2010-01-01`,
ID: 10,
Name: `Yang Wang`,
ParentID: -1,
Phone: `(171) 555-7788`,
PostalCode: 39000,
Title: `Localization Manager`,
LastName: `Wang`,
FullAddress: `120 Hanover Sq., London, UK`
}),
new EmployeesFlatDetailsItem(
{
Address: `Berguvsvägen 8`,
Age: 43,
City: `Luleå`,
Country: `Sweden`,
Fax: `0921-12 34 67`,
HireDate: `2011-06-03`,
ID: 3,
Name: `Michael Burke`,
ParentID: 1,
Phone: `0921-12 34 65`,
PostalCode: 29000,
Title: `Senior Software Developer`,
LastName: `Burke`,
FullAddress: `Berguvsvägen 8, Luleå, Sweden`
}),
new EmployeesFlatDetailsItem(
{
Address: `Forsterstr. 57`,
Age: 29,
City: `Mannheim`,
Country: `Germany`,
Fax: `0621-08924`,
HireDate: `2009-06-19`,
ID: 2,
Name: `Thomas Anderson`,
ParentID: 1,
Phone: `0621-08460`,
PostalCode: 68306,
Title: `Senior Software Developer`,
LastName: `Anderson`,
FullAddress: `Forsterstr. 57, Mannheim, Germany`
}),
new EmployeesFlatDetailsItem(
{
Address: `24, place Kléber`,
Age: 31,
City: `Strasbourg`,
Country: `France`,
Fax: `88.60.15.32`,
HireDate: `2014-08-18`,
ID: 11,
Name: `Monica Reyes`,
ParentID: 1,
Phone: `88.60.15.31`,
PostalCode: 67000,
Title: `Software Development Team Lead`,
LastName: `Reyes`,
FullAddress: `24, place Kléber, Strasbourg, France`
}),
new EmployeesFlatDetailsItem(
{
Address: `C/ Araquil, 67`,
Age: 35,
City: `Madrid`,
Country: `Spain`,
Fax: `(911) 555 91 99`,
HireDate: `2015-09-17`,
ID: 6,
Name: `Roland Mendel`,
ParentID: 11,
Phone: `(91) 555 22 82`,
PostalCode: 28023,
Title: `Senior Software Developer`,
LastName: `Mendel`,
FullAddress: `C/ Araquil, 67, Madrid, Spain`
}),
new EmployeesFlatDetailsItem(
{
Address: `12, rue des Bouchers`,
Age: 44,
City: `Marseille`,
Country: `France`,
Fax: `91.24.45.41`,
HireDate: `2009-10-11`,
ID: 12,
Name: `Sven Cooper`,
ParentID: 11,
Phone: `91.24.45.40`,
PostalCode: 13008,
Title: `Senior Software Developer`,
LastName: `Cooper`,
FullAddress: `12, rue des Bouchers, Marseille, France`
}),
new EmployeesFlatDetailsItem(
{
Address: `23 Tsawassen Blvd.`,
Age: 44,
City: `Tsawassen`,
Country: `Canada`,
Fax: `(604) 555-3745`,
HireDate: `2014-04-04`,
ID: 14,
Name: `Laurence Johnson`,
ParentID: 4,
Phone: `(604) 555-4729`,
PostalCode: 19000,
Title: `Director`,
LastName: `Johnson`,
FullAddress: `23 Tsawassen Blvd., Tsawassen, Canada`
}),
new EmployeesFlatDetailsItem(
{
Address: `Fauntleroy Circus`,
Age: 25,
City: `London`,
Country: `UK`,
Fax: `(125) 555-3798`,
HireDate: `2017-11-9`,
ID: 5,
Name: `Elizabeth Richards`,
ParentID: 4,
Phone: `(171) 555-1212`,
PostalCode: 30000,
Title: `Vice President`,
LastName: `Richards`,
FullAddress: `Fauntleroy Circus, London, UK`
}),
new EmployeesFlatDetailsItem(
{
Address: `Cerrito 333`,
Age: 39,
City: `Buenos Aires`,
Country: `Argentina`,
Fax: `(121) 135-4892`,
HireDate: `2010-03-22`,
ID: 13,
Name: `Trevor Ashworth`,
ParentID: 5,
Phone: `(1) 135-5555`,
PostalCode: 1010,
Title: `Director`,
LastName: `Ashworth`,
FullAddress: `Cerrito 333, Buenos Aires, Argentina`
}),
new EmployeesFlatDetailsItem(
{
Address: `Sierras de Granada 9993`,
Age: 44,
City: `México D.F.`,
Country: `Mexico`,
Fax: `(153) 555-7293`,
HireDate: `2014-04-04`,
ID: 17,
Name: `Antonio Moreno`,
ParentID: 18,
Phone: `(5) 555-3392`,
PostalCode: 5022,
Title: `Senior Accountant`,
LastName: `Moreno`,
FullAddress: `Sierras de Granada 9993, México D.F., Mexico`
}),
new EmployeesFlatDetailsItem(
{
Address: `Hauptstr. 29`,
Age: 50,
City: `Sao Paulo`,
Country: `Brazil`,
Fax: `(531) 555-6691`,
HireDate: `2007-11-18`,
ID: 7,
Name: `Pedro Rodriguez`,
ParentID: 10,
Phone: `0452-076545`,
PostalCode: 3012,
Title: `Senior Localization Developer`,
LastName: `Rodriguez`,
FullAddress: `Hauptstr. 29, Sao Paulo, Brazil`
}),
new EmployeesFlatDetailsItem(
{
Address: `Av. dos Lusíadas, 23`,
Age: 27,
City: `Bern`,
Country: `Switzerland`,
Fax: `(271) 335-357`,
HireDate: `2016-02-19`,
ID: 8,
Name: `Casey Harper`,
ParentID: 10,
Phone: `(11) 555-7647`,
PostalCode: 40000,
Title: `Senior Localization`,
LastName: `Harper`,
FullAddress: `Av. dos Lusíadas, 23, Bern, Switzerland`
}),
new EmployeesFlatDetailsItem(
{
Address: `Berkeley Gardens 12`,
Age: 25,
City: `London`,
Country: `UK`,
Fax: `(171) 555-9199`,
HireDate: `2017-11-09`,
ID: 15,
Name: `Patricia Simpson`,
ParentID: 7,
Phone: `(171) 555-2282`,
PostalCode: 26000,
Title: `Localization Intern`,
LastName: `Simpson`,
FullAddress: `Berkeley Gardens 12, London, UK`
}),
new EmployeesFlatDetailsItem(
{
Address: `Walserweg 21`,
Age: 39,
City: `Aachen`,
Country: `Germany`,
Fax: `0241-059428`,
HireDate: `2010-03-22`,
ID: 9,
Name: `Francisco Chang`,
ParentID: 7,
Phone: `0241-039123`,
PostalCode: 52066,
Title: `Localization Intern`,
LastName: `Chang`,
FullAddress: `Walserweg 21, Aachen, Germany`
}),
new EmployeesFlatDetailsItem(
{
Address: `35 King George`,
Age: 25,
City: `London`,
Country: `UK`,
Fax: `(171) 555-3373`,
HireDate: `2018-03-18`,
ID: 16,
Name: `Peter Lewis`,
ParentID: 7,
Phone: `(171) 555-0297`,
PostalCode: 48000,
Title: `Localization Intern`,
LastName: `Lewis`,
FullAddress: `35 King George, London, UK`
}),
];
super(...newItems.slice(0));
}
}
}
tsimport React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrGridModule, IgrColumnGroupModule } from "@infragistics/igniteui-react-grids";
import { IgrPropertyEditorPanelModule } from "@infragistics/igniteui-react-layouts";
import { IgrPropertyEditorPanel, IgrPropertyEditorPropertyDescription } from "@infragistics/igniteui-react-layouts";
import { IgrTreeGrid, IgrColumn, IgrColumnGroup } from "@infragistics/igniteui-react-grids";
import { ComponentRenderer, WebGridDescriptionModule, WebColumnGroupDescriptionModule, PropertyEditorPanelDescriptionModule } from "@infragistics/igniteui-react-core";
import { EmployeesFlatDetailsItem, EmployeesFlatDetails } from './EmployeesFlatDetails';
import { IgrPropertyEditorPropertyDescriptionButtonClickEventArgs } from "@infragistics/igniteui-react-layouts";
import "@infragistics/igniteui-react-grids/grids/combined";
import "@infragistics/igniteui-react-grids/grids/themes/light/bootstrap.css";
import 'igniteui-webcomponents/themes/light/bootstrap.css';
const mods: any[] = [
IgrGridModule,
IgrColumnGroupModule,
IgrPropertyEditorPanelModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component<any, any> {
private propertyEditor: IgrPropertyEditorPanel
private propertyEditorRef(r: IgrPropertyEditorPanel) {
this.propertyEditor = r;
this.setState({});
}
private propertyEditorPropertyDescription1: IgrPropertyEditorPropertyDescription
private propertyEditorPropertyDescription2: IgrPropertyEditorPropertyDescription
private treeGrid: IgrTreeGrid
private treeGridRef(r: IgrTreeGrid) {
this.treeGrid = r;
this.setState({});
}
constructor(props: any) {
super(props);
this.propertyEditorRef = this.propertyEditorRef.bind(this);
this.webTreeGridPinFirstGroupToggle = this.webTreeGridPinFirstGroupToggle.bind(this);
this.webTreeGridHideFirstGroupToggle = this.webTreeGridHideFirstGroupToggle.bind(this);
this.treeGridRef = this.treeGridRef.bind(this);
}
public render(): JSX.Element {
return (
<div className="container sample ig-typography">
<div className="options vertical">
<IgrPropertyEditorPanel
ref={this.propertyEditorRef}
componentRenderer={this.renderer}
target={this.treeGrid}
descriptionType="WebTreeGrid"
isHorizontal="true"
isWrappingEnabled="true">
<IgrPropertyEditorPropertyDescription
valueType="Button"
primitiveValue="Toggle First Group Pinned"
buttonClicked={this.webTreeGridPinFirstGroupToggle}
name="propertyEditorPropertyDescription1">
</IgrPropertyEditorPropertyDescription>
<IgrPropertyEditorPropertyDescription
valueType="Button"
primitiveValue="Toggle First Group Hidden"
buttonClicked={this.webTreeGridHideFirstGroupToggle}
name="propertyEditorPropertyDescription2">
</IgrPropertyEditorPropertyDescription>
</IgrPropertyEditorPanel>
</div>
<div className="container fill">
<IgrTreeGrid
autoGenerate="false"
data={this.employeesFlatDetails}
ref={this.treeGridRef}
id="treeGrid"
primaryKey="ID"
foreignKey="ParentID">
<IgrColumn
field="Name"
resizable="true">
</IgrColumn>
<IgrColumnGroup
header="General Information">
<IgrColumn
field="HireDate"
sortable="true"
resizable="true">
</IgrColumn>
<IgrColumnGroup
header="Personal Details">
<IgrColumn
field="ID"
sortable="true"
resizable="true">
</IgrColumn>
<IgrColumn
field="Title"
sortable="true"
resizable="true">
</IgrColumn>
<IgrColumn
field="Age"
sortable="true"
resizable="true">
</IgrColumn>
</IgrColumnGroup>
</IgrColumnGroup>
<IgrColumnGroup
header="Address Information">
<IgrColumnGroup
header="Location">
<IgrColumn
field="Country"
sortable="true"
resizable="true">
</IgrColumn>
<IgrColumn
field="City"
sortable="true"
resizable="true">
</IgrColumn>
<IgrColumn
field="Address"
sortable="true"
resizable="true">
</IgrColumn>
</IgrColumnGroup>
<IgrColumnGroup
header="Contact Information">
<IgrColumn
field="Phone"
sortable="true"
resizable="true">
</IgrColumn>
<IgrColumn
field="Fax"
sortable="true"
resizable="true">
</IgrColumn>
<IgrColumn
field="PostalCode"
sortable="true"
resizable="true">
</IgrColumn>
</IgrColumnGroup>
</IgrColumnGroup>
</IgrTreeGrid>
</div>
</div>
);
}
private _employeesFlatDetails: EmployeesFlatDetails = null;
public get employeesFlatDetails(): EmployeesFlatDetails {
if (this._employeesFlatDetails == null)
{
this._employeesFlatDetails = new EmployeesFlatDetails();
}
return this._employeesFlatDetails;
}
private _componentRenderer: ComponentRenderer = null;
public get renderer(): ComponentRenderer {
if (this._componentRenderer == null) {
this._componentRenderer = new ComponentRenderer();
var context = this._componentRenderer.context;
WebGridDescriptionModule.register(context);
WebColumnGroupDescriptionModule.register(context);
PropertyEditorPanelDescriptionModule.register(context);
}
return this._componentRenderer;
}
public webTreeGridPinFirstGroupToggle(sender: any, args: IgrPropertyEditorPropertyDescriptionButtonClickEventArgs): void {
const grid: IgrTreeGrid = this.treeGrid;
const firstColumnGroup = grid.getColumnByName("HireDate").parent;
firstColumnGroup.pinned = !firstColumnGroup.pinned;
grid.markForCheck();
}
public webTreeGridHideFirstGroupToggle(sender: any, args: IgrPropertyEditorPropertyDescriptionButtonClickEventArgs): void {
const grid: IgrTreeGrid = this.treeGrid;
const firstColumnGroup = grid.getColumnByName("HireDate").parent;
firstColumnGroup.hidden = !firstColumnGroup.hidden;
grid.markForCheck();
}
}
// rendering above component in the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Sample/>);
tsx/* shared styles are loaded from: */
/* https://static.infragistics.com/xplatform/css/samples */
css
Like this sample? Get access to our complete Ignite UI for React toolkit and start building your own apps in minutes. Download it for free.
The declaration of multi-column headers is achieved by wrapping a set of columns into an IgrColumnGroup
component with IgrHeader
title information passed.
<IgrTreeGrid primaryKey="ID" foreignKey="ParentID">
<IgrColumnGroup header="Contact Information">
<IgrColumn sortable="true" resizable="true" field="Phone" dataType={GridColumnDataType.String}></IgrColumn>
<IgrColumn sortable="true" resizable="true" field="Fax" dataType={GridColumnDataType.String}></IgrColumn>
<IgrColumn sortable="true" resizable="true" field="PostalCode" dataType={GridColumnDataType.String}></IgrColumn>
</IgrColumnGroup>
</IgrTreeGrid>
tsx
For achieving n-th
level of nested headers, the declaration above should be followed. So by nesting IgrColumnGroup
leads to the desired result.
<IgrTreeGrid primaryKey="ID" foreignKey="ParentID" moving="true">
<IgrColumnGroup pinned="false" header="General Information">
<IgrColumn field="HireDate" sortable="true" resizable="true" dataType={GridColumnDataType.Date}></IgrColumn>
<IgrColumnGroup header="Person Details">
<IgrColumn field="ID" resizable="true" filterable="true" dataType={GridColumnDataType.Number}></IgrColumn>
<IgrColumn field="Title" sortable="true" resizable="true" dataType={GridColumnDataType.String}></IgrColumn>
<IgrColumn field="Age" sortable="true" resizable="true" dataType={GridColumnDataType.Number}></IgrColumn>
</IgrColumnGroup>
</IgrColumnGroup>
</IgrTreeGrid>
tsx
Every IgrColumnGroup
supports moving, pinning and hiding.
When there is a set of columns and column groups, pinning works only for top level column parents. More specifically pinning per nested column groups or columns is not allowed. Moving between columns and column groups is allowed only when they are at the same level in the hierarchy and both are in the same group. When columns/column-groups are not wrapped by current group which means they are top level columns, moving is allowed between whole visible columns.
<IgrTreeGrid primaryKey="ID" foreignKey="ParentID" moving="true">
<IgrColumnGroup header="Contact Information">
<IgrColumn field="Phone" movable="true" sortable="true" resizable="true" dataType={GridColumnDataType.String}></IgrColumn>
</IgrColumnGroup>
<IgrColumn field="Name" sortable="true" resizable="true" dataType={GridColumnDataType.String}></IgrColumn>
<IgrColumn field="Title" sortable="true" resizable="true" dataType={GridColumnDataType.String}></IgrColumn>
<IgrColumn field="Age" sortable="true" resizable="true" dataType={GridColumnDataType.Number}></IgrColumn>
</IgrTreeGrid>
tsx
Multi-Column Header Template
<IgrColumnGroup header="Contact Information" headerTemplate={groupHeaderTemplate}></IgrColumnGroup>
tsx
function groupHeaderTemplate(e: { dataContext: IgrColumnTemplateContext }) {
const column = e.dataContext.column as IgrColumnGroup;
return (
<div>
<span style={{ float: "left" }}>{column.header.toUpperCase()}</span>
</div>
);
}
tsx
If a header is re-templated and the corresponding column group is movable, you have to set the draggable attribute to false on the templated elements, so that you can handle any of the events that are applied!
function columnHeaderTemplate(e: { dataContext: IgrColumnTemplateContext }) {
const column = e.dataContext.column as IgrColumnGroup;
return (
<span onClick={onClick}>
<IgrIcon data-draggable="false"></IgrIcon>
</span>
);
}
tsx
The following sample demonstrates how to implement collapsible column groups using header templates.
export class EmployeesFlatDetailsItem {
public constructor(init: Partial<EmployeesFlatDetailsItem>) {
Object.assign(this, init);
}
public Address: string;
public Age: number;
public City: string;
public Country: string;
public Fax: string;
public HireDate: string;
public ID: number;
public Name: string;
public ParentID: number;
public Phone: string;
public PostalCode: number;
public Title: string;
public LastName: string;
public FullAddress: string;
}
export class EmployeesFlatDetails extends Array<EmployeesFlatDetailsItem> {
public constructor(items: Array<EmployeesFlatDetailsItem> | number = -1) {
if (Array.isArray(items)) {
super(...items);
} else {
const newItems = [
new EmployeesFlatDetailsItem(
{
Address: `Obere Str. 57`,
Age: 55,
City: `Berlin`,
Country: `Germany`,
Fax: `030-0076545`,
HireDate: `2008-03-20`,
ID: 1,
Name: `Johnathan Winchester`,
ParentID: -1,
Phone: `030-0074321`,
PostalCode: 12209,
Title: `Development Manager`,
LastName: `Winchester`,
FullAddress: `Obere Str. 57, Berlin, Germany`
}),
new EmployeesFlatDetailsItem(
{
Address: `Avda. de la Constitución 2222`,
Age: 42,
City: `México D.F.`,
Country: `Mexico`,
Fax: `(51) 555-3745`,
HireDate: `2014-01-22`,
ID: 4,
Name: `Ana Sanders`,
ParentID: -1,
Phone: `(5) 555-4729`,
PostalCode: 5021,
Title: `CEO`,
LastName: `Sanders`,
FullAddress: `Avda. de la Constitución 2222, México D.F., Mexico`
}),
new EmployeesFlatDetailsItem(
{
Address: `Mataderos 2312`,
Age: 49,
City: `México D.F.`,
Country: `Mexico`,
Fax: `(5) 555-3995`,
HireDate: `2014-01-22`,
ID: 18,
Name: `Victoria Lincoln`,
ParentID: -1,
Phone: `(5) 555-3932`,
PostalCode: 5023,
Title: `Accounting Manager`,
LastName: `Lincoln`,
FullAddress: `Mataderos 2312, México D.F., Mexico`
}),
new EmployeesFlatDetailsItem(
{
Address: `120 Hanover Sq.`,
Age: 61,
City: `London`,
Country: `UK`,
Fax: `(171) 555-6750`,
HireDate: `2010-01-01`,
ID: 10,
Name: `Yang Wang`,
ParentID: -1,
Phone: `(171) 555-7788`,
PostalCode: 39000,
Title: `Localization Manager`,
LastName: `Wang`,
FullAddress: `120 Hanover Sq., London, UK`
}),
new EmployeesFlatDetailsItem(
{
Address: `Berguvsvägen 8`,
Age: 43,
City: `Luleå`,
Country: `Sweden`,
Fax: `0921-12 34 67`,
HireDate: `2011-06-03`,
ID: 3,
Name: `Michael Burke`,
ParentID: 1,
Phone: `0921-12 34 65`,
PostalCode: 29000,
Title: `Senior Software Developer`,
LastName: `Burke`,
FullAddress: `Berguvsvägen 8, Luleå, Sweden`
}),
new EmployeesFlatDetailsItem(
{
Address: `Forsterstr. 57`,
Age: 29,
City: `Mannheim`,
Country: `Germany`,
Fax: `0621-08924`,
HireDate: `2009-06-19`,
ID: 2,
Name: `Thomas Anderson`,
ParentID: 1,
Phone: `0621-08460`,
PostalCode: 68306,
Title: `Senior Software Developer`,
LastName: `Anderson`,
FullAddress: `Forsterstr. 57, Mannheim, Germany`
}),
new EmployeesFlatDetailsItem(
{
Address: `24, place Kléber`,
Age: 31,
City: `Strasbourg`,
Country: `France`,
Fax: `88.60.15.32`,
HireDate: `2014-08-18`,
ID: 11,
Name: `Monica Reyes`,
ParentID: 1,
Phone: `88.60.15.31`,
PostalCode: 67000,
Title: `Software Development Team Lead`,
LastName: `Reyes`,
FullAddress: `24, place Kléber, Strasbourg, France`
}),
new EmployeesFlatDetailsItem(
{
Address: `C/ Araquil, 67`,
Age: 35,
City: `Madrid`,
Country: `Spain`,
Fax: `(911) 555 91 99`,
HireDate: `2015-09-17`,
ID: 6,
Name: `Roland Mendel`,
ParentID: 11,
Phone: `(91) 555 22 82`,
PostalCode: 28023,
Title: `Senior Software Developer`,
LastName: `Mendel`,
FullAddress: `C/ Araquil, 67, Madrid, Spain`
}),
new EmployeesFlatDetailsItem(
{
Address: `12, rue des Bouchers`,
Age: 44,
City: `Marseille`,
Country: `France`,
Fax: `91.24.45.41`,
HireDate: `2009-10-11`,
ID: 12,
Name: `Sven Cooper`,
ParentID: 11,
Phone: `91.24.45.40`,
PostalCode: 13008,
Title: `Senior Software Developer`,
LastName: `Cooper`,
FullAddress: `12, rue des Bouchers, Marseille, France`
}),
new EmployeesFlatDetailsItem(
{
Address: `23 Tsawassen Blvd.`,
Age: 44,
City: `Tsawassen`,
Country: `Canada`,
Fax: `(604) 555-3745`,
HireDate: `2014-04-04`,
ID: 14,
Name: `Laurence Johnson`,
ParentID: 4,
Phone: `(604) 555-4729`,
PostalCode: 19000,
Title: `Director`,
LastName: `Johnson`,
FullAddress: `23 Tsawassen Blvd., Tsawassen, Canada`
}),
new EmployeesFlatDetailsItem(
{
Address: `Fauntleroy Circus`,
Age: 25,
City: `London`,
Country: `UK`,
Fax: `(125) 555-3798`,
HireDate: `2017-11-9`,
ID: 5,
Name: `Elizabeth Richards`,
ParentID: 4,
Phone: `(171) 555-1212`,
PostalCode: 30000,
Title: `Vice President`,
LastName: `Richards`,
FullAddress: `Fauntleroy Circus, London, UK`
}),
new EmployeesFlatDetailsItem(
{
Address: `Cerrito 333`,
Age: 39,
City: `Buenos Aires`,
Country: `Argentina`,
Fax: `(121) 135-4892`,
HireDate: `2010-03-22`,
ID: 13,
Name: `Trevor Ashworth`,
ParentID: 5,
Phone: `(1) 135-5555`,
PostalCode: 1010,
Title: `Director`,
LastName: `Ashworth`,
FullAddress: `Cerrito 333, Buenos Aires, Argentina`
}),
new EmployeesFlatDetailsItem(
{
Address: `Sierras de Granada 9993`,
Age: 44,
City: `México D.F.`,
Country: `Mexico`,
Fax: `(153) 555-7293`,
HireDate: `2014-04-04`,
ID: 17,
Name: `Antonio Moreno`,
ParentID: 18,
Phone: `(5) 555-3392`,
PostalCode: 5022,
Title: `Senior Accountant`,
LastName: `Moreno`,
FullAddress: `Sierras de Granada 9993, México D.F., Mexico`
}),
new EmployeesFlatDetailsItem(
{
Address: `Hauptstr. 29`,
Age: 50,
City: `Sao Paulo`,
Country: `Brazil`,
Fax: `(531) 555-6691`,
HireDate: `2007-11-18`,
ID: 7,
Name: `Pedro Rodriguez`,
ParentID: 10,
Phone: `0452-076545`,
PostalCode: 3012,
Title: `Senior Localization Developer`,
LastName: `Rodriguez`,
FullAddress: `Hauptstr. 29, Sao Paulo, Brazil`
}),
new EmployeesFlatDetailsItem(
{
Address: `Av. dos Lusíadas, 23`,
Age: 27,
City: `Bern`,
Country: `Switzerland`,
Fax: `(271) 335-357`,
HireDate: `2016-02-19`,
ID: 8,
Name: `Casey Harper`,
ParentID: 10,
Phone: `(11) 555-7647`,
PostalCode: 40000,
Title: `Senior Localization`,
LastName: `Harper`,
FullAddress: `Av. dos Lusíadas, 23, Bern, Switzerland`
}),
new EmployeesFlatDetailsItem(
{
Address: `Berkeley Gardens 12`,
Age: 25,
City: `London`,
Country: `UK`,
Fax: `(171) 555-9199`,
HireDate: `2017-11-09`,
ID: 15,
Name: `Patricia Simpson`,
ParentID: 7,
Phone: `(171) 555-2282`,
PostalCode: 26000,
Title: `Localization Intern`,
LastName: `Simpson`,
FullAddress: `Berkeley Gardens 12, London, UK`
}),
new EmployeesFlatDetailsItem(
{
Address: `Walserweg 21`,
Age: 39,
City: `Aachen`,
Country: `Germany`,
Fax: `0241-059428`,
HireDate: `2010-03-22`,
ID: 9,
Name: `Francisco Chang`,
ParentID: 7,
Phone: `0241-039123`,
PostalCode: 52066,
Title: `Localization Intern`,
LastName: `Chang`,
FullAddress: `Walserweg 21, Aachen, Germany`
}),
new EmployeesFlatDetailsItem(
{
Address: `35 King George`,
Age: 25,
City: `London`,
Country: `UK`,
Fax: `(171) 555-3373`,
HireDate: `2018-03-18`,
ID: 16,
Name: `Peter Lewis`,
ParentID: 7,
Phone: `(171) 555-0297`,
PostalCode: 48000,
Title: `Localization Intern`,
LastName: `Lewis`,
FullAddress: `35 King George, London, UK`
}),
];
super(...newItems.slice(0));
}
}
}
tsimport React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrGridModule, IgrColumnGroupModule } from "@infragistics/igniteui-react-grids";
import { IgrTreeGrid, IgrColumn, IgrColumnGroup } from "@infragistics/igniteui-react-grids";
import { ComponentRenderer, WebGridDescriptionModule, WebColumnGroupDescriptionModule } from "@infragistics/igniteui-react-core";
import { EmployeesFlatDetailsItem, EmployeesFlatDetails } from './EmployeesFlatDetails';
import { IgrColumnTemplateContext } from "@infragistics/igniteui-react-grids";
import "@infragistics/igniteui-react-grids/grids/combined";
import "@infragistics/igniteui-react-grids/grids/themes/light/bootstrap.css";
const mods: any[] = [
IgrGridModule,
IgrColumnGroupModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component<any, any> {
private treeGrid: IgrTreeGrid
private treeGridRef(r: IgrTreeGrid) {
this.treeGrid = r;
this.setState({});
}
private columnGroup1: IgrColumnGroup
private columnGroup2: IgrColumnGroup
constructor(props: any) {
super(props);
this.treeGridRef = this.treeGridRef.bind(this);
}
public render(): JSX.Element {
return (
<div className="container sample ig-typography">
<div className="container fill">
<IgrTreeGrid
autoGenerate="false"
data={this.employeesFlatDetails}
ref={this.treeGridRef}
id="treeGrid"
primaryKey="ID"
foreignKey="ParentID">
<IgrColumn
field="Name"
resizable="true">
</IgrColumn>
<IgrColumnGroup
header="General Information"
headerTemplate={this.webTreeGridColumnGroupHeaderTemplate}
name="columnGroup1">
<IgrColumn
field="HireDate"
sortable="true"
resizable="true">
</IgrColumn>
<IgrColumnGroup
header="Personal Details">
<IgrColumn
field="ID"
sortable="true"
resizable="true">
</IgrColumn>
<IgrColumn
field="Title"
sortable="true"
resizable="true">
</IgrColumn>
<IgrColumn
field="Age"
sortable="true"
resizable="true">
</IgrColumn>
</IgrColumnGroup>
</IgrColumnGroup>
<IgrColumnGroup
header="Address Information"
headerTemplate={this.webTreeGridColumnGroupHeaderTemplate}
name="columnGroup2">
<IgrColumn
header="Location"
field="Address"
hidden="true"
sortable="true"
resizable="true">
</IgrColumn>
<IgrColumn
field="Phone"
hidden="true"
sortable="true"
resizable="true">
</IgrColumn>
<IgrColumnGroup
header="Location">
<IgrColumn
field="Country"
sortable="true"
resizable="true">
</IgrColumn>
<IgrColumn
field="City"
sortable="true"
resizable="true">
</IgrColumn>
<IgrColumn
field="Address"
sortable="true"
resizable="true">
</IgrColumn>
</IgrColumnGroup>
<IgrColumnGroup
header="Contact Information">
<IgrColumn
field="Phone"
sortable="true"
resizable="true">
</IgrColumn>
<IgrColumn
field="Fax"
sortable="true"
resizable="true">
</IgrColumn>
<IgrColumn
field="PostalCode"
sortable="true"
resizable="true">
</IgrColumn>
</IgrColumnGroup>
</IgrColumnGroup>
</IgrTreeGrid>
</div>
</div>
);
}
private _employeesFlatDetails: EmployeesFlatDetails = null;
public get employeesFlatDetails(): EmployeesFlatDetails {
if (this._employeesFlatDetails == null)
{
this._employeesFlatDetails = new EmployeesFlatDetails();
}
return this._employeesFlatDetails;
}
private _componentRenderer: ComponentRenderer = null;
public get renderer(): ComponentRenderer {
if (this._componentRenderer == null) {
this._componentRenderer = new ComponentRenderer();
var context = this._componentRenderer.context;
WebGridDescriptionModule.register(context);
WebColumnGroupDescriptionModule.register(context);
}
return this._componentRenderer;
}
public webTreeGridColumnGroupHeaderTemplate = (e: { dataContext: IgrColumnTemplateContext }) => {
const column = e.dataContext.column;
return (
<div style={{ display: 'flex', alignItems: 'center', gap: '5px' }}>
<span draggable="false" onClick={(e: any) => this.toggleColumnGroup(column)}>
{this.columnGroupStates.get(column) ? "🔽" : "🔼"}
</span>
<span>{column.header}</span>
</div>
);
};
public columnGroupStates = new Map<IgrColumn, boolean>();
public toggleColumnGroup(columnGroup: IgrColumn) {
const columns = columnGroup.childColumns;
if (columnGroup.header === 'General Information') {
const col = columns[1] as IgrColumn;
col.hidden = !col.hidden;
} else if (columnGroup.header === 'Address Information') {
for (const col of columns) {
const c = col as IgrColumn;
c.hidden = !c.hidden;
}
}
columnGroup.forceUpdate();
this.columnGroupStates.set(columnGroup, !this.columnGroupStates.get(columnGroup));
}
}
// rendering above component in the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Sample/>);
tsx/* shared styles are loaded from: */
/* https://static.infragistics.com/xplatform/css/samples */
css
Styling
In addition to the predefined themes, the grid could be further customized by setting some of the available CSS properties. In case you would like to change some of the colors, you need to set a class for the grid first:
<IgrTreeGrid className="grid"></IgrTreeGrid>
tsx
Then set the related CSS properties to this class:
.grid {
--ig-grid-header-background: #e0f3ff;
--ig-grid-header-text-color: #e41c77;
--ig-grid-header-border-width: 1px;
--ig-grid-header-border-style: solid;
--ig-grid-header-border-color: rgba(0, 0, 0, 0.08);
}
css
Demo
export class EmployeesFlatDetailsItem {
public constructor(init: Partial<EmployeesFlatDetailsItem>) {
Object.assign(this, init);
}
public Address: string;
public Age: number;
public City: string;
public Country: string;
public Fax: string;
public HireDate: string;
public ID: number;
public Name: string;
public ParentID: number;
public Phone: string;
public PostalCode: number;
public Title: string;
public LastName: string;
public FullAddress: string;
}
export class EmployeesFlatDetails extends Array<EmployeesFlatDetailsItem> {
public constructor(items: Array<EmployeesFlatDetailsItem> | number = -1) {
if (Array.isArray(items)) {
super(...items);
} else {
const newItems = [
new EmployeesFlatDetailsItem(
{
Address: `Obere Str. 57`,
Age: 55,
City: `Berlin`,
Country: `Germany`,
Fax: `030-0076545`,
HireDate: `2008-03-20`,
ID: 1,
Name: `Johnathan Winchester`,
ParentID: -1,
Phone: `030-0074321`,
PostalCode: 12209,
Title: `Development Manager`,
LastName: `Winchester`,
FullAddress: `Obere Str. 57, Berlin, Germany`
}),
new EmployeesFlatDetailsItem(
{
Address: `Avda. de la Constitución 2222`,
Age: 42,
City: `México D.F.`,
Country: `Mexico`,
Fax: `(51) 555-3745`,
HireDate: `2014-01-22`,
ID: 4,
Name: `Ana Sanders`,
ParentID: -1,
Phone: `(5) 555-4729`,
PostalCode: 5021,
Title: `CEO`,
LastName: `Sanders`,
FullAddress: `Avda. de la Constitución 2222, México D.F., Mexico`
}),
new EmployeesFlatDetailsItem(
{
Address: `Mataderos 2312`,
Age: 49,
City: `México D.F.`,
Country: `Mexico`,
Fax: `(5) 555-3995`,
HireDate: `2014-01-22`,
ID: 18,
Name: `Victoria Lincoln`,
ParentID: -1,
Phone: `(5) 555-3932`,
PostalCode: 5023,
Title: `Accounting Manager`,
LastName: `Lincoln`,
FullAddress: `Mataderos 2312, México D.F., Mexico`
}),
new EmployeesFlatDetailsItem(
{
Address: `120 Hanover Sq.`,
Age: 61,
City: `London`,
Country: `UK`,
Fax: `(171) 555-6750`,
HireDate: `2010-01-01`,
ID: 10,
Name: `Yang Wang`,
ParentID: -1,
Phone: `(171) 555-7788`,
PostalCode: 39000,
Title: `Localization Manager`,
LastName: `Wang`,
FullAddress: `120 Hanover Sq., London, UK`
}),
new EmployeesFlatDetailsItem(
{
Address: `Berguvsvägen 8`,
Age: 43,
City: `Luleå`,
Country: `Sweden`,
Fax: `0921-12 34 67`,
HireDate: `2011-06-03`,
ID: 3,
Name: `Michael Burke`,
ParentID: 1,
Phone: `0921-12 34 65`,
PostalCode: 29000,
Title: `Senior Software Developer`,
LastName: `Burke`,
FullAddress: `Berguvsvägen 8, Luleå, Sweden`
}),
new EmployeesFlatDetailsItem(
{
Address: `Forsterstr. 57`,
Age: 29,
City: `Mannheim`,
Country: `Germany`,
Fax: `0621-08924`,
HireDate: `2009-06-19`,
ID: 2,
Name: `Thomas Anderson`,
ParentID: 1,
Phone: `0621-08460`,
PostalCode: 68306,
Title: `Senior Software Developer`,
LastName: `Anderson`,
FullAddress: `Forsterstr. 57, Mannheim, Germany`
}),
new EmployeesFlatDetailsItem(
{
Address: `24, place Kléber`,
Age: 31,
City: `Strasbourg`,
Country: `France`,
Fax: `88.60.15.32`,
HireDate: `2014-08-18`,
ID: 11,
Name: `Monica Reyes`,
ParentID: 1,
Phone: `88.60.15.31`,
PostalCode: 67000,
Title: `Software Development Team Lead`,
LastName: `Reyes`,
FullAddress: `24, place Kléber, Strasbourg, France`
}),
new EmployeesFlatDetailsItem(
{
Address: `C/ Araquil, 67`,
Age: 35,
City: `Madrid`,
Country: `Spain`,
Fax: `(911) 555 91 99`,
HireDate: `2015-09-17`,
ID: 6,
Name: `Roland Mendel`,
ParentID: 11,
Phone: `(91) 555 22 82`,
PostalCode: 28023,
Title: `Senior Software Developer`,
LastName: `Mendel`,
FullAddress: `C/ Araquil, 67, Madrid, Spain`
}),
new EmployeesFlatDetailsItem(
{
Address: `12, rue des Bouchers`,
Age: 44,
City: `Marseille`,
Country: `France`,
Fax: `91.24.45.41`,
HireDate: `2009-10-11`,
ID: 12,
Name: `Sven Cooper`,
ParentID: 11,
Phone: `91.24.45.40`,
PostalCode: 13008,
Title: `Senior Software Developer`,
LastName: `Cooper`,
FullAddress: `12, rue des Bouchers, Marseille, France`
}),
new EmployeesFlatDetailsItem(
{
Address: `23 Tsawassen Blvd.`,
Age: 44,
City: `Tsawassen`,
Country: `Canada`,
Fax: `(604) 555-3745`,
HireDate: `2014-04-04`,
ID: 14,
Name: `Laurence Johnson`,
ParentID: 4,
Phone: `(604) 555-4729`,
PostalCode: 19000,
Title: `Director`,
LastName: `Johnson`,
FullAddress: `23 Tsawassen Blvd., Tsawassen, Canada`
}),
new EmployeesFlatDetailsItem(
{
Address: `Fauntleroy Circus`,
Age: 25,
City: `London`,
Country: `UK`,
Fax: `(125) 555-3798`,
HireDate: `2017-11-9`,
ID: 5,
Name: `Elizabeth Richards`,
ParentID: 4,
Phone: `(171) 555-1212`,
PostalCode: 30000,
Title: `Vice President`,
LastName: `Richards`,
FullAddress: `Fauntleroy Circus, London, UK`
}),
new EmployeesFlatDetailsItem(
{
Address: `Cerrito 333`,
Age: 39,
City: `Buenos Aires`,
Country: `Argentina`,
Fax: `(121) 135-4892`,
HireDate: `2010-03-22`,
ID: 13,
Name: `Trevor Ashworth`,
ParentID: 5,
Phone: `(1) 135-5555`,
PostalCode: 1010,
Title: `Director`,
LastName: `Ashworth`,
FullAddress: `Cerrito 333, Buenos Aires, Argentina`
}),
new EmployeesFlatDetailsItem(
{
Address: `Sierras de Granada 9993`,
Age: 44,
City: `México D.F.`,
Country: `Mexico`,
Fax: `(153) 555-7293`,
HireDate: `2014-04-04`,
ID: 17,
Name: `Antonio Moreno`,
ParentID: 18,
Phone: `(5) 555-3392`,
PostalCode: 5022,
Title: `Senior Accountant`,
LastName: `Moreno`,
FullAddress: `Sierras de Granada 9993, México D.F., Mexico`
}),
new EmployeesFlatDetailsItem(
{
Address: `Hauptstr. 29`,
Age: 50,
City: `Sao Paulo`,
Country: `Brazil`,
Fax: `(531) 555-6691`,
HireDate: `2007-11-18`,
ID: 7,
Name: `Pedro Rodriguez`,
ParentID: 10,
Phone: `0452-076545`,
PostalCode: 3012,
Title: `Senior Localization Developer`,
LastName: `Rodriguez`,
FullAddress: `Hauptstr. 29, Sao Paulo, Brazil`
}),
new EmployeesFlatDetailsItem(
{
Address: `Av. dos Lusíadas, 23`,
Age: 27,
City: `Bern`,
Country: `Switzerland`,
Fax: `(271) 335-357`,
HireDate: `2016-02-19`,
ID: 8,
Name: `Casey Harper`,
ParentID: 10,
Phone: `(11) 555-7647`,
PostalCode: 40000,
Title: `Senior Localization`,
LastName: `Harper`,
FullAddress: `Av. dos Lusíadas, 23, Bern, Switzerland`
}),
new EmployeesFlatDetailsItem(
{
Address: `Berkeley Gardens 12`,
Age: 25,
City: `London`,
Country: `UK`,
Fax: `(171) 555-9199`,
HireDate: `2017-11-09`,
ID: 15,
Name: `Patricia Simpson`,
ParentID: 7,
Phone: `(171) 555-2282`,
PostalCode: 26000,
Title: `Localization Intern`,
LastName: `Simpson`,
FullAddress: `Berkeley Gardens 12, London, UK`
}),
new EmployeesFlatDetailsItem(
{
Address: `Walserweg 21`,
Age: 39,
City: `Aachen`,
Country: `Germany`,
Fax: `0241-059428`,
HireDate: `2010-03-22`,
ID: 9,
Name: `Francisco Chang`,
ParentID: 7,
Phone: `0241-039123`,
PostalCode: 52066,
Title: `Localization Intern`,
LastName: `Chang`,
FullAddress: `Walserweg 21, Aachen, Germany`
}),
new EmployeesFlatDetailsItem(
{
Address: `35 King George`,
Age: 25,
City: `London`,
Country: `UK`,
Fax: `(171) 555-3373`,
HireDate: `2018-03-18`,
ID: 16,
Name: `Peter Lewis`,
ParentID: 7,
Phone: `(171) 555-0297`,
PostalCode: 48000,
Title: `Localization Intern`,
LastName: `Lewis`,
FullAddress: `35 King George, London, UK`
}),
];
super(...newItems.slice(0));
}
}
}
tsimport React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrGridModule } from "@infragistics/igniteui-react-grids";
import { IgrTreeGrid, IgrColumn, IgrColumnGroup } from "@infragistics/igniteui-react-grids";
import { ComponentRenderer, WebGridDescriptionModule } from "@infragistics/igniteui-react-core";
import { EmployeesFlatDetailsItem, EmployeesFlatDetails } from './EmployeesFlatDetails';
import "@infragistics/igniteui-react-grids/grids/combined";
import "@infragistics/igniteui-react-grids/grids/themes/light/bootstrap.css";
const mods: any[] = [
IgrGridModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component<any, any> {
private treeGrid: IgrTreeGrid
private treeGridRef(r: IgrTreeGrid) {
this.treeGrid = r;
this.setState({});
}
constructor(props: any) {
super(props);
this.treeGridRef = this.treeGridRef.bind(this);
}
public render(): JSX.Element {
return (
<div className="container sample ig-typography">
<div className="container fill">
<IgrTreeGrid
autoGenerate="false"
data={this.employeesFlatDetails}
ref={this.treeGridRef}
id="treeGrid"
primaryKey="ID"
foreignKey="ParentID">
<IgrColumn
field="Name"
resizable="true">
</IgrColumn>
<IgrColumnGroup
header="General Information">
<IgrColumn
field="HireDate"
sortable="true"
resizable="true">
</IgrColumn>
<IgrColumnGroup
header="Personal Details">
<IgrColumn
field="ID"
sortable="true"
resizable="true">
</IgrColumn>
<IgrColumn
field="Title"
sortable="true"
resizable="true">
</IgrColumn>
<IgrColumn
field="Age"
sortable="true"
resizable="true">
</IgrColumn>
</IgrColumnGroup>
</IgrColumnGroup>
<IgrColumnGroup
header="Address Information">
<IgrColumnGroup
header="Location">
<IgrColumn
field="Country"
sortable="true"
resizable="true">
</IgrColumn>
<IgrColumn
field="City"
sortable="true"
resizable="true">
</IgrColumn>
<IgrColumn
field="Address"
sortable="true"
resizable="true">
</IgrColumn>
</IgrColumnGroup>
<IgrColumnGroup
header="Contact Information">
<IgrColumn
field="Phone"
sortable="true"
resizable="true">
</IgrColumn>
<IgrColumn
field="Fax"
sortable="true"
resizable="true">
</IgrColumn>
<IgrColumn
field="PostalCode"
sortable="true"
resizable="true">
</IgrColumn>
</IgrColumnGroup>
</IgrColumnGroup>
</IgrTreeGrid>
</div>
</div>
);
}
private _employeesFlatDetails: EmployeesFlatDetails = null;
public get employeesFlatDetails(): EmployeesFlatDetails {
if (this._employeesFlatDetails == null)
{
this._employeesFlatDetails = new EmployeesFlatDetails();
}
return this._employeesFlatDetails;
}
private _componentRenderer: ComponentRenderer = null;
public get renderer(): ComponentRenderer {
if (this._componentRenderer == null) {
this._componentRenderer = new ComponentRenderer();
var context = this._componentRenderer.context;
WebGridDescriptionModule.register(context);
}
return this._componentRenderer;
}
}
// rendering above component in the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Sample/>);
tsx/* shared styles are loaded from: */
/* https://static.infragistics.com/xplatform/css/samples */
#treeGrid {
--ig-grid-header-background: #e0f3ff;
--ig-grid-header-text-color: #e41c77;
--ig-grid-header-border-width: 1px;
--ig-grid-header-border-style: solid;
--ig-grid-header-border-color: rgba(0, 0, 0, 0.08);
}
css
API References
Additional Resources
Our community is active and always welcoming to new ideas.