a suite of UI Components for development of web apps
If you have any questions, don't hesitate to contact us at support@lidorsystems.com
Advanced User Interface Controls and Components
IntegralUI TreeGrid is a native Angular component that displays hierarchical data structures in multiple columns. You can load data on demand from custom local or remote data sources, and add custom HTML content in each grid cell. In following sections, you can find details about various features available in the TreeGrid component.
If you have any questions, don't hesitate to contact us at support@lidorsystems.com
In above demo, the grid has columns with different content: checkbox, text and image. When you click on first column header (with a check box), all rows become checked or unchecked. In addition, a click on parent row changes the check box value to its child rows. In this example, check boxes can have two values: checked or unchecked, but you can change this easily by providing three values.
Some columns have their content aligned to center, while others have their alignment set to left. You may also notice that expand icon is shown for cells in second column. This is customizable, you can set which column has the expand box in your code.
By left-click on a row and move the mouse cursor, a drag drop operation will start and you can reorder rows during run-time. In this example, there are some restrictions set, that prevent drag drop of a movie from one category to another, or as a child of another movie. This is set in sample code, you can find more information in below section describing drag drop operations.
You can also select multiple rows, by holding SHIFT or CTRL key and click on specific row. For more information on supported selection types, see section below.
In order to use the TreeGrid component in your app, you need to do the following:
public columns: Array;
public rows: Array;
constructor(){
this.columns = [
{ id: 1, width: 30, fixedWidth: true },
{ id: 2, headerText: "Title", width: 300},
{ id: 3, headerText: "Year", headerAlignment: "center", contentAlignment: "center", width: 70 },
{ id: 4, headerText: "Ratings", headerAlignment: "center", contentAlignment: "center", width: 150, fixedWidth: true },
{ id: 5, headerText: "Released", headerAlignment: "center", contentAlignment: "center", width: 180 }
];
this.rows = [
{
id: 1,
text: "Mystery",
cells: [{ cid: 1 }, { cid: 2, text: "Mystery" }],
rows: [
{
id: 11,
pid: 1,
text: "Inception",
cells: [{ cid: 1, value: true }, { cid: 2, text: "Inception" }, { cid: 3, text: "2010" }, { cid: 4, value: 4 }, { cid: 5, text: "16 Jul 2010" } ]
},
// . . .
//
// The full data set is available at https://stackblitz.com/edit/integralui-treegrid-overview
//
]
}
];
}
<iui-treegrid [columns]="columns" [rows]="rows">
<ng-template let-column [iuiTemplate]="{ type: 'header' }">
{{column.headerText}}
</ng-template>
<ng-template let-cell [iuiTemplate]="{ type: 'cell' }">
{{cell.text}}
</ng-template>
<ng-template let-column [iuiTemplate]="{ type: 'footer' }">
{{column.footerText}}
</ng-template>
</iui-treegrid>
Each grid cell can have a different content. You can use some conditions that will distinguish content from one cell to another. In this example, the object id is used. When condition is met, the corresponding content is placed in target cell.
Note If you want to show row with different content then other rows, you can use the ngIf directive and set condition by which a different content will appear.
<iui-treegrid [columns]="columns" [rows]="rows">
<ng-template let-column [iuiTemplate]="{ type: 'header' }">
{{column.headerText}}
</ng-template>
<ng-template let-cell [iuiTemplate]="{ type: 'cell' }">
<span [ngSwitch]="cell.cid">
<span *ngSwitchCase="1">
<span class="trg-ovw-cell-checkbox" [ngStyle]="{ 'background-image': getCheckValue(cell) }" (mousedown)="checkBoxClicked(cell)"></span>
</span>
<span *ngSwitchCase="4"> <!-- RATING -->
<iui-rating [controlStyle]="trgOverviewRatingStyleStars" [(ngModel)]="cell.value" [max]="5"></iui-rating>
</span>
<span *ngSwitchDefault>
<span class="trg-ovw-cell-text">{{cell.text}}</span>
</span>
</span>
</ng-template>
<ng-template let-column [iuiTemplate]="{ type: 'footer' }">
{{column.footerText}}
</ng-template>
</iui-treegrid>
When you have a template ready, you need to link the data source with the TreeGrid using the columns and rows properties. The data source can be any array in flat or tree format.
Your data source should have columns and rows set. Each row can have cells and child rows. These objects can have different field names then the ones used by the TreeGrid component. You can find more information about this in below section of data binding.
A detailed list of all properties, events and methods that you can use is available here: TreeGrid online help.
In some cases, the data source you are using will have a different format (structure and object field names) then the one used by the TreeGrid component. In order to use this data source, at first you may need to match the names of data fields in your data source with those used by the grid.
For this purpose, you can use the dataFields property, which holds an object that maps the data field names, and then you can populate the TreeGrid by setting the columns and rows properties and using the loadData method.
Related: Load from Custom Data Source in Angular TreeGrid
In some cases, you may need to add new rows or remove existing rows in the TreeGrid during run-time. For this purpose, there are built-in methods available that allow you to change the structure of the TreeGrid:
import { IntegralUITreeGrid } from './integralui/components/integralui.treegrid';
// . . .
export class AppComponent {
// Get a reference to the TreeGrid component using a variable set in HTML
@ViewChild('treegrid') treegrid: IntegralUITreeGrid;
// An Array object that holds all column objects shown in TreeGrid
private columns: Array;
// An Array object that holds all row objects shown in TreeGrid
private rows: Array;
// Holds the number of rows created
private rowCount: number = 0;
// Initialize rows in component constructor
constructor(){
this.rows = [];
}
// Adds a new row to the end of the TreeGrid
addRow(){
let row = {
text : 'Row ' + (this.rowCount+1).toString(),
cells: []
};
for (let j = 0; j < this.columns.length; j++)
row.cells.push({ text: "Item" + (this.rowCount+1).toString() + j });
this.treegrid.addRow(row);
this.rowCount++;
}
// Fired whenever a new row is added to the TreeGrid
rowAddedEvent(e){
if (e.row)
console.log("rowAdded: " + e.row.text);
}
}
<button (click)="addRow()">Add Row<button><br /><br />
<iui-treegrid [columns]="columns" [rows]="rows" (rowAdded)="rowAddedEvent($event)" #treegrid>
<ng-template let-column [iuiTemplate]="{ type: 'header' }">
{{column.headerText}}
</ng-template>
<ng-template let-cell [iuiTemplate]="{ type: 'cell' }">
{{cell.text}}
</ng-template>
</iui-treegrid>
In above code, we are adding a new row with some rows using the addRow method. To access this method, at first we need to get a reference to the TreeGrid component. In HTML we are adding the #treegrid variable, which is used to locate the TreeGrid within your application component.
After you have a reference to the TreeGrid component, you can get access to all public methods available.
Related: Add Rows on Demand in Angular TreeGrid
TreeGrid component comes with advanced drag drop that allows you to reorder rows in tree hierarchy by simply dragging one or multiple rows from one place to another within the same or other components.
During this process, events are fired that can help you to add custom actions that may alter the default built-in drag drop functionality. In each event, you can set up custom conditions that can prevent or allow drag drop in special cases, depending on your application requirements.
Whenever a row is dragged, a dragging window will appear showing the target row and position at which row can be dropped. There are four possible positions:
In this demo, you can only reorder child rows within its parent row, or you can reorder root rows. You cannot drag and drop a row as a child of another row. These conditions are set to because of the sample data, a movie cannot become a child of another movie.
gridDragOver(e){
if (e.targetRow){
switch (e.dropPos){
// arc arrow
case 0:
// Cancel all drag drop operations when dragged row is about to be dropped as a child of target row
e.cancel = true;
break;
// up arrow
case 1:
// If dragged row is a child and its dragged over root row
if (!e.dragRow.pid && e.targetRow.pid)
e.cancel = true;
// If dragged row is a root row and its dragged over child row
else if (e.dragRow.pid && !e.targetRow.pid)
e.cancel = true;
break;
// down arrow
case 2:
// If dragged row is a child and its dragged over root row
if (!e.dragRow.pid && e.targetRow.pid)
e.cancel = true;
// If dragged row is a root row and its dragged over child row
else if (e.dragRow.pid && !e.targetRow.pid)
e.cancel = true;
break;
}
}
// down arrow with a line
// Cancel all drag drop operations if dragged row is a child and is dragged over empty space at the end of the TreeGrid
else if (e.dragRow.pid)
e.cancel = true;
}
}
<div #application>
<iui-treegrid [columns]="columns" [rows]="rows" [allowDrag]="true" (dragOver)="gridDragOver($event)">
<ng-template let-column [iuiTemplate]="{ type: 'header' }">
{{column.headerText}}
</ng-template>
<ng-template let-cell [iuiTemplate]="{ type: 'cell' }">
{{cell.text}}
</ng-template>
</iui-treegrid>
</div>
By default, during drag and drop rows are moved from their original position to a new one. In some cases, instead of moving you may need to create a copy of dragged rows. Copy operation is already built-in, you only need to press and hold the SHIFT key, when row is dropped. The dragging window will change its icon showing a + sign. This states that copy of dragged row will drop at specified position.
By default, a single selection mode is active, which means that only one row can become selected at one time. You can change this by setting the selectionMode property to a different value. This property accepts values from IntegralUISelectionMode enumeration:
You can also select multiple rows using the selectRows method. You can call this method from your app code and select rows manually without user interaction.
selectMulti(){
// Create a list of rows that you want to be selected
let list = [];
// Add first row to the list
list.push(this.rows[0]);
// Add child rows of the first row starting from second child
if (this.rows[0].rows){
for (let i = 1; i < this.rows[0].rows.length; i++){
let childRow = this.rows[0].rows[i];
list.push(childRow);
}
}
// Add third row to the list
list.push(this.rows[2]);
// Add this list as argument to the selectRows method
this.treegrid.selectRows(list);
}
There is already built-in virtualization in the TreeGrid, which allows you to display hundreds of thousands of rows at one time. The only limit here is how much data the browser can handle, but for sure, you can display for example 10,000 rows in 100 columns.
The TreeGrid is optimized to work with large data sets. You can load your data set initially into the TreeGrid, and update only small portion on your server when required. All work is done on the client side, which increases overall user interaction.
A performance demonstration is available at Fast Loading in Angular TreeGrid.
You can also choose to load data on demand. Just before a row expands, a new data is retrieved from the server and the TreeGrid is updated. This process requires very little time to execute, in most cases is instantly.
An example that shows how to filter the TreeGrid content using multiple different conditions in different combinations for each column separately is available here: Angular TreeGrid Filter.
For filtering operations we are using the IntegralUIFilterService, which provides many ways to set string, numeric or custom filtering using multiple conditions with AND / OR combinations for each column separately.
Here you can find an example of Sorting in Angular TreeGrid. In general, you can sort columns using built-in sort operations for basic types: string, number or you can create your own custom sorting.
Each part of IntegralUI TreeGrid component is fully customizable. There are different CSS classes for each component part. Although changing the attributes of built-in classes is possible, you can completely override them using the controlStyle property.
The controlStyle property accepts an object that holds a list of CSS class names that will override the default ones. For each component part, a different CSS class governs its appearance. This allows you to specify a set of different CSS classes for each component part and alter the appearance of the TreeGrid in whole.
treegridStyle = {
general: {
disabled: 'iui-treegrid-disabled',
focused: 'iui-treegrid-focused',
normal: 'iui-treegrid',
hovered: 'iui-treegrid-hovered',
selected: 'iui-treegrid-selected'
},
column: {
header: {
cell: 'iui-treegrid-column-header-cell',
disabled: 'iui-treegrid-column-header-disabled',
normal: 'iui-treegrid-column-header',
hovered: 'iui-treegrid-column-header-hovered',
selected: 'iui-treegrid-column-header-selected'
},
body: {
cell: 'iui-treegrid-column-body-cell',
disabled: 'iui-treegrid-column-body-disabled',
normal: 'iui-treegrid-column-body',
hovered: 'iui-treegrid-column-body-hovered',
selected: 'iui-treegrid-column-body-selected'
},
footer: {
cell: 'iui-treegrid-column-footer-cell',
disabled: 'iui-treegrid-column-footer-disabled',
normal: 'iui-treegrid-column-footer',
hovered: 'iui-treegrid-column-footer-hovered',
selected: 'iui-treegrid-column-footer-selected'
},
sorting: {
normal: {
ascending: 'iui-sort-ascending',
descending: 'iui-sort-descending'
},
selected: {
ascending: 'iui-sort-ascending-selected',
descending: 'iui-sort-descending-selected'
}
}
},
row: {
general: {
disabled: 'iui-treegrid-row-disabled',
focused: 'iui-treegrid-row-focused',
normal: 'iui-treegrid-row',
hovered: 'iui-treegrid-row-hovered',
selected: 'iui-treegrid-row-selected'
},
expandBox: {
general: 'iui-treegrid-expand-box',
load: 'iui-treegrid-expand-box-load',
expanded: 'iui-treegrid-expand-box-open',
collapsed: 'iui-treegrid-expand-box-close'
},
cell: {
disabled: 'iui-treegrid-row-cell-disabled',
focused: 'iui-treegrid-row-cell-focused',
normal: 'iui-treegrid-row-cell',
hovered: 'iui-treegrid-row-cell-hovered',
selected: 'iui-treegrid-row-cell-selected'
}
},
treegridLines: {
none: 'iui-treegrid-lines-none',
horizontal: 'iui-treegrid-lines-horizontal',
vertical: 'iui-treegrid-lines-vertical',
both: 'iui-treegrid-lines-both'
}
}
IntegralUI TreeGrid component allows you to display hierarchical data structures in multiple columns. It has built-in virtualization that allows you to work with thousands of rows on client side. You can populate the TreeGrid using custom data source, locally or remotely. Supports drag drop operations, which are customizable on your side by handling events.
By using templates, you can add any custom HTML elements or Angular components in column header, footer and each row cell individually. With use of conditions like ngIf directive, you can have different cells with different content.
To modify the TreeGrid appearance, you can create your own CSS classes that will override the default ones.
The TreeGrid component is part of IntegralUI Web.