Angular Grid Conditional Styling
If you need to provide any custom styling in the IgxGrid component, you can do it on either row or cell level.
Grid Conditional Row Styling
The IgxGrid component in Ignite UI for Angular provides two ways to conditional styling of rows based on custom rules.
- By setting
rowClassesinput on the IgxGrid component; - By setting
rowStylesinput on the IgxGrid component;
Further in this topic wi will cover both of them in more details.
Using rowClasses
You can conditionally style the IgxGrid rows by setting the rowClasses input and define custom rules.
<!-- sample.component.html -->
<igx-grid #grid [data]="data" [height]="'600px'" [width]="'100%'" [rowClasses]="rowClasses">
...
</igx-grid>
The rowClasses input accepts an object literal, containing key-value pairs, where the key is the name of the CSS class, while the value is either a callback function that returns a boolean, or boolean value.
// sample.component.ts
public rowClasses = {
activeRow: this.activeRowCondition
};
public activeRowCondition = (row: RowType) => this.grid?.navigation.activeNode?.row === row.index;
// sample.component.scss
::ng-deep {
.activeRow {
border: 2px solid #fc81b8;
border-left: 3px solid #e41c77;
}
}
Note
Use ::ng-deep or ViewEncapsulation.None to force the custom styles down through the current component and its children.
Demo
Using rowStyles
Columns now expose the rowStyles property which allows conditional styling of the data rows. Similar to rowClasses it accepts an object literal where the keys are style properties and the values are expressions for evaluation. Also, you can apply regular styling (without any conditions).
The callback signature for both
rowStylesandrowClassesis:
(row: RowType) => boolean
Let's define our styles:
// component.ts
public rowStyles = {
background: (row: RowType) => (+row.data['Change'] < 0 && +row.data['Change On Year(%)'] < 0) ? '#FF000088' : '#00000000',
border: (row: RowType) => (+row.data['Change'] < 0 && +row.data['Change On Year(%)'] < 0) ? '2px solid' : '1px solid',
'border-color': (row: RowType) => (+row.data['Change'] < 0 && +row.data['Change On Year(%)'] < 0) ? '#FF000099' : '#E9E9E9'
};
<!-- sample.component.html -->
<igx-grid #grid1 [data]="data | async" [height]="'500px'" width="100%"
[autoGenerate]="false" [allowFiltering]="true" [rowStyles]="rowStyles">
...
</igx-grid>
Demo
Grid Conditional Cell Styling
Overview
The IgxGrid component in Ignite UI for Angular provides two ways to conditional styling of cells based on custom rules.
- By setting the
IgxColumnComponentinputcellClassesto an object literal containing key-value pairs. The key is the name of the CSS class, while the value is either a callback function that returns a boolean, or boolean value. The result is a convenient material styling of the cell.
// component.ts file
public beatsPerMinuteClasses = {
downFont: this.downFontCondition,
upFont: this.upFontCondition
};
...
private downFontCondition = (rowData: any, columnKey: any): boolean => {
return rowData[columnKey] <= 95;
}
// component.scss file
.upFont {
color: red;
}
.downFont {
color: green;
}
Using cellClasses
You can conditionally style the IgxGrid cells by setting the IgxColumnComponent cellClasses input and define custom rules.
<!-- sample.component.html -->
<igx-column field="BeatsPerMinute" dataType="number" [cellClasses]="beatsPerMinuteClasses"></igx-column>
The cellClasses input accepts an object literal, containing key-value pairs, where the key is the name of the CSS class, while the value is either a callback function that returns a boolean, or boolean value.
// sample.component.ts
private upFontCondition = (rowData: any, columnKey: any): boolean => {
return rowData[columnKey] > 95;
}
private downFontCondition = (rowData: any, columnKey: any): boolean => {
return rowData[columnKey] <= 95;
}
public beatsPerMinuteClasses = {
downFont: this.downFontCondition,
upFont: this.upFontCondition
};
// sample.component.scss
::ng-deep {
.upFont {
color: green;
}
.downFont {
color: red;
}
}
Note
Use ::ng-deep or ViewEncapsulation.None to force the custom styles down through the current component and its children.
Demo
- By using the
IgxColumnComponentinputcellStyleswhich accepts an object literal where the keys are style properties and the values are expressions for evaluation.
public styles = {
'background': 'linear-gradient(180deg, #dd4c4c 0%, firebrick 100%)',
'text-shadow': '1px 1px 2px rgba(25,25,25,.25)',
'animation': '0.25s ease-in-out forwards alternate popin'
};
The callback signature for both
cellStylesandcellClassesis now changed to:
(rowData: any, columnKey: string, cellValue: any, rowIndex: number) => boolean
Using cellStyles
Columns now expose the cellStyles property which allows conditional styling of the column cells. Similar to cellClasses it accepts an object literal where the keys are style properties and the values are expressions for evaluation. Also, you can apply regular styling with ease (without any conditions).
In the sample above we've created:
- Two different styles that will be applied based on the column index.
- You will also change the
text colorbased on even/odd rows.
The callback signature for both
cellStylesis:
(rowData: any, columnKey: string, cellValue: any, rowIndex: number) => boolean
Let's define our styles:
// component.ts
public oddColStyles = {
background: 'linear-gradient(to right, #b993d6, #8ca6db)',
color: (rowData, coljey, cellValue, rowIndex) => rowIndex % 2 === 0 ? 'white' : 'gray',
animation: '0.75s popin'
};
public evenColStyles = {
background: 'linear-gradient(to right, #8ca6db, #b993d6)',
color: (rowData, coljey, cellValue, rowIndex) => rowIndex % 2 === 0 ? 'gray' : 'white',
animation: '0.75s popin'
};
On ngOnInit we will add the cellStyles configuration for each column of the predefined columns collection, which is used to create the IgxGrid columns dynamically.
// component.ts
public ngOnInit() {
this.data = athletesData;
this.columns = [
{ field: 'Id' },
{ field: 'Position' },
{ field: 'Name' },
{ field: 'AthleteNumber' },
{ field: 'CountryName' }
];
this.applyCSS();
}
public applyCSS() {
this.columns.forEach((column, index) => {
column.cellStyles = (index % 2 === 0 ? this.evenColStyles : this.oddColStyles);
});
}
public updateCSS(css: string) {
this.oddColStyles = {...this.oddColStyles, ...JSON.parse(css)};
this.evenColStyles = {...this.evenColStyles, ...JSON.parse(css)};
this.applyCSS();
}
// component.html
<igx-grid
#grid1 [data]="data"
primaryKey="ID"
width="80%"
height="300px">
<igx-column *ngFor="let c of columns"
[field]="c.field"
[header]="c.field"
[cellStyles]="c.cellStyles">
</igx-column>
</igx-grid>
Define a popin animation
// component.scss
@keyframes popin {
0% {
opacity: 0.1;
transform: scale(.75, .75);
filter: blur(3px) invert(1);
}
50% {
opacity: .5;
filter: blur(1px);
}
100% {
transform: scale(1, 1);
opacity: 1;
filter: none;
}
}
Demo
Known issues and limitations
- If there are cells bind to the same condition (from different columns) and one cell is updated, the other cells won't be updated based on the new value, if the condition is met.
A pipe check should be performed in order to apply the changes to the rest of the cells. The example below shows how to do that with a
spread operator(...)ononCellEditevent. This will copy the original object with a new instance, and lead pure pipe to be fired.
public backgroundClasses = {
myBackground: (rowData: any, columnKey: string) => {
return rowData.Col2 < 10;
}
};
...
editDone(evt) {
this.backgroundClasses = {...this.backgroundClasses};
}
<igx-grid #grid1 [data]="data" height="500px" width="100%" (onCellEdit)="editDone($event)">
<igx-column field="Col1" dataType="number" [cellClasses]="backgroundClasses"></igx-column>
<igx-column field="Col2" dataType="number" [editable]="true" [cellClasses]="backgroundClasses"></igx-column>
<igx-column field="Col3" header="Col3" dataType="string" [cellClasses]="backgroundClasses"></igx-column>
</igx-grid>
API References
Additional Resources
- Grid overview
- Virtualization and Performance
- Editing
- Paging
- Filtering
- Sorting
- Summaries
- Column Moving
- Column Pinning
- Column Resizing
- Column Hiding
- Selection
- Searching
- Toolbar
- Multi-column Headers
- Size