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

IgniteUI / igniteui-angular / 16053471080

03 Jul 2025 02:41PM UTC coverage: 4.981% (-86.4%) from 91.409%
16053471080

Pull #16021

github

web-flow
Merge 7c49966eb into 7e40671a1
Pull Request #16021: fix(radio-group): dynamically added radio buttons do not initialize

178 of 15753 branches covered (1.13%)

13 of 14 new or added lines in 2 files covered. (92.86%)

25644 existing lines in 324 files now uncovered.

1478 of 29670 relevant lines covered (4.98%)

0.51 hits per line

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

1.3
/projects/igniteui-angular/src/lib/grids/filtering/base/grid-filtering-cell.component.ts
1
import {
2
    AfterViewInit,
3
    ChangeDetectionStrategy,
4
    ChangeDetectorRef,
5
    Component,
6
    DoCheck,
7
    ElementRef,
8
    HostBinding,
9
    Input,
10
    OnInit,
11
    TemplateRef,
12
    ViewChild
13
} from '@angular/core';
14
import { IFilteringExpression } from '../../../data-operations/filtering-expression.interface';
15
import { IgxFilteringService } from '../grid-filtering.service';
16
import { ExpressionUI } from '../excel-style/common';
17
import { IgxChipsAreaComponent } from '../../../chips/chips-area.component';
18
import { IBaseChipEventArgs, IgxChipComponent } from '../../../chips/chip.component';
19
import { ColumnType } from '../../common/grid.interface';
20
import { IgxBadgeComponent } from '../../../badge/badge.component';
21
import { NgClass, NgTemplateOutlet } from '@angular/common';
22
import { IgxPrefixDirective } from '../../../directives/prefix/prefix.directive';
23
import { IgxIconComponent } from '../../../icon/icon.component';
24
import { Size } from '../../common/enums';
25

26
/**
27
 * @hidden
28
 */
29
@Component({
30
    changeDetection: ChangeDetectionStrategy.OnPush,
31
    selector: 'igx-grid-filtering-cell',
32
    templateUrl: './grid-filtering-cell.component.html',
33
    imports: [
34
        IgxChipsAreaComponent,
35
        IgxChipComponent,
36
        IgxIconComponent,
37
        IgxPrefixDirective,
38
        NgClass,
39
        IgxBadgeComponent,
40
        NgTemplateOutlet
41
    ]
42
})
43
export class IgxGridFilteringCellComponent implements AfterViewInit, OnInit, DoCheck {
3✔
44
    @Input()
45
    public column: ColumnType;
46

47
    @ViewChild('emptyFilter', { read: TemplateRef, static: true })
48
    protected emptyFilter: TemplateRef<any>;
49

50
    @ViewChild('defaultFilter', { read: TemplateRef, static: true })
51
    protected defaultFilter: TemplateRef<any>;
52

53
    @ViewChild('complexFilter', { read: TemplateRef, static: true })
54
    protected complexFilter: TemplateRef<any>;
55

56
    @ViewChild('chipsArea', { read: IgxChipsAreaComponent })
57
    protected chipsArea: IgxChipsAreaComponent;
58

59
    @ViewChild('moreIcon', { read: ElementRef })
60
    protected moreIcon: ElementRef;
61

62
    @ViewChild('ghostChip', { read: IgxChipComponent })
63
    protected ghostChip: IgxChipComponent;
64

65
    @ViewChild('complexChip', { read: IgxChipComponent })
66
    protected complexChip: IgxChipComponent;
67

68

69
    @HostBinding('class')
70
    public get styleClasses(): string {
UNCOV
71
        return this.column && this.column.selected ?
×
72
            'igx-grid__filtering-cell--selected' :
73
            'igx-grid__filtering-cell';
74
    }
75

76
    public expressionsList: ExpressionUI[];
UNCOV
77
    public moreFiltersCount = 0;
×
78

UNCOV
79
    private baseClass = 'igx-grid__filtering-cell-indicator';
×
80

81
    constructor(
UNCOV
82
        public cdr: ChangeDetectorRef,
×
UNCOV
83
        public filteringService: IgxFilteringService,
×
84
    ) {
UNCOV
85
        this.filteringService.subscribeToEvents();
×
86
    }
87

88
    public ngOnInit(): void {
UNCOV
89
        this.filteringService.columnToMoreIconHidden.set(this.column.field, true);
×
90
    }
91

92
    public ngAfterViewInit(): void {
UNCOV
93
        this.updateFilterCellArea();
×
94
    }
95

96
    public ngDoCheck() {
UNCOV
97
        this.updateFilterCellArea();
×
98
    }
99

100
    /**
101
     * Returns whether a chip with a given index is visible or not.
102
     */
103
    public isChipVisible(index: number) {
UNCOV
104
        const expression = this.expressionsList[index];
×
UNCOV
105
        return !!(expression && expression.isVisible);
×
106
    }
107

108
    /**
109
     * Updates the filtering cell area.
110
     */
111
    public updateFilterCellArea() {
UNCOV
112
        this.expressionsList = this.filteringService.getExpressions(this.column.field);
×
UNCOV
113
        this.updateVisibleFilters();
×
114
    }
115

116
    public get template(): TemplateRef<any> {
UNCOV
117
        if (!this.column.filterable) {
×
UNCOV
118
            return null;
×
119
        }
UNCOV
120
        if (this.column.filterCellTemplate) {
×
UNCOV
121
            return this.column.filterCellTemplate;
×
122
        }
UNCOV
123
        const expressionTree = this.column.filteringExpressionsTree;
×
UNCOV
124
        if (!expressionTree || expressionTree.filteringOperands.length === 0) {
×
UNCOV
125
            return this.emptyFilter;
×
126
        }
UNCOV
127
        if (this.filteringService.isFilterComplex(this.column.field)) {
×
128
            return this.complexFilter;
×
129
        }
UNCOV
130
        return this.defaultFilter;
×
131
    }
132

133
    /**
134
     * Gets the context passed to the filter template.
135
     *
136
     * @memberof IgxGridFilteringCellComponent
137
     */
138
    public get context() {
UNCOV
139
        return { $implicit: this.column, column: this.column};
×
140
    }
141

142
    /**
143
     * Chip clicked event handler.
144
     */
145
    public onChipClicked(expression?: IFilteringExpression) {
UNCOV
146
        if (expression) {
×
UNCOV
147
            this.expressionsList.forEach((item) => {
×
UNCOV
148
                item.isSelected = (item.expression === expression);
×
149
            });
UNCOV
150
        } else if (this.expressionsList.length > 0) {
×
UNCOV
151
            this.expressionsList.forEach((item) => {
×
UNCOV
152
                item.isSelected = false;
×
153
            });
UNCOV
154
            this.expressionsList[0].isSelected = true;
×
155
        }
UNCOV
156
        this.filteringService.grid.navigation.performHorizontalScrollToCell(this.column.visibleIndex);
×
UNCOV
157
        this.filteringService.filteredColumn = this.column;
×
UNCOV
158
        this.filteringService.isFilterRowVisible = true;
×
UNCOV
159
        this.filteringService.selectedExpression = expression;
×
160
    }
161

162
    /**
163
     * Chip removed event handler.
164
     */
165
    public onChipRemoved(eventArgs: IBaseChipEventArgs, item: ExpressionUI): void {
UNCOV
166
        const indexToRemove = this.expressionsList.indexOf(item);
×
UNCOV
167
        this.removeExpression(indexToRemove);
×
UNCOV
168
        this.filteringService.grid.theadRow.nativeElement.focus();
×
169
    }
170

171
    /**
172
     * Clears the filtering.
173
     */
174
    public clearFiltering(): void {
UNCOV
175
        this.filteringService.clearFilter(this.column.field);
×
UNCOV
176
        this.cdr.detectChanges();
×
177
    }
178

179
    /**
180
     * Returns the filtering indicator class.
181
     */
182
    public filteringIndicatorClass() {
UNCOV
183
        return {
×
184
            [this.baseClass]: !this.isMoreIconHidden(),
185
            [`${this.baseClass}--hidden`]: this.isMoreIconHidden()
186
        };
187
    }
188

189
    protected get filteringElementsSize(): Size {
UNCOV
190
        return this.column.grid.gridSize === Size.Large ? Size.Medium : this.column.grid.gridSize;
×
191
    }
192

193
    private removeExpression(indexToRemove: number) {
UNCOV
194
        if (indexToRemove === 0 && this.expressionsList.length === 1) {
×
UNCOV
195
            this.clearFiltering();
×
UNCOV
196
            return;
×
197
        }
198

UNCOV
199
        this.filteringService.removeExpression(this.column.field, indexToRemove);
×
200

UNCOV
201
        this.updateVisibleFilters();
×
UNCOV
202
        this.filteringService.filterInternal(this.column.field);
×
203
    }
204

205
    private isMoreIconHidden(): boolean {
UNCOV
206
        return this.filteringService.columnToMoreIconHidden.get(this.column.field);
×
207
    }
208

209
    private updateVisibleFilters() {
UNCOV
210
        this.expressionsList.forEach((ex) => ex.isVisible = true);
×
211

UNCOV
212
        if (this.moreIcon) {
×
UNCOV
213
            this.filteringService.columnToMoreIconHidden.set(this.column.field, true);
×
214
        }
UNCOV
215
        this.cdr.detectChanges();
×
216

UNCOV
217
        if (this.chipsArea && this.expressionsList.length > 1) {
×
UNCOV
218
            const areaWidth = this.chipsArea.element.nativeElement.offsetWidth;
×
UNCOV
219
            let viewWidth = 0;
×
UNCOV
220
            const chipsAreaElements = this.chipsArea.element.nativeElement.children;
×
UNCOV
221
            let visibleChipsCount = 0;
×
UNCOV
222
            const moreIconWidth = this.moreIcon.nativeElement.offsetWidth -
×
223
                parseInt(this.column?.grid.document.defaultView.getComputedStyle(this.moreIcon.nativeElement)['margin-left'], 10);
224

UNCOV
225
            for (let index = 0; index < chipsAreaElements.length - 1; index++) {
×
UNCOV
226
                if (viewWidth + chipsAreaElements[index].offsetWidth < areaWidth) {
×
UNCOV
227
                    viewWidth += chipsAreaElements[index].offsetWidth;
×
UNCOV
228
                    if (index % 2 === 0) {
×
UNCOV
229
                        visibleChipsCount++;
×
230
                    } else {
UNCOV
231
                        viewWidth += parseInt(this.column?.grid.document.defaultView.getComputedStyle(chipsAreaElements[index])['margin-left'], 10);
×
UNCOV
232
                        viewWidth += parseInt(this.column?.grid.document.defaultView.getComputedStyle(chipsAreaElements[index])['margin-right'], 10);
×
233
                    }
234
                } else {
UNCOV
235
                    if (index % 2 !== 0 && viewWidth + moreIconWidth > areaWidth) {
×
236
                        visibleChipsCount--;
×
UNCOV
237
                    } else if (visibleChipsCount > 0 && viewWidth - chipsAreaElements[index - 1].offsetWidth + moreIconWidth > areaWidth) {
×
UNCOV
238
                        visibleChipsCount--;
×
239
                    }
UNCOV
240
                    this.moreFiltersCount = this.expressionsList.length - visibleChipsCount;
×
UNCOV
241
                    this.filteringService.columnToMoreIconHidden.set(this.column.field, false);
×
UNCOV
242
                    break;
×
243
                }
244
            }
245

UNCOV
246
            for (let i = visibleChipsCount; i < this.expressionsList.length; i++) {
×
UNCOV
247
                this.expressionsList[i].isVisible = false;
×
248
            }
UNCOV
249
            this.cdr.detectChanges();
×
250
        }
251
    }
252
}
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