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

IgniteUI / igniteui-angular / 12788818376

15 Jan 2025 12:57PM CUT coverage: 91.595% (+0.003%) from 91.592%
12788818376

Pull #15226

github

web-flow
Merge 8b5559bf4 into 58936f8fc
Pull Request #15226: feat(elements-grid): Add content children ready event.

12986 of 15228 branches covered (85.28%)

26329 of 28745 relevant lines covered (91.6%)

34037.86 hits per line

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

93.9
/projects/igniteui-angular/src/lib/grids/filtering/excel-style/excel-style-custom-dialog.component.ts
1
import {
2
    Component,
3
    Input,
4
    ChangeDetectorRef,
5
    ViewChild,
6
    AfterViewInit,
7
    TemplateRef,
8
    ViewChildren,
9
    QueryList,
10
    ElementRef
11
} from '@angular/core';
12
import { IgxFilteringService } from '../grid-filtering.service';
13
import { FilteringLogic } from '../../../data-operations/filtering-expression.interface';
14
import { GridColumnDataType } from '../../../data-operations/data-util';
15
import {
16
    IgxStringFilteringOperand,
17
    IgxBooleanFilteringOperand,
18
    IgxNumberFilteringOperand,
19
    IgxDateFilteringOperand,
20
    IgxDateTimeFilteringOperand,
21
    IgxTimeFilteringOperand
22
} from '../../../data-operations/filtering-condition';
23
import { IgxToggleDirective } from '../../../directives/toggle/toggle.directive';
24
import { ILogicOperatorChangedArgs, IgxExcelStyleDefaultExpressionComponent } from './excel-style-default-expression.component';
25
import { IgxExcelStyleDateExpressionComponent } from './excel-style-date-expression.component';
26
import { PlatformUtil } from '../../../core/utils';
27
import { ExpressionUI } from './common';
28
import { ColumnType } from '../../common/grid.interface';
29
import { HorizontalAlignment, OverlaySettings, PositionSettings, VerticalAlignment } from '../../../services/overlay/utilities';
30
import { AutoPositionStrategy } from '../../../services/overlay/position/auto-position-strategy';
31
import { AbsoluteScrollStrategy } from '../../../services/overlay/scroll/absolute-scroll-strategy';
32
import { IgxOverlayService } from '../../../services/overlay/overlay';
33
import { IgxIconComponent } from '../../../icon/icon.component';
34
import { IgxButtonDirective } from '../../../directives/button/button.directive';
35
import { NgClass, NgIf, NgFor } from '@angular/common';
36

37
/**
38
 * @hidden
39
 */
40
@Component({
41
    selector: 'igx-excel-style-custom-dialog',
42
    templateUrl: './excel-style-custom-dialog.component.html',
43
    imports: [IgxToggleDirective, NgClass, NgIf, NgFor, IgxExcelStyleDateExpressionComponent, IgxExcelStyleDefaultExpressionComponent, IgxButtonDirective, IgxIconComponent]
44
})
45
export class IgxExcelStyleCustomDialogComponent implements AfterViewInit {
2✔
46
    @Input()
47
    public expressionsList = new Array<ExpressionUI>();
186✔
48

49
    @Input()
50
    public column: ColumnType;
51

52
    @Input()
53
    public selectedOperator: string;
54

55
    @Input()
56
    public filteringService: IgxFilteringService;
57

58
    @Input()
59
    public overlayComponentId: string;
60

61
    @ViewChild('toggle', { read: IgxToggleDirective, static: true })
62
    public toggle: IgxToggleDirective;
63

64
    @ViewChild('defaultExpressionTemplate', { read: TemplateRef })
65
    protected defaultExpressionTemplate: TemplateRef<any>;
66

67
    @ViewChild('dateExpressionTemplate', { read: TemplateRef })
68
    protected dateExpressionTemplate: TemplateRef<any>;
69

70
    @ViewChild('expressionsContainer', { static: true })
71
    protected expressionsContainer: ElementRef;
72

73
    @ViewChildren(IgxExcelStyleDefaultExpressionComponent)
74
    private expressionComponents: QueryList<IgxExcelStyleDefaultExpressionComponent>;
75

76
    @ViewChildren(IgxExcelStyleDateExpressionComponent)
77
    private expressionDateComponents: QueryList<IgxExcelStyleDateExpressionComponent>;
78

79
    private _customDialogPositionSettings: PositionSettings = {
186✔
80
        verticalDirection: VerticalAlignment.Middle,
81
        horizontalDirection: HorizontalAlignment.Center,
82
        horizontalStartPoint: HorizontalAlignment.Center,
83
        verticalStartPoint: VerticalAlignment.Middle
84
    };
85

86
    private _customDialogOverlaySettings: OverlaySettings = {
186✔
87
        closeOnOutsideClick: true,
88
        modal: false,
89
        positionStrategy: new AutoPositionStrategy(this._customDialogPositionSettings),
90
        scrollStrategy: new AbsoluteScrollStrategy()
91
    };
92

93

94
    constructor(
95
        protected overlayService: IgxOverlayService,
186✔
96
        private cdr: ChangeDetectorRef,
186✔
97
        protected platform: PlatformUtil,
186✔
98
    ) { }
99

100
    public ngAfterViewInit(): void {
101
        this._customDialogOverlaySettings.outlet = this.grid.outlet;
186✔
102
    }
103

104
    public get template(): TemplateRef<any> {
105
        if (this.column.dataType === GridColumnDataType.Date) {
×
106
            return this.dateExpressionTemplate;
×
107
        }
108

109
        return this.defaultExpressionTemplate;
×
110
    }
111

112
    public get grid(): any {
113
        return this.filteringService.grid;
7,116✔
114
    }
115

116
    public onCustomDialogOpening() {
117
        if (this.selectedOperator) {
34✔
118
            this.createInitialExpressionUIElement();
30✔
119
        }
120
    }
121

122
    public onCustomDialogOpened() {
123
        if (this.expressionComponents.first) {
34✔
124
            this.expressionComponents.first.focus();
16✔
125
        }
126
    }
127

128
    public open(esf) {
129
        this._customDialogOverlaySettings.target =
34✔
130
            this.overlayComponentId ?
34✔
131
                this.grid.rootGrid ? this.grid.rootGrid.nativeElement : this.grid.nativeElement :
32!
132
                esf;
133
        this.toggle.open(this._customDialogOverlaySettings);
34✔
134
        this.overlayComponentId = this.toggle.overlayId;
34✔
135
    }
136

137
    public onClearButtonClick() {
138
        this.filteringService.clearFilter(this.column.field);
2✔
139
        this.selectedOperator = null;
2✔
140
        this.createInitialExpressionUIElement();
2✔
141
        this.cdr.detectChanges();
2✔
142
    }
143

144
    public closeDialog() {
145
        if (this.overlayComponentId) {
15!
146
            this.overlayService.hide(this.overlayComponentId);
15✔
147
            this.overlayComponentId = null;
15✔
148
        } else {
149
            this.toggle.close();
×
150
        }
151
    }
152

153
    public onApplyButtonClick() {
154
        this.expressionsList = this.expressionsList.filter(
13✔
155
            element => element.expression.condition &&
27✔
156
                (element.expression.searchVal || element.expression.searchVal === 0 || element.expression.condition.isUnary));
157

158
        if (this.expressionsList.length > 0) {
13✔
159
            this.expressionsList[0].beforeOperator = null;
9✔
160
            this.expressionsList[this.expressionsList.length - 1].afterOperator = null;
9✔
161
        }
162

163
        this.filteringService.filterInternal(this.column.field, this.expressionsList);
13✔
164
        this.closeDialog();
13✔
165
    }
166

167
    public onAddButtonClick() {
168
        const exprUI = new ExpressionUI();
4✔
169
        exprUI.expression = {
4✔
170
            condition: null,
171
            fieldName: this.column.field,
172
            ignoreCase: this.column.filteringIgnoreCase,
173
            searchVal: null
174
        };
175

176
        this.expressionsList[this.expressionsList.length - 1].afterOperator = FilteringLogic.And;
4✔
177
        exprUI.beforeOperator = this.expressionsList[this.expressionsList.length - 1].afterOperator;
4✔
178

179
        this.expressionsList.push(exprUI);
4✔
180

181
        this.markChildrenForCheck();
4✔
182
        this.scrollToBottom();
4✔
183
    }
184

185
    public onExpressionRemoved(event: ExpressionUI) {
186
        const indexToRemove = this.expressionsList.indexOf(event);
2✔
187

188
        if (indexToRemove === 0 && this.expressionsList.length > 1) {
2!
189
            this.expressionsList[1].beforeOperator = null;
×
190
        } else if (indexToRemove === this.expressionsList.length - 1) {
2✔
191
            this.expressionsList[indexToRemove - 1].afterOperator = null;
1✔
192
        } else {
193
            this.expressionsList[indexToRemove - 1].afterOperator = this.expressionsList[indexToRemove + 1].beforeOperator;
1✔
194
            this.expressionsList[0].beforeOperator = null;
1✔
195
            this.expressionsList[this.expressionsList.length - 1].afterOperator = null;
1✔
196
        }
197

198
        this.expressionsList.splice(indexToRemove, 1);
2✔
199

200
        this.cdr.detectChanges();
2✔
201

202
        this.markChildrenForCheck();
2✔
203
    }
204

205
    public onLogicOperatorChanged(event: ILogicOperatorChangedArgs) {
206
        const index = this.expressionsList.indexOf(event.target);
4✔
207
        event.target.afterOperator = event.newValue;
4✔
208
        if (index + 1 < this.expressionsList.length) {
4✔
209
            this.expressionsList[index + 1].beforeOperator = event.newValue;
4✔
210
        }
211
    }
212

213
    public onKeyDown(eventArgs: KeyboardEvent) {
214
        eventArgs.stopPropagation();
3✔
215
    }
216

217
    public onApplyButtonKeyDown(eventArgs: KeyboardEvent) {
218
        if (eventArgs.key === this.platform.KEYMAP.TAB && !eventArgs.shiftKey) {
1✔
219
            eventArgs.stopPropagation();
1✔
220
            eventArgs.preventDefault();
1✔
221
        }
222
    }
223

224
    private createCondition(conditionName: string) {
225
        switch (this.column.dataType) {
31✔
226
            case GridColumnDataType.Boolean:
227
                return IgxBooleanFilteringOperand.instance().condition(conditionName);
1✔
228
            case GridColumnDataType.Number:
229
            case GridColumnDataType.Currency:
230
            case GridColumnDataType.Percent:
231
                return IgxNumberFilteringOperand.instance().condition(conditionName);
3✔
232
            case GridColumnDataType.Date:
233
                return IgxDateFilteringOperand.instance().condition(conditionName);
10✔
234
            case GridColumnDataType.Time:
235
                return IgxTimeFilteringOperand.instance().condition(conditionName);
2✔
236
            case GridColumnDataType.DateTime:
237
                return IgxDateTimeFilteringOperand.instance().condition(conditionName);
4✔
238
            default:
239
                return IgxStringFilteringOperand.instance().condition(conditionName);
11✔
240
        }
241
    }
242

243
    private markChildrenForCheck() {
244
        this.expressionComponents.forEach(x => x.cdr.markForCheck());
14✔
245
        this.expressionDateComponents.forEach(x => x.cdr.markForCheck());
6✔
246
    }
247

248
    private createInitialExpressionUIElement() {
249
        let firstExprUI = new ExpressionUI();
32✔
250
        if (this.expressionsList.length == 1 && this.expressionsList[0].expression.condition.name === this.selectedOperator) {
32✔
251
            firstExprUI = this.expressionsList.pop();
1✔
252
        } else {
253
            this.expressionsList = [];
31✔
254
            firstExprUI.expression = {
31✔
255
                condition: this.createCondition(this.selectedOperator),
256
                fieldName: this.column.field,
257
                ignoreCase: this.column.filteringIgnoreCase,
258
                searchVal: null
259
            };
260
        }
261

262
        firstExprUI.afterOperator = FilteringLogic.And;
32✔
263
        this.expressionsList.push(firstExprUI);
32✔
264

265
        const secondExprUI = new ExpressionUI();
32✔
266
        secondExprUI.expression = {
32✔
267
            condition: null,
268
            fieldName: this.column.field,
269
            ignoreCase: this.column.filteringIgnoreCase,
270
            searchVal: null
271
        };
272

273
        secondExprUI.beforeOperator = FilteringLogic.And;
32✔
274

275
        this.expressionsList.push(secondExprUI);
32✔
276
    }
277

278
    private scrollToBottom() {
279
        requestAnimationFrame(() => {
4✔
280
            this.expressionsContainer.nativeElement.scrollTop = this.expressionsContainer.nativeElement.scrollHeight;
4✔
281
        });
282
    }
283
}
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

© 2025 Coveralls, Inc