Skip to content

Commit bc6ebc7

Browse files
ViktorSlavovLipata
authored andcommitted
fix(drop-down): properly overwrite selection w/ onSelection args, #6208 (#6255)
1 parent e91e1f5 commit bc6ebc7

File tree

2 files changed

+72
-11
lines changed

2 files changed

+72
-11
lines changed

projects/igniteui-angular/src/lib/drop-down/drop-down.component.spec.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,51 @@ describe('IgxDropDown ', () => {
420420
expect(list.onSelection.emit).toHaveBeenCalledWith(selectionArgs1);
421421
}));
422422

423+
it('Should be able to change selection when manipulating ISelectionEventArgs', fakeAsync(() => {
424+
const fixture = TestBed.createComponent(IgxDropDownTestScrollComponent);
425+
fixture.detectChanges();
426+
const dropdown = fixture.componentInstance.dropdownScroll;
427+
expect(dropdown.selectedItem).toEqual(null);
428+
dropdown.toggle();
429+
tick();
430+
fixture.detectChanges();
431+
tick();
432+
433+
// Overwrite selection args
434+
let expectedSelected = dropdown.items[4];
435+
const calledSelected = dropdown.items[1];
436+
const subscription = dropdown.onSelection.subscribe((e: ISelectionEventArgs) => {
437+
expect(e.newSelection).toEqual(calledSelected);
438+
e.newSelection = expectedSelected;
439+
});
440+
dropdown.selectItem(calledSelected);
441+
tick();
442+
expect(dropdown.selectedItem).toEqual(expectedSelected);
443+
444+
// Clear selection
445+
expectedSelected = null;
446+
dropdown.selectItem(calledSelected);
447+
tick();
448+
expect(dropdown.selectedItem).toEqual(expectedSelected);
449+
450+
// Set header - error
451+
dropdown.toggle();
452+
tick();
453+
fixture.detectChanges();
454+
455+
expectedSelected = dropdown.items[4];
456+
dropdown.items[4].isHeader = true;
457+
458+
spyOn(dropdown, 'selectItem').and.callThrough();
459+
expect(() => { dropdown.selectItem(calledSelected); }).toThrow();
460+
461+
// Set non-IgxDropDownItemBaseDirective
462+
expectedSelected = 7 as any;
463+
expect(() => { dropdown.selectItem(calledSelected); }).toThrow();
464+
465+
subscription.unsubscribe();
466+
}));
467+
423468
it('Should persist selection through scrolling', fakeAsync(() => {
424469
const fixture = TestBed.createComponent(IgxDropDownTestScrollComponent);
425470
fixture.detectChanges();

projects/igniteui-angular/src/lib/drop-down/drop-down.component.ts

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,8 @@ export class IgxDropDownComponent extends IgxDropDownBase implements IDropDownBa
136136
public get focusedItem(): IgxDropDownItemBase {
137137
if (this.virtDir) {
138138
return this._focusedItem && this._focusedItem.index !== -1 ?
139-
(this.children.find(e => e.index === this._focusedItem.index) || null) :
140-
null;
139+
(this.children.find(e => e.index === this._focusedItem.index) || null) :
140+
null;
141141
}
142142
return this._focusedItem;
143143
}
@@ -538,19 +538,35 @@ export class IgxDropDownComponent extends IgxDropDownBase implements IDropDownBa
538538
this.onSelection.emit(args);
539539

540540
if (!args.cancel) {
541-
this.selection.set(this.id, new Set([newSelection]));
542-
if (!this.virtDir) {
543-
if (oldSelection) {
544-
oldSelection.selected = false;
541+
if (this.isSelectionValid(args.newSelection)) {
542+
this.selection.set(this.id, new Set([args.newSelection]));
543+
if (!this.virtDir) {
544+
if (oldSelection) {
545+
oldSelection.selected = false;
546+
}
547+
if (args.newSelection) {
548+
args.newSelection.selected = true;
549+
}
545550
}
546-
if (newSelection) {
547-
newSelection.selected = true;
551+
if (event) {
552+
this.toggleDirective.close();
548553
}
549-
}
550-
if (event) {
551-
this.toggleDirective.close();
554+
} else {
555+
throw new Error('Please provide a valid drop-down item for the selection!');
552556
}
553557
}
554558
}
559+
560+
/**
561+
* Checks whether the selection is valid
562+
* `null` - the selection should be emptied
563+
* Virtual? - the selection should at least have and `index` and `value` property
564+
* Non-virtual? - the selection should be a valid drop-down item and **not** be a header
565+
*/
566+
protected isSelectionValid(selection: any): boolean {
567+
return selection === null
568+
|| (this.virtDir && selection.hasOwnProperty('value') && selection.hasOwnProperty('index'))
569+
|| (selection instanceof IgxDropDownItemComponent && !selection.isHeader);
570+
}
555571
}
556572

0 commit comments

Comments
 (0)