Skip to content

Commit 877930f

Browse files
authored
Merge pull request #6194 from IgniteUI/iminchev/grid-cell-merging
feat(grids): add cell merging topic
2 parents 79d4317 + 1f6ad98 commit 877930f

2 files changed

Lines changed: 204 additions & 0 deletions

File tree

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
---
2+
title: Angular Grid Cell Merging - Ignite UI for Angular
3+
_description: Position and size columns in a more powerful way, using the multi-row layout functionality in the Ignite UI for Angular Data Grid. Check out examples and demos!
4+
_keywords: angular cell merging, cell merging, ignite ui for angular
5+
---
6+
7+
# Angular Cell Merging
8+
9+
The Ignite UI for Angular @@igComponent provides a Cell Merging feature that combines two or more adjacent cells with the same value into a single, larger cell. Merging is applied vertically within a column and helps improve readability by reducing duplicate values. The feature can be configured to merge cells either by default matching data values or by applying a custom condition.
10+
11+
## Angular Cell Merging Example
12+
13+
@@if(igxName === 'IgxGrid'){
14+
<code-view style="height:755px"
15+
data-demos-base-url="{environment:demosBaseUrl}"
16+
iframe-src="{environment:demosBaseUrl}/grid/grid-cellMerge" alt="Angular Cell Merging Example">
17+
</code-view>
18+
}
19+
@@if(igxName === 'IgxHierarchicalGrid'){
20+
<code-view style="height:755px"
21+
data-demos-base-url="{environment:demosBaseUrl}"
22+
iframe-src="{environment:demosBaseUrl}/hierarchical-grid/hierarchical-grid-cell-merge" alt="Angular Cell Merging Example">
23+
</code-view>
24+
}
25+
@@if(igxName === 'IgxTreeGrid'){
26+
<code-view style="height:755px"
27+
data-demos-base-url="{environment:demosBaseUrl}"
28+
iframe-src="{environment:demosBaseUrl}/tree-grid/treegrid-cell-merge" alt="Angular Cell Merging Example">
29+
</code-view>
30+
}
31+
32+
## Enabling and Using Cell Merging
33+
34+
Cell merging in the grid is controlled at two levels:
35+
- Grid-level merge mode – determines when merging is applied.
36+
- Column-level merge toggle – determines which columns can merge cells.
37+
38+
### Grid Merge Mode
39+
The grid exposes a `cellMergeMode` property that accepts values from the `GridCellMergeMode` enum:
40+
- `always` - Merges any adjacent cells that meet the merging condition, regardless of sort state.
41+
- `onSort` - Merges adjacent cells only when the column is sorted **(default value)**.
42+
43+
```html
44+
<@@igSelector [data]="data" [cellMergeMode]="cellMergeMode">
45+
...
46+
</@@igSelector>
47+
```
48+
```ts
49+
protected cellMergeMode: GridCellMergeMode = 'always';
50+
```
51+
52+
### Column Merge Toggle
53+
At the column level, merging can be enabled or disabled with the `merge` property.
54+
55+
```html
56+
<igx-column field="OrderID" [merge]="true"></igx-column>
57+
<igx-column field="ShipperName" [merge]="false"></igx-column>
58+
```
59+
60+
In the above example:
61+
- The **OrderID** column will merge adjacent duplicate values.
62+
- The **ShipperName** column will render normally without merging.
63+
64+
### Combined Example
65+
66+
```html
67+
<@@igSelector [data]="data" [cellMergeMode]="cellMergeMode" [autoGenerate]="false">
68+
<igx-column field="OrderID" header="Order ID" [merge]="true"></igx-column>
69+
<igx-column field="ShipperName" header="Shipper Name" [merge]="true"></igx-column>
70+
<igx-column field="Salesperson" header="Salesperson"></igx-column>
71+
</@@igSelector>
72+
```
73+
```ts
74+
protected cellMergeMode: GridCellMergeMode = 'onSort';
75+
```
76+
Here, the grid is set to merge only when columns are sorted, and both Category and Product columns are configured for merging.
77+
78+
## Custom Merge Conditions
79+
In addition to the built-in `always` and `onSort` modes, the grid allows you to define a custom condition for merging cells through the `mergeStrategy` property. This strategy controls both how cells are compared and how merged ranges are calculated.
80+
81+
### Merge Strategy Interface
82+
A custom merge strategy must implement the `IGridMergeStrategy` interface:
83+
84+
```ts
85+
export interface IGridMergeStrategy {
86+
merge: (
87+
data: any[],
88+
field: string,
89+
comparer: (prevRecord: any, currentRecord: any, field: string) => boolean,
90+
result: any[],
91+
activeRowIndex?: number,
92+
grid?: GridType
93+
) => any[];
94+
95+
comparer: (prevRecord: any, record: any, field: string) => boolean;
96+
}
97+
```
98+
- `merge` - defines how merged cells are produced.
99+
- `comparer` - defines the condition to decide if two adjacent records should be merged.
100+
101+
@@if(igxName === 'IgxGrid' || igxName === 'IgxHierarchicalGrid'){
102+
### Extending the Default Strategy
103+
104+
If you only want to customize part of the behavior (for example, the comparer logic), you can extend the built-in `DefaultMergeStrategy` and override the relevant methods.
105+
106+
```ts
107+
export class MyCustomStrategy extends DefaultMergeStrategy {
108+
/* Merge only cells within their respective projects */
109+
public override comparer(prevRecord: any, record: any, field: string): boolean {
110+
const a = prevRecord[field];
111+
const b = record[field];
112+
const projA = prevRecord['ProjectName'];
113+
const projB = record['ProjectName'];
114+
return a === b && projA === projB;
115+
}
116+
}
117+
```
118+
}
119+
@@if(igxName === 'IgxTreeGrid'){
120+
The `IgxTreeGrid` provides two built-in strategies that implement the `IGridMergeStrategy` interface: `DefaultTreeGridMergeStrategy` and `ByLevelTreeGridMergeStrategy`. `DefaultTreeGridMergeStrategy` merges all cells with the same value, regardless of their hierarchical level. In contrast, `ByLevelTreeGridMergeStrategy` only merges cells if they have the same value and are located at the same level, making level a required condition for merging.
121+
122+
### Extending the Default Strategy
123+
124+
If you only want to customize part of the behavior (for example, the comparer logic), you can extend one of the built-in strategies, either `DefaultTreeGridMergeStrategy` or `ByLevelTreeGridMergeStrategy`, and override the relevant methods.
125+
126+
```ts
127+
export class MyCustomStrategy extends DefaultTreeGridMergeStrategy {
128+
/* Merge only cells within their respective projects */
129+
public override comparer(prevRecord: any, record: any, field: string): boolean {
130+
const a = prevRecord[field];
131+
const b = record[field];
132+
const projA = prevRecord['ProjectName'];
133+
const projB = record['ProjectName'];
134+
return a === b && projA === projB;
135+
}
136+
}
137+
```
138+
}
139+
140+
### Applying a Custom Strategy
141+
Once defined, assign the strategy to the grid through the `mergeStrategy` property:
142+
```html
143+
<@@igSelector [data]="data" [mergeStrategy]="customStrategy">
144+
<igx-column field="ActionID" [merge]="true"></igx-column>
145+
<igx-column field="ProjectName" [merge]="true"></igx-column>
146+
</@@igSelector>
147+
```
148+
```ts
149+
protected customStrategy = new MyCustomStrategy();
150+
```
151+
@@if(igxName === 'IgxGrid'){
152+
### Demo
153+
<code-view style="height:755px"
154+
data-demos-base-url="{environment:demosBaseUrl}"
155+
iframe-src="{environment:demosBaseUrl}/grid/grid-cellMerge-custom" alt="Angular Cell Merging Example with Custom Condition">
156+
</code-view>
157+
}
158+
159+
## Feature Integration
160+
Due to the specific behavior of merged cells it has to be noted how exactly it ties together with some of the other features of the grid:
161+
@@if(igxName === 'IgxGrid'){
162+
- **Expand/Collapse**: if a feature (such as master-detail, grouping, etc.) generates a non-data row, then the cell merging is interrupted and the group will be split.
163+
}
164+
- **Excel export**: merged cells remain merged when exported to Excel.
165+
- **Column pinning**: cells remain merged when a column is pinned and are displayed in the pinned area.
166+
- **Row pinning**: cells merge only withing their containing area, i.e. cells of pinned rows merge only with cells of other pinned rows, while cells of unpinned rows merge only with cells of unpinned rows.
167+
- **Navigation/Activation**: when a cell is active, all merged cells in the same row become single cells, i.e. their merge sequence is broken. This also includes activation via keyboard navigation.
168+
169+
>[!NOTE]
170+
> If a merged cell is clicked, the closest cell from the merge sequence will become active.
171+
172+
- **Updating/Editing**: since activation breaks the merge sequence, only a single cell will be in edit mode.
173+
- **Row selection**: if selected rows intersect merged cells, all related merged cells should be marked as part of the selection.
174+
175+
@@if(igxName === 'IgxGrid'){
176+
## Limitations
177+
|Known Limitations| Description|
178+
| --- | --- |
179+
| Cell merging is not supported in combination with Multi-row Layout. | Both span complex layouts that don't make sense when combined. A warning will be thrown if such invalid configuration is detected. |
180+
}
181+
182+
## API References
183+
* [@@igxNameComponent API]({environment:angularApiUrl}/classes/@@igTypeDoc.html)
184+
* [@@igxNameComponent Styles]({environment:sassApiUrl}/themes#function-grid-theme)
185+
186+
## Additional Resources
187+
<div class="divider--half"></div>
188+
189+
* [@@igComponent overview](@@igMainTopic.md)
190+
191+
<div class="divider--half"></div>
192+
Our community is active and always welcoming to new ideas.
193+
194+
* [Ignite UI for Angular **Forums**](https://www.infragistics.com/community/forums/f/ignite-ui-for-angular)
195+
* [Ignite UI for Angular **GitHub**](https://github.com/IgniteUI/igniteui-angular)

en/components/toc.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,9 @@
265265
- name: State Persistence
266266
href: grid/state-persistence.md
267267
updated: false
268+
- name: Cell Merging
269+
href: grid/cell-merging.md
270+
new: true
268271
- name: Tree Grid
269272
href: treegrid/tree-grid.md
270273
new: false
@@ -406,6 +409,9 @@
406409
- name: State Persistence
407410
href: treegrid/state-persistence.md
408411
new: false
412+
- name: Cell Merging
413+
href: treegrid/cell-merging.md
414+
new: true
409415
- name: Hierarchical Grid
410416
href: hierarchicalgrid/hierarchical-grid.md
411417
new: false
@@ -542,6 +548,9 @@
542548
- name: State Persistence
543549
href: hierarchicalgrid/state-persistence.md
544550
new: false
551+
- name: Cell Merging
552+
href: hierarchicalgrid/cell-merging.md
553+
new: true
545554
- name: Pivot Grid
546555
href: pivotGrid/pivot-grid.md
547556
new: false

0 commit comments

Comments
 (0)