• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

IgniteUI / igniteui-angular / 15445220374

04 Jun 2025 02:36PM UTC coverage: 91.391% (-0.06%) from 91.446%
15445220374

Pull #15603

github

web-flow
Merge 53f1366d3 into 9c31d23ec
Pull Request #15603: Refactor how the grid calculates the size of the body.

13348 of 15671 branches covered (85.18%)

7 of 8 new or added lines in 3 files covered. (87.5%)

47 existing lines in 7 files now uncovered.

26974 of 29515 relevant lines covered (91.39%)

34084.81 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.68
/projects/igniteui-angular/src/lib/grids/columns/column-group.component.ts
1
import {
2
    AfterContentInit,
3
    Component,
4
    ContentChildren,
5
    ChangeDetectionStrategy,
6
    Input,
7
    forwardRef,
8
    QueryList,
9
    TemplateRef,
10
    booleanAttribute
11
} from '@angular/core';
12
import { takeUntil } from 'rxjs/operators';
13

14
import { IgxColumnComponent } from './column.component';
15
import { flatten } from '../../core/utils';
16
import { CellType, ColumnType, IgxColumnTemplateContext } from '../common/grid.interface';
17

18
/* blazorElement */
19
/* omitModule */
20
/* wcElementTag: igc-column-group */
21
/* additionalIdentifier: Children.Field */
22
/* jsonAPIManageCollectionInMarkup */
23
/* blazorIndirectRender */
24
/**
25
 * **Ignite UI for Angular Column Group**
26
 *
27
 * @igxParent IgxGridComponent, IgxTreeGridComponent, IgxHierarchicalGridComponent, IgxColumnGroupComponent, IgxRowIslandComponent
28
 */
29
@Component({
30
    changeDetection: ChangeDetectionStrategy.OnPush,
31
    providers: [{ provide: IgxColumnComponent, useExisting: forwardRef(() => IgxColumnGroupComponent) }],
1,043✔
32
    selector: 'igx-column-group',
33
    template: `@if (platform.isElements) {
34
        <ng-content select="igx-column,igc-column,igx-column-group,igc-column-group"></ng-content>
35
    }`,
36
    styles: `:host { display: none }`,
37
    standalone: true
38
})
39
export class IgxColumnGroupComponent extends IgxColumnComponent implements AfterContentInit {
3✔
40

41
    /* blazorInclude */
42
    /* contentChildren */
43
    /* blazorTreatAsCollection */
44
    /* blazorCollectionName: ColumnCollection */
45
    /* blazorCollectionItemName: Column */
46
    /* alternateType: HTMLCollection */
47
    /**
48
     * @deprecated in version 18.1.0. Use the `childColumns` property instead.
49
     */
50
    @ContentChildren(IgxColumnComponent, { read: IgxColumnComponent,  })
51
    public override children = new QueryList<IgxColumnComponent>();
2,172✔
52

53
    /**
54
     * Set if the column group is collapsible.
55
     * Default value is `false`
56
     * ```html
57
     *  <igx-column-group [collapsible] = "true"></igx-column-group>
58
     * ```
59
     *
60
     * @memberof IgxColumnGroupComponent
61
     */
62
    @Input({ transform: booleanAttribute })
63
    public override set collapsible(value: boolean) {
64
        this._collapsible = value;
223✔
65
        this.collapsibleChange.emit(this._collapsible);
223✔
66
        if (this.children && !this.hidden) {
223✔
67
            if (this._collapsible) {
7✔
68
                this.setExpandCollapseState();
2✔
69
            } else {
70
                this.children.forEach(child => child.hidden = false);
6✔
71
            }
72
        }
73
    }
74
    public override get collapsible() {
75
        return this._collapsible && this.checkCollapsibleState();
30,388✔
76
    }
77

78
    /**
79
     * Set whether the group is expanded or collapsed initially.
80
     * Applied only if the collapsible property is set to `true`
81
     * Default value is `true`
82
     * ```html
83
     *  const state = false
84
     *  <igx-column-group [(expand)] = "state"></igx-column-group>
85
     * ```
86
     *
87
     * @memberof IgxColumnGroupComponent
88
     */
89
    @Input({ transform: booleanAttribute })
90
    public override set expanded(value: boolean) {
91
        this._expanded = value;
149✔
92
        this.expandedChange.emit(this._expanded);
149✔
93
        if (!this.collapsible) {
149✔
94
            return;
121✔
95
        }
96
        if (!this.hidden && this.children) {
28✔
97
            this.setExpandCollapseState();
28✔
98
        }
99
    }
100
    public override get expanded() {
101
        return this._expanded;
14,387✔
102
    }
103

104
    /**
105
     * Gets the column group `summaries`.
106
     * ```typescript
107
     * let columnGroupSummaries = this.columnGroup.summaries;
108
     * ```
109
     *
110
     * @memberof IgxColumnGroupComponent
111
     */
112
    @Input()
113
    public override get summaries(): any {
114
        return this._summaries;
41✔
115
    }
116

117
     /* blazorSuppress */
118
    /**
119
     * Sets the column group `summaries`.
120
     * ```typescript
121
     * this.columnGroup.summaries = IgxNumberSummaryOperand;
122
     * ```
123
     *
124
     * @memberof IgxColumnGroupComponent
125
     */
126
    public override set summaries(classRef: any) { }
127

128
     /* blazorSuppress */
129
    /**
130
     * Sets/gets whether the column group is `searchable`.
131
     * Default value is `true`.
132
     * ```typescript
133
     * let isSearchable =  this.columnGroup.searchable;
134
     * ```
135
     * ```html
136
     *  <igx-column-group [searchable] = "false"></igx-column-group>
137
     * ```
138
     *
139
     * @memberof IgxColumnGroupComponent
140
     */
141
    @Input({ transform: booleanAttribute })
142
    public override searchable = true;
2,172✔
143
    /**
144
     * Gets the column group `filters`.
145
     * ```typescript
146
     * let columnGroupFilters = this.columnGroup.filters;
147
     * ```
148
     *
149
     * @memberof IgxColumnGroupComponent
150
     */
151
    @Input()
152
    public override get filters(): any {
153
        return this._filters;
41✔
154
    }
155

156
     /* blazorSuppress */
157
    /**
158
     * Sets the column group `filters`.
159
     * ```typescript
160
     * this.columnGroup.filters = IgxStringFilteringOperand;
161
     * ```
162
     *
163
     * @memberof IgxColumnGroupComponent
164
     */
165
    public override set filters(classRef: any) { }
166

167
    /**
168
     * Returns if the column group is selectable
169
     * ```typescript
170
     * let columnGroupSelectable = this.columnGroup.selectable;
171
     * ```
172
     *
173
     * @memberof IgxColumnGroupComponent
174
     */
175
    public override get selectable(): boolean {
176
        return this.children && this.children.some(child => child.selectable);
5,709✔
177
    }
178

179
    /**
180
     * @hidden
181
     */
182
    public override set selectable(value: boolean) { }
183

184
    /**
185
     * @hidden
186
     */
187
    public override get bodyTemplate(): TemplateRef<any> {
188
        return this._bodyTemplate;
41✔
189
    }
190
    /**
191
     * @hidden
192
     */
193
    public override set bodyTemplate(template: TemplateRef<any>) { }
194

195
    /**
196
     * Allows you to define a custom template for expand/collapse indicator
197
     *
198
     * @memberof IgxColumnGroupComponent
199
     */
200
    @Input()
201
    public override collapsibleIndicatorTemplate: TemplateRef<IgxColumnTemplateContext>;
202

203
    /**
204
     * @hidden
205
     */
206
    public override get inlineEditorTemplate(): TemplateRef<any> {
207
        return this._inlineEditorTemplate;
41✔
208
    }
209
    /**
210
     * @hidden
211
     */
212
    public override set inlineEditorTemplate(template: TemplateRef<any>) { }
213
    /**
214
     * @hidden @internal
215
     */
216
    public override get cells(): CellType[] {
UNCOV
217
        return [];
×
218
    }
219
    /**
220
     * Gets whether the column group is hidden.
221
     * ```typescript
222
     * let isHidden = this.columnGroup.hidden;
223
     * ```
224
     *
225
     * @memberof IgxColumnGroupComponent
226
     */
227
    @Input({ transform: booleanAttribute })
228
    public override get hidden() {
229
        return this.allChildren.every(c => c.hidden);
96,122✔
230
    }
231

232
    /* blazorSuppress */
233
    /**
234
     * Sets the column group hidden property.
235
     * ```html
236
     * <igx-column [hidden] = "true"></igx-column>
237
     * ```
238
     *
239
     * Two-way data binding
240
     * ```html
241
     * <igx-column [(hidden)] = "model.columns[0].isHidden"></igx-column>
242
     * ```
243
     *
244
     * @memberof IgxColumnGroupComponent
245
     */
246
    public override set hidden(value: boolean) {
247
        this._hidden = value;
375✔
248
        this.hiddenChange.emit(this._hidden);
375✔
249
        if (this._hidden || !this.collapsible) {
375✔
250
            this.children.forEach(child => child.hidden = this._hidden);
722✔
251
        } else {
252
            this.children.forEach(c => {
2✔
253
                if (c.visibleWhenCollapsed === undefined) {
4!
UNCOV
254
                    c.hidden = false; return;
×
255
                }
256
                c.hidden = this.expanded ? c.visibleWhenCollapsed : !c.visibleWhenCollapsed;
4✔
257
            });
258
        }
259
    }
260

261
    /**
262
     * Returns if the column group is selected.
263
     * ```typescript
264
     * let isSelected = this.columnGroup.selected;
265
     * ```
266
     *
267
     * @memberof IgxColumnGroupComponent
268
     */
269
    public override get selected(): boolean {
270
        const selectableChildren = this.allChildren.filter(c => !c.columnGroup && c.selectable && !c.hidden);
88,442✔
271
        return selectableChildren.length > 0 && selectableChildren.every(c => c.selected);
27,498✔
272
    }
273

274
     /* blazorSuppress */
275
    /**
276
     * Select/deselect the column group.
277
     * ```typescript
278
     * this.columnGroup.selected = true;
279
     * ```
280
     *
281
     * @memberof IgxColumnGroupComponent
282
     */
283
    public override set selected(value: boolean) {
284
        if (this.selectable) {
12✔
285
            this.children.forEach(c => {
9✔
286
                c.selected = value;
21✔
287
            });
288
        }
289
    }
290

291
    /**
292
     * @hidden
293
     */
294
    public override ngAfterContentInit() {
295
        /*
296
            @ContentChildren with descendants still returns the `parent`
297
            component in the query list.
298
        */
299
        if (this.headTemplate && this.headTemplate.length) {
2,172✔
300
            this._headerTemplate = this.headTemplate.toArray()[0].template;
2✔
301
        }
302
        if (this.collapseIndicatorTemplate) {
2,172✔
303
            this.collapsibleIndicatorTemplate = this.collapseIndicatorTemplate.template;
2✔
304
        }
305
        // currently only ivy fixes the issue, we have to slice only if the first child is group
306
        if (this.children.first === this) {
2,172!
UNCOV
307
            this.children.reset(this.children.toArray().slice(1));
×
308
        }
309
        this.children.forEach(child => {
2,172✔
310
            child.parent = this;
3,394✔
311
            if (this.pinned) {
3,394✔
312
                child.pinned = this.pinned;
106✔
313
            }
314
            if (this._hidden) {
3,394✔
315
                child.hidden = this._hidden;
74✔
316
            }
317
        });
318
        if (this.collapsible) {
2,172✔
319
            this.setExpandCollapseState();
53✔
320
        }
321

322
        this.children.changes
2,172✔
323
            .pipe(takeUntil(this.destroy$))
324
            .subscribe((change: QueryList<IgxColumnComponent>) => {
325
                let shouldReinitPinning = false;
63✔
326
                change.forEach(x => {
63✔
327
                    x.parent = this;
204✔
328
                    if (this.pinned && x.pinned !== this.pinned) {
204!
UNCOV
329
                        shouldReinitPinning = true;
×
330
                        x.pinned = this.pinned;
×
331
                    }
332
                });
333
                if (this.collapsible) {
63✔
334
                    this.setExpandCollapseState();
3✔
335
                }
336
                if (shouldReinitPinning) {
63!
UNCOV
337
                    (this.grid as any).initPinning();
×
338
                }
339
            });
340

341
    }
342

343
    /**
344
     * A list containing all the child columns under this column (if any).
345
     * Empty without children or if this column is not Group or Layout.
346
     */
347
    public override get childColumns(): ColumnType[] {
348
        return this.children.toArray();
31✔
349
    }
350

351
    /** @hidden @internal **/
352
    public override get allChildren(): IgxColumnComponent[] {
353
        return flatten(this.children.toArray());
157,434✔
354
    }
355
    /**
356
     * Returns a boolean indicating if the column is a `ColumnGroup`.
357
     * ```typescript
358
     * let isColumnGroup =  this.columnGroup.columnGroup
359
     * ```
360
     *
361
     * @memberof IgxColumnGroupComponent
362
     */
363
    public override get columnGroup() {
364
        return true;
1,323,439✔
365
    }
366
    /**
367
     * Returns a boolean indicating if the column is a `ColumnLayout` for multi-row layout.
368
     * ```typescript
369
     * let columnGroup =  this.column.columnGroup;
370
     * ```
371
     *
372
     * @memberof IgxColumnComponent
373
     */
374
    public override get columnLayout() {
375
        return false;
3,818,388✔
376
    }
377
    /**
378
     * Gets the width of the column group.
379
     * ```typescript
380
     * let columnGroupWidth = this.columnGroup.width;
381
     * ```
382
     *
383
     * @memberof IgxColumnGroupComponent
384
     */
385
    public override get width() {
386
        const width = `${this.children.reduce((acc, val) => {
78,874✔
387
            if (val.hidden) {
174,700✔
388
                return acc;
11,028✔
389
            }
390
            return acc + parseFloat(val.calcWidth);
163,672✔
391
        }, 0)}`;
392
        return width + 'px';
78,874✔
393
    }
394

395
     /* blazorSuppress */
396
    public override set width(val) { }
397

398
    /** @hidden @internal **/
399
    public override get resolvedWidth() {
400
        return this.width;
33,418✔
401
    }
402

403
    /**
404
     * @hidden
405
     */
406
    public override get applySelectableClass(): boolean {
407
        return this._applySelectableClass;
5,545✔
408
    }
409

410
    /**
411
     * @hidden
412
     */
413
    public override set applySelectableClass(value: boolean) {
414
        if (this.selectable) {
10✔
415
            this._applySelectableClass = value;
6✔
416
            this.children.forEach(c => {
6✔
417
                c.applySelectableClass = value;
12✔
418
            });
419
        }
420
    }
421

422
    /**
423
     * @hidden
424
     * Calculates the number of visible columns, based on indexes of first and last visible columns.
425
     */
426
    public override calcChildren(): number {
427
        const visibleChildren = this.allChildren.filter(c => c.visibleIndex > -1);
82✔
428
        const fi = visibleChildren[0].visibleIndex;
22✔
429
        const li = visibleChildren[visibleChildren.length - 1].visibleIndex;
22✔
430
        return li - fi + 1;
22✔
431
    }
432
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc