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

IgniteUI / igniteui-angular / 16193550997

10 Jul 2025 11:12AM UTC coverage: 4.657% (-87.0%) from 91.64%
16193550997

Pull #16028

github

web-flow
Merge f7a9963b8 into 87246e3ce
Pull Request #16028: fix(radio-group): dynamically added radio buttons do not initialize

178 of 15764 branches covered (1.13%)

18 of 19 new or added lines in 2 files covered. (94.74%)

25721 existing lines in 324 files now uncovered.

1377 of 29570 relevant lines covered (4.66%)

0.53 hits per line

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

2.94
/projects/igniteui-angular/src/lib/select/select.component.ts
1
import {
2
    AfterContentChecked,
3
    AfterContentInit,
4
    AfterViewInit,
5
    booleanAttribute,
6
    ChangeDetectorRef,
7
    Component,
8
    ContentChild,
9
    ContentChildren,
10
    Directive,
11
    ElementRef,
12
    EventEmitter,
13
    forwardRef,
14
    HostBinding,
15
    Inject,
16
    Injector,
17
    Input,
18
    OnDestroy,
19
    OnInit,
20
    Optional,
21
    Output,
22
    QueryList,
23
    TemplateRef,
24
    ViewChild,
25
    ViewChildren
26
} from '@angular/core';
27
import { DOCUMENT, NgTemplateOutlet } from '@angular/common';
28
import { AbstractControl, ControlValueAccessor, NgControl, NG_VALUE_ACCESSOR } from '@angular/forms';
29
import { noop } from 'rxjs';
30
import { takeUntil } from 'rxjs/operators';
31

32
import { EditorProvider } from '../core/edit-provider';
33
import { IgxSelectionAPIService } from '../core/selection';
34
import { IBaseCancelableBrowserEventArgs, IBaseEventArgs } from '../core/utils';
35
import { IgxLabelDirective } from '../directives/label/label.directive';
36
import { IgxDropDownItemBaseDirective } from '../drop-down/drop-down-item.base';
37
import { IGX_DROPDOWN_BASE, ISelectionEventArgs, Navigate } from '../drop-down/drop-down.common';
38
import { IgxInputGroupComponent } from '../input-group/input-group.component';
39
import { AbsoluteScrollStrategy } from '../services/overlay/scroll/absolute-scroll-strategy';
40
import { OverlaySettings } from '../services/overlay/utilities';
41
import { IgxDropDownComponent } from './../drop-down/drop-down.component';
42
import { IgxSelectItemComponent } from './select-item.component';
43
import { SelectPositioningStrategy } from './select-positioning-strategy';
44
import { IgxSelectBase } from './select.common';
45
import { IgxHintDirective, IgxInputGroupType, IgxPrefixDirective, IGX_INPUT_GROUP_TYPE } from '../input-group/public_api';
46
import { ToggleViewCancelableEventArgs, ToggleViewEventArgs, IgxToggleDirective } from '../directives/toggle/toggle.directive';
47
import { IgxOverlayService } from '../services/overlay/overlay';
48
import { IgxIconComponent } from '../icon/icon.component';
49
import { IgxSuffixDirective } from '../directives/suffix/suffix.directive';
50
import { IgxSelectItemNavigationDirective } from './select-navigation.directive';
51
import { IgxInputDirective, IgxInputState } from '../directives/input/input.directive';
52

53
/** @hidden @internal */
54
@Directive({
55
    selector: '[igxSelectToggleIcon]',
56
    standalone: true
57
})
58
export class IgxSelectToggleIconDirective {
3✔
59
}
60

61
/** @hidden @internal */
62
@Directive({
63
    selector: '[igxSelectHeader]',
64
    standalone: true
65
})
66
export class IgxSelectHeaderDirective {
3✔
67
}
68

69
/** @hidden @internal */
70
@Directive({
71
    selector: '[igxSelectFooter]',
72
    standalone: true
73
})
74
export class IgxSelectFooterDirective {
3✔
75
}
76

77
/**
78
 * **Ignite UI for Angular Select** -
79
 * [Documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/select)
80
 *
81
 * The `igxSelect` provides an input with dropdown list allowing selection of a single item.
82
 *
83
 * Example:
84
 * ```html
85
 * <igx-select #select1 [placeholder]="'Pick One'">
86
 *   <label igxLabel>Select Label</label>
87
 *   <igx-select-item *ngFor="let item of items" [value]="item.field">
88
 *     {{ item.field }}
89
 *   </igx-select-item>
90
 * </igx-select>
91
 * ```
92
 */
93
@Component({
94
    selector: 'igx-select',
95
    templateUrl: './select.component.html',
96
    providers: [
97
        { provide: NG_VALUE_ACCESSOR, useExisting: IgxSelectComponent, multi: true },
98
        { provide: IGX_DROPDOWN_BASE, useExisting: IgxSelectComponent }
99
    ],
100
    styles: [`
101
        :host {
102
            display: block;
103
        }
104
    `],
105
    imports: [IgxInputGroupComponent, IgxInputDirective, IgxSelectItemNavigationDirective, IgxSuffixDirective, NgTemplateOutlet, IgxIconComponent, IgxToggleDirective]
106
})
107
export class IgxSelectComponent extends IgxDropDownComponent implements IgxSelectBase, ControlValueAccessor,
3✔
108
    AfterContentInit, OnInit, AfterViewInit, OnDestroy, EditorProvider, AfterContentChecked {
109

110
    /** @hidden @internal */
111
    @ViewChild('inputGroup', { read: IgxInputGroupComponent, static: true }) public inputGroup: IgxInputGroupComponent;
112

113
    /** @hidden @internal */
114
    @ViewChild('input', { read: IgxInputDirective, static: true }) public input: IgxInputDirective;
115

116
    /** @hidden @internal */
UNCOV
117
    @ContentChildren(forwardRef(() => IgxSelectItemComponent), { descendants: true })
×
118
    public override children: QueryList<IgxSelectItemComponent>;
119

120
    @ContentChildren(IgxPrefixDirective, { descendants: true })
121
    protected prefixes: QueryList<IgxPrefixDirective>;
122

123
    @ContentChildren(IgxSuffixDirective, { descendants: true })
124
    protected suffixes: QueryList<IgxSuffixDirective>;
125

126
    @ViewChildren(IgxSuffixDirective)
127
    protected internalSuffixes: QueryList<IgxSuffixDirective>;
128

129
    /** @hidden @internal */
UNCOV
130
    @ContentChild(forwardRef(() => IgxLabelDirective), { static: true }) public label: IgxLabelDirective;
×
131

132
    /**
133
     * Sets input placeholder.
134
     *
135
     */
136
    @Input() public placeholder;
137

138

139
    /**
140
     * Disables the component.
141
     * ```html
142
     * <igx-select [disabled]="'true'"></igx-select>
143
     * ```
144
     */
UNCOV
145
    @Input({ transform: booleanAttribute }) public disabled = false;
×
146

147
    /**
148
     * Sets custom OverlaySettings `IgxSelectComponent`.
149
     * ```html
150
     * <igx-select [overlaySettings] = "customOverlaySettings"></igx-select>
151
     * ```
152
     */
153
    @Input()
154
    public overlaySettings: OverlaySettings;
155

156
    /** @hidden @internal */
157
    @HostBinding('style.maxHeight')
UNCOV
158
    public override maxHeight = '256px';
×
159

160
    /**
161
     * Emitted before the dropdown is opened
162
     *
163
     * ```html
164
     * <igx-select opening='handleOpening($event)'></igx-select>
165
     * ```
166
     */
167
    @Output()
UNCOV
168
    public override opening = new EventEmitter<IBaseCancelableBrowserEventArgs>();
×
169

170
    /**
171
     * Emitted after the dropdown is opened
172
     *
173
     * ```html
174
     * <igx-select (opened)='handleOpened($event)'></igx-select>
175
     * ```
176
     */
177
    @Output()
UNCOV
178
    public override opened = new EventEmitter<IBaseEventArgs>();
×
179

180
    /**
181
     * Emitted before the dropdown is closed
182
     *
183
     * ```html
184
     * <igx-select (closing)='handleClosing($event)'></igx-select>
185
     * ```
186
     */
187
    @Output()
UNCOV
188
    public override closing = new EventEmitter<IBaseCancelableBrowserEventArgs>();
×
189

190
    /**
191
     * Emitted after the dropdown is closed
192
     *
193
     * ```html
194
     * <igx-select (closed)='handleClosed($event)'></igx-select>
195
     * ```
196
     */
197
    @Output()
UNCOV
198
    public override closed = new EventEmitter<IBaseEventArgs>();
×
199

200
    /**
201
     * The custom template, if any, that should be used when rendering the select TOGGLE(open/close) button
202
     *
203
     * ```typescript
204
     * // Set in typescript
205
     * const myCustomTemplate: TemplateRef<any> = myComponent.customTemplate;
206
     * myComponent.select.toggleIconTemplate = myCustomTemplate;
207
     * ```
208
     * ```html
209
     * <!-- Set in markup -->
210
     *  <igx-select #select>
211
     *      ...
212
     *      <ng-template igxSelectToggleIcon let-collapsed>
213
     *          <igx-icon>{{ collapsed ? 'remove_circle' : 'remove_circle_outline'}}</igx-icon>
214
     *      </ng-template>
215
     *  </igx-select>
216
     * ```
217
     */
218
    @ContentChild(IgxSelectToggleIconDirective, { read: TemplateRef })
UNCOV
219
    public toggleIconTemplate: TemplateRef<any> = null;
×
220

221
    /**
222
     * The custom template, if any, that should be used when rendering the HEADER for the select items list
223
     *
224
     * ```typescript
225
     * // Set in typescript
226
     * const myCustomTemplate: TemplateRef<any> = myComponent.customTemplate;
227
     * myComponent.select.headerTemplate = myCustomTemplate;
228
     * ```
229
     * ```html
230
     * <!-- Set in markup -->
231
     *  <igx-select #select>
232
     *      ...
233
     *      <ng-template igxSelectHeader>
234
     *          <div class="select__header">
235
     *              This is a custom header
236
     *          </div>
237
     *      </ng-template>
238
     *  </igx-select>
239
     * ```
240
     */
241
    @ContentChild(IgxSelectHeaderDirective, { read: TemplateRef, static: false })
UNCOV
242
    public headerTemplate: TemplateRef<any> = null;
×
243

244
    /**
245
     * The custom template, if any, that should be used when rendering the FOOTER for the select items list
246
     *
247
     * ```typescript
248
     * // Set in typescript
249
     * const myCustomTemplate: TemplateRef<any> = myComponent.customTemplate;
250
     * myComponent.select.footerTemplate = myCustomTemplate;
251
     * ```
252
     * ```html
253
     * <!-- Set in markup -->
254
     *  <igx-select #select>
255
     *      ...
256
     *      <ng-template igxSelectFooter>
257
     *          <div class="select__footer">
258
     *              This is a custom footer
259
     *          </div>
260
     *      </ng-template>
261
     *  </igx-select>
262
     * ```
263
     */
264
    @ContentChild(IgxSelectFooterDirective, { read: TemplateRef, static: false })
UNCOV
265
    public footerTemplate: TemplateRef<any> = null;
×
266

267
    @ContentChild(IgxHintDirective, { read: ElementRef }) private hintElement: ElementRef;
268

269
    /** @hidden @internal */
270
    public override width: string;
271

272
    /** @hidden @internal do not use the drop-down container class */
UNCOV
273
    public override cssClass = false;
×
274

275
    /** @hidden @internal */
UNCOV
276
    public override allowItemsFocus = false;
×
277

278
    /** @hidden @internal */
279
    public override height: string;
280

UNCOV
281
    private ngControl: NgControl = null;
×
282
    private _overlayDefaults: OverlaySettings;
283
    private _value: any;
UNCOV
284
    private _type = null;
×
285

286
    /**
287
     * Gets/Sets the component value.
288
     *
289
     * ```typescript
290
     * // get
291
     * let selectValue = this.select.value;
292
     * ```
293
     *
294
     * ```typescript
295
     * // set
296
     * this.select.value = 'London';
297
     * ```
298
     * ```html
299
     * <igx-select [value]="value"></igx-select>
300
     * ```
301
     */
302
    @Input()
303
    public get value(): any {
UNCOV
304
        return this._value;
×
305
    }
306
    public set value(v: any) {
UNCOV
307
        if (this._value === v) {
×
UNCOV
308
            return;
×
309
        }
UNCOV
310
        this._value = v;
×
UNCOV
311
        this.setSelection(this.items.find(x => x.value === this.value));
×
312
    }
313

314
    /**
315
     * Sets how the select will be styled.
316
     * The allowed values are `line`, `box` and `border`. The input-group default is `line`.
317
     * ```html
318
     * <igx-select [type]="'box'"></igx-select>
319
     * ```
320
     */
321
    @Input()
322
    public get type(): IgxInputGroupType {
UNCOV
323
        return this._type || this._inputGroupType || 'line';
×
324
    }
325

326
    public set type(val: IgxInputGroupType) {
UNCOV
327
        this._type = val;
×
328
    }
329

330
    /** @hidden @internal */
331
    public get selectionValue() {
UNCOV
332
        const selectedItem = this.selectedItem;
×
UNCOV
333
        return selectedItem ? selectedItem.itemText : '';
×
334
    }
335

336
    /** @hidden @internal */
337
    public override get selectedItem(): IgxSelectItemComponent {
UNCOV
338
        return this.selection.first_item(this.id);
×
339
    }
340

UNCOV
341
    private _onChangeCallback: (_: any) => void = noop;
×
UNCOV
342
    private _onTouchedCallback: () => void = noop;
×
343

344
    constructor(
345
        elementRef: ElementRef,
346
        cdr: ChangeDetectorRef,
347
        @Inject(DOCUMENT) document: any,
348
        selection: IgxSelectionAPIService,
UNCOV
349
        @Inject(IgxOverlayService) protected overlayService: IgxOverlayService,
×
UNCOV
350
        @Optional() @Inject(IGX_INPUT_GROUP_TYPE) private _inputGroupType: IgxInputGroupType,
×
UNCOV
351
        private _injector: Injector,
×
352
    ) {
UNCOV
353
        super(elementRef, cdr, document, selection);
×
354
    }
355

356
    //#region ControlValueAccessor
357

358
    /** @hidden @internal */
UNCOV
359
    public writeValue = (value: any) => {
×
UNCOV
360
        this.value = value;
×
361
    };
362

363
    /** @hidden @internal */
364
    public registerOnChange(fn: any): void {
UNCOV
365
        this._onChangeCallback = fn;
×
366
    }
367

368
    /** @hidden @internal */
369
    public registerOnTouched(fn: any): void {
UNCOV
370
        this._onTouchedCallback = fn;
×
371
    }
372

373
    /** @hidden @internal */
374
    public setDisabledState(isDisabled: boolean): void {
UNCOV
375
        this.disabled = isDisabled;
×
376
    }
377
    //#endregion
378

379
    /** @hidden @internal */
380
    public getEditElement(): HTMLInputElement {
UNCOV
381
        return this.input.nativeElement;
×
382
    }
383

384
    /** @hidden @internal */
385
    public override selectItem(newSelection: IgxDropDownItemBaseDirective, event?) {
UNCOV
386
        const oldSelection = this.selectedItem ?? <IgxDropDownItemBaseDirective>{};
×
387

UNCOV
388
        if (newSelection === null || newSelection.disabled || newSelection.isHeader) {
×
UNCOV
389
            return;
×
390
        }
391

UNCOV
392
        if (newSelection === oldSelection) {
×
UNCOV
393
            this.toggleDirective.close();
×
UNCOV
394
            return;
×
395
        }
396

UNCOV
397
        const args: ISelectionEventArgs = { oldSelection, newSelection, cancel: false, owner: this };
×
UNCOV
398
        this.selectionChanging.emit(args);
×
399

UNCOV
400
        if (args.cancel) {
×
UNCOV
401
            return;
×
402
        }
403

UNCOV
404
        this.setSelection(newSelection);
×
UNCOV
405
        this._value = newSelection.value;
×
406

UNCOV
407
        if (event) {
×
UNCOV
408
            this.toggleDirective.close();
×
409
        }
410

UNCOV
411
        this.cdr.detectChanges();
×
UNCOV
412
        this._onChangeCallback(this.value);
×
413
    }
414

415
    /** @hidden @internal */
416
    public getFirstItemElement(): HTMLElement {
UNCOV
417
        return this.children.first.element.nativeElement;
×
418
    }
419

420
    /**
421
     * Opens the select
422
     *
423
     * ```typescript
424
     * this.select.open();
425
     * ```
426
     */
427
    public override open(overlaySettings?: OverlaySettings) {
UNCOV
428
        if (this.disabled || this.items.length === 0) {
×
UNCOV
429
            return;
×
430
        }
UNCOV
431
        if (!this.selectedItem) {
×
UNCOV
432
            this.navigateFirst();
×
433
        }
434

UNCOV
435
        super.open(Object.assign({}, this._overlayDefaults, this.overlaySettings, overlaySettings));
×
436
    }
437

438
    public inputGroupClick(event: MouseEvent, overlaySettings?: OverlaySettings) {
UNCOV
439
        const targetElement = event.target as HTMLElement;
×
440

UNCOV
441
        if (this.hintElement && targetElement.contains(this.hintElement.nativeElement)) {
×
442
            return;
×
443
        }
UNCOV
444
        this.toggle(Object.assign({}, this._overlayDefaults, this.overlaySettings, overlaySettings));
×
445
    }
446

447
    /** @hidden @internal */
448
    public ngAfterContentInit() {
UNCOV
449
        this._overlayDefaults = {
×
450
            target: this.getEditElement(),
451
            modal: false,
452
            positionStrategy: new SelectPositioningStrategy(this),
453
            scrollStrategy: new AbsoluteScrollStrategy(),
454
            excludeFromOutsideClick: [this.inputGroup.element.nativeElement as HTMLElement]
455
        };
UNCOV
456
        const changes$ = this.children.changes.pipe(takeUntil(this.destroy$)).subscribe(() => {
×
UNCOV
457
            this.setSelection(this.items.find(x => x.value === this.value));
×
UNCOV
458
            this.cdr.detectChanges();
×
459
        });
UNCOV
460
        Promise.resolve().then(() => {
×
UNCOV
461
            if (!changes$.closed) {
×
UNCOV
462
                this.children.notifyOnChanges();
×
463
            }
464
        });
465
    }
466

467
    /**
468
     * Event handlers
469
     *
470
     * @hidden @internal
471
     */
472
    public handleOpening(e: ToggleViewCancelableEventArgs) {
UNCOV
473
        const args: IBaseCancelableBrowserEventArgs = { owner: this, event: e.event, cancel: e.cancel };
×
UNCOV
474
        this.opening.emit(args);
×
475

UNCOV
476
        e.cancel = args.cancel;
×
UNCOV
477
        if (args.cancel) {
×
478
            return;
×
479
        }
480
    }
481

482
    /** @hidden @internal */
483
    public override onToggleContentAppended(event: ToggleViewEventArgs) {
UNCOV
484
        const info = this.overlayService.getOverlayById(event.id);
×
UNCOV
485
        if (info?.settings?.positionStrategy instanceof SelectPositioningStrategy) {
×
486
            return;
×
487
        }
UNCOV
488
        super.onToggleContentAppended(event);
×
489
    }
490

491
    /** @hidden @internal */
492
    public handleOpened() {
UNCOV
493
        this.updateItemFocus();
×
UNCOV
494
        this.opened.emit({ owner: this });
×
495
    }
496

497
    /** @hidden @internal */
498
    public handleClosing(e: ToggleViewCancelableEventArgs) {
UNCOV
499
        const args: IBaseCancelableBrowserEventArgs = { owner: this, event: e.event, cancel: e.cancel };
×
UNCOV
500
        this.closing.emit(args);
×
UNCOV
501
        e.cancel = args.cancel;
×
502
    }
503

504
    /** @hidden @internal */
505
    public handleClosed() {
UNCOV
506
        this.focusItem(false);
×
UNCOV
507
        this.closed.emit({ owner: this });
×
508
    }
509

510
    /** @hidden @internal */
511
    public onBlur(): void {
UNCOV
512
        this._onTouchedCallback();
×
UNCOV
513
        if (this.ngControl && this.ngControl.invalid) {
×
UNCOV
514
            this.input.valid = IgxInputState.INVALID;
×
515
        } else {
UNCOV
516
            this.input.valid = IgxInputState.INITIAL;
×
517
        }
518
    }
519

520
    /** @hidden @internal */
521
    public onFocus(): void {
UNCOV
522
        this._onTouchedCallback();
×
523
    }
524

525
    /**
526
     * @hidden @internal
527
     */
528
    public override ngOnInit() {
UNCOV
529
        this.ngControl = this._injector.get<NgControl>(NgControl, null);
×
530
    }
531

532
    /**
533
     * @hidden @internal
534
     */
535
    public override ngAfterViewInit() {
UNCOV
536
        super.ngAfterViewInit();
×
537

UNCOV
538
        if (this.ngControl) {
×
UNCOV
539
            this.ngControl.statusChanges.pipe(takeUntil(this.destroy$)).subscribe(this.onStatusChanged.bind(this));
×
UNCOV
540
            this.manageRequiredAsterisk();
×
541
        }
542

UNCOV
543
        this.cdr.detectChanges();
×
544
    }
545

546
    /** @hidden @internal */
547
    public ngAfterContentChecked() {
UNCOV
548
        if (this.inputGroup && this.prefixes?.length > 0) {
×
UNCOV
549
            this.inputGroup.prefixes = this.prefixes;
×
550
        }
551

UNCOV
552
        if (this.inputGroup) {
×
UNCOV
553
            const suffixesArray = this.suffixes?.toArray() ?? [];
×
UNCOV
554
            const internalSuffixesArray = this.internalSuffixes?.toArray() ?? [];
×
UNCOV
555
            const mergedSuffixes = new QueryList<IgxSuffixDirective>();
×
UNCOV
556
            mergedSuffixes.reset([
×
557
                ...suffixesArray,
558
                ...internalSuffixesArray
559
            ]);
UNCOV
560
            this.inputGroup.suffixes = mergedSuffixes;
×
561
        }
562
    }
563

564
    /** @hidden @internal */
565
    public get toggleIcon(): string {
UNCOV
566
        return this.collapsed ? 'input_expand' : 'input_collapse';
×
567
    }
568

569
    /**
570
     * @hidden @internal
571
     * Prevent input blur - closing the items container on Header/Footer Template click.
572
     */
573
    public mousedownHandler(event) {
574
        event.preventDefault();
×
575
    }
576

577
    protected onStatusChanged() {
UNCOV
578
        this.manageRequiredAsterisk();
×
UNCOV
579
        if (this.ngControl && !this.disabled && this.isTouchedOrDirty) {
×
UNCOV
580
            if (this.hasValidators && this.inputGroup.isFocused) {
×
UNCOV
581
                this.input.valid = this.ngControl.valid ? IgxInputState.VALID : IgxInputState.INVALID;
×
582
            } else {
583
                // B.P. 18 May 2021: IgxDatePicker does not reset its state upon resetForm #9526
UNCOV
584
                this.input.valid = this.ngControl.valid ? IgxInputState.INITIAL : IgxInputState.INVALID;
×
585
            }
586
        } else {
UNCOV
587
            this.input.valid = IgxInputState.INITIAL;
×
588
        }
589
    }
590

591
    private get isTouchedOrDirty(): boolean {
UNCOV
592
        return (this.ngControl.control.touched || this.ngControl.control.dirty);
×
593
    }
594

595
    private get hasValidators(): boolean {
UNCOV
596
        return (!!this.ngControl.control.validator || !!this.ngControl.control.asyncValidator);
×
597
    }
598

599
    protected override navigate(direction: Navigate, currentIndex?: number) {
UNCOV
600
        if (this.collapsed && this.selectedItem) {
×
UNCOV
601
            this.navigateItem(this.selectedItem.itemIndex);
×
602
        }
UNCOV
603
        super.navigate(direction, currentIndex);
×
604
    }
605

606
    protected manageRequiredAsterisk(): void {
UNCOV
607
        const hasRequiredHTMLAttribute = this.elementRef.nativeElement.hasAttribute('required');
×
UNCOV
608
        let isRequired = false;
×
609

UNCOV
610
        if (this.ngControl && this.ngControl.control.validator) {
×
UNCOV
611
            const error = this.ngControl.control.validator({} as AbstractControl);
×
UNCOV
612
            isRequired = !!(error && error.required);
×
613
        }
614

UNCOV
615
        this.inputGroup.isRequired = isRequired;
×
616

UNCOV
617
        if (this.input?.nativeElement) {
×
UNCOV
618
            this.input.nativeElement.setAttribute('aria-required', isRequired.toString());
×
619
        }
620

621
        // Handle validator removal case
UNCOV
622
        if (!isRequired && !hasRequiredHTMLAttribute) {
×
UNCOV
623
            this.input.valid = IgxInputState.INITIAL;
×
624
        }
625

UNCOV
626
        this.cdr.markForCheck();
×
627
    }
628

629
    private setSelection(item: IgxDropDownItemBaseDirective) {
UNCOV
630
        if (item && item.value !== undefined && item.value !== null) {
×
UNCOV
631
            this.selection.set(this.id, new Set([item]));
×
632
        } else {
UNCOV
633
            this.selection.clear(this.id);
×
634
        }
635
    }
636
}
637

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