Skip to content

Commit 38b88ea

Browse files
PlamenaMitevaLipata
authored andcommitted
feat(dropdown): add clearSelction method #6218 (#6422)
1 parent f017a1d commit 38b88ea

File tree

6 files changed

+157
-11
lines changed

6 files changed

+157
-11
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ All notable changes for each version of this project will be documented in this
8383
- `IgxSelect`:
8484
- adding `IgxSelectHeaderDirective` and `IgxSelectFooterDirective`. These can be used to provide a custom header, respectively footer templates for the `igxSelect` drop-down list. If there are no templates marked with these directives - no default templates will be used so the drop-down list will not have header nor footer.
8585

86+
- `IgxDropDown`:
87+
- `clearSelection` method is added, which can be used to deselect the selected dropdown item
88+
8689
- `IgxCircularProgressBar`:
8790
- added `IgxProgressBarGradientDirective` to allow providing custom circular progress SVG gradients. Providing a custom gradient via a template is as easy as writing:
8891
```html

projects/igniteui-angular/src/lib/drop-down/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ The following methods are available in the **igx-drop-down** component:
149149
| `setSelectedItem(index: number)` | Selects dropdown item by index. |
150150
| `open()` | Opens the dropdown. |
151151
| `close()` | Closes the dropdown. |
152+
| `clearSelection()` | Deselects the selected dropdown item. |
152153

153154
## Getters
154155
The following getters are available on the **igx-drop-down** component:

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

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,39 @@ describe('IgxDropDown ', () => {
342342
expect(fixture.componentInstance.onSelection).toHaveBeenCalledTimes(1);
343343
}));
344344

345+
it('Should notify when selection is cleared', fakeAsync(() => {
346+
const fixture = TestBed.createComponent(IgxDropDownTestComponent);
347+
fixture.detectChanges();
348+
const button = fixture.debugElement.query(By.css('button')).nativeElement;
349+
const list = fixture.componentInstance.dropdown;
350+
const mockObj = jasmine.createSpyObj('mockEvt', ['stopPropagation', 'preventDefault']);
351+
spyOn(list.onSelection, 'emit').and.callThrough();
352+
spyOn(list.onClosed, 'emit').and.callThrough();
353+
spyOn(fixture.componentInstance, 'onSelection');
354+
355+
list.setSelectedItem(1);
356+
357+
button.click(mockObj);
358+
tick();
359+
fixture.detectChanges();
360+
expect(list.selectedItem).toEqual(list.items[1]);
361+
expect(list.onSelection.emit).toHaveBeenCalledTimes(1);
362+
expect(fixture.componentInstance.onSelection).toHaveBeenCalledTimes(1);
363+
364+
const selectionArgs: ISelectionEventArgs = {
365+
newSelection: null,
366+
oldSelection: list.items[1],
367+
cancel: false
368+
};
369+
list.clearSelection();
370+
tick();
371+
fixture.detectChanges();
372+
expect(list.selectedItem).toBeNull();
373+
expect(list.onSelection.emit).toHaveBeenCalledTimes(2);
374+
expect(fixture.componentInstance.onSelection).toHaveBeenCalledTimes(2);
375+
expect(list.onSelection.emit).toHaveBeenCalledWith(selectionArgs);
376+
}));
377+
345378
it('Should check if selection event return the proper eventArgs', fakeAsync(() => {
346379
const fixture = TestBed.createComponent(IgxDropDownTestComponent);
347380
fixture.detectChanges();
@@ -678,6 +711,45 @@ describe('IgxDropDown ', () => {
678711
expect(currentItem.componentInstance.itemIndex).toEqual(5);
679712
}));
680713

714+
it('Should deselect item when clearSelection is called', fakeAsync(() => {
715+
const fixture = TestBed.createComponent(IgxDropDownTestScrollComponent);
716+
fixture.detectChanges();
717+
const button = fixture.debugElement.query(By.css('button')).nativeElement;
718+
const list = fixture.componentInstance.dropdownScroll;
719+
const listItems = list.items;
720+
721+
list.setSelectedItem(0);
722+
button.click();
723+
tick();
724+
fixture.detectChanges();
725+
let selectedItem = fixture.debugElement.query(By.css('.' + CSS_CLASS_SELECTED));
726+
expect(selectedItem.componentInstance.itemIndex).toEqual(0);
727+
expect(listItems[0].selected).toBeTruthy();
728+
expect(selectedItem.classes[CSS_CLASS_SELECTED]).toBeTruthy();
729+
730+
list.clearSelection();
731+
tick();
732+
fixture.detectChanges();
733+
expect(listItems[0].selected).toBeFalsy();
734+
selectedItem = fixture.debugElement.query(By.css('.' + CSS_CLASS_SELECTED));
735+
expect(selectedItem).toBeNull();
736+
737+
list.setSelectedItem(5);
738+
tick();
739+
fixture.detectChanges();
740+
selectedItem = fixture.debugElement.query(By.css('.' + CSS_CLASS_SELECTED));
741+
expect(selectedItem.componentInstance.itemIndex).toEqual(5);
742+
expect(listItems[5].selected).toBeTruthy();
743+
expect(selectedItem.classes[CSS_CLASS_SELECTED]).toBeTruthy();
744+
745+
list.clearSelection();
746+
tick();
747+
fixture.detectChanges();
748+
expect(listItems[5].selected).toBeFalsy();
749+
selectedItem = fixture.debugElement.query(By.css('.' + CSS_CLASS_SELECTED));
750+
expect(selectedItem).toBeNull();
751+
}));
752+
681753
it('Home key should select the first enabled item', fakeAsync(() => {
682754
const fixture = TestBed.createComponent(IgxDropDownTestDisabledComponent);
683755
fixture.detectChanges();
@@ -1076,6 +1148,27 @@ describe('IgxDropDown ', () => {
10761148
expect(selectedItem).toBeNull();
10771149
}));
10781150

1151+
it('SelectedItem should return null when selection is cleared', fakeAsync(() => {
1152+
const fixture = TestBed.createComponent(IgxDropDownTestScrollComponent);
1153+
fixture.detectChanges();
1154+
const button = fixture.debugElement.query(By.css('button')).nativeElement;
1155+
const igxDropDown = fixture.componentInstance.dropdownScroll;
1156+
igxDropDown.setSelectedItem(3);
1157+
button.click();
1158+
tick();
1159+
1160+
fixture.detectChanges();
1161+
let selectedItem = igxDropDown.selectedItem;
1162+
expect(selectedItem).toBeTruthy();
1163+
expect(selectedItem.itemIndex).toEqual(3);
1164+
1165+
igxDropDown.clearSelection();
1166+
fixture.detectChanges();
1167+
selectedItem = igxDropDown.selectedItem;
1168+
expect(selectedItem).toBeNull();
1169+
}));
1170+
1171+
10791172
it('Should return empty array for items when there are no items', fakeAsync(() => {
10801173
const fixture = TestBed.createComponent(IgxDropDownTestEmptyListComponent);
10811174
fixture.detectChanges();

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,23 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID
561561
}
562562
}
563563

564+
/**
565+
* Clears the selection of the dropdown
566+
* ```typescript
567+
* this.dropdown.clearSelection();
568+
* ```
569+
*/
570+
public clearSelection() {
571+
const oldSelection = this.selectedItem;
572+
const newSelection: IgxDropDownItemBaseDirective = null;
573+
const args: ISelectionEventArgs = { oldSelection, newSelection, cancel: false };
574+
this.onSelection.emit(args);
575+
if (this.selectedItem && !args.cancel) {
576+
this.selectedItem.selected = false;
577+
this.selection.clear(this.id);
578+
}
579+
}
580+
564581
/**
565582
* Checks whether the selection is valid
566583
* `null` - the selection should be emptied

src/app/drop-down/drop-down.sample.html

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,27 +58,49 @@
5858
</igx-drop-down-item>
5959
</igx-drop-down-item-group>
6060
</igx-drop-down>
61-
6261
<div igxOverlayOutlet #outlet="overlay-outlet"></div>
6362
</section>
64-
<section>
65-
<button igxButton="raised" igxRipple [igxToggleAction]="dropDownComfortable" [igxDropDownItemNavigation]="dropDownComfortable" displayDensity="comfortable">Display: Comfortable</button>
66-
<igx-drop-down #dropDownComfortable (onSelection)="onSelection($event)" (onOpening)="onOpening($event)" height='400px' displayDensity="comfortable">
63+
<section class="sample-content">
64+
<button igxButton="raised" igxRipple [igxToggleAction]="dropDownComfortable"
65+
[igxDropDownItemNavigation]="dropDownComfortable" displayDensity="comfortable">Display: Comfortable</button>
66+
<igx-drop-down #dropDownComfortable (onSelection)="onSelection($event)" (onOpening)="onOpening($event)"
67+
height='400px' displayDensity="comfortable">
6768
<igx-drop-down-item *ngFor="let item of items" [disabled]="item.disabled" [isHeader]="item.header">
68-
{{ item.field }}
69+
{{ item.field }}
6970
</igx-drop-down-item>
7071
</igx-drop-down>
71-
<button igxButton="raised" igxRipple [igxToggleAction]="dropDownCosy" [igxDropDownItemNavigation]="dropDownCosy" displayDensity="cosy">Display: Cosy</button>
72-
<igx-drop-down #dropDownCosy (onSelection)="onSelection($event)" (onOpening)="onOpening($event)" height='400px' displayDensity="cosy">
72+
<button igxButton="raised" igxRipple [igxToggleAction]="dropDownCosy" [igxDropDownItemNavigation]="dropDownCosy"
73+
displayDensity="cosy">Display: Cosy</button>
74+
<igx-drop-down #dropDownCosy (onSelection)="onSelection($event)" (onOpening)="onOpening($event)" height='400px'
75+
displayDensity="cosy">
7376
<igx-drop-down-item *ngFor="let item of items" [disabled]="item.disabled" [isHeader]="item.header">
74-
{{ item.field }}
77+
{{ item.field }}
7578
</igx-drop-down-item>
7679
</igx-drop-down>
77-
<button igxButton="raised" igxRipple [igxToggleAction]="dropDownCompact" [igxDropDownItemNavigation]="dropDownCompact" displayDensity="compact">Display: Compact</button>
78-
<igx-drop-down #dropDownCompact (onSelection)="onSelection($event)" (onOpening)="onOpening($event)" height='400px' displayDensity="compact">
80+
<button igxButton="raised" igxRipple [igxToggleAction]="dropDownCompact"
81+
[igxDropDownItemNavigation]="dropDownCompact" displayDensity="compact">Display: Compact</button>
82+
<igx-drop-down #dropDownCompact (onSelection)="onSelection($event)" (onOpening)="onOpening($event)"
83+
height='400px' displayDensity="compact">
7984
<igx-drop-down-item *ngFor="let item of items" [disabled]="item.disabled" [isHeader]="item.header">
85+
{{ item.field }}
86+
</igx-drop-down-item>
87+
</igx-drop-down>
88+
</section>
89+
<section class="sample-content">
90+
<igx-input-group class="input-group">
91+
<input type="text" [igxToggleAction]="dropdown3" [igxDropDownItemNavigation]="dropdown3" igxInput
92+
readonly="true" [value]="dropdown3.selectedItem?.value.field" />
93+
</igx-input-group>
94+
<igx-drop-down #dropdown3 (onOpening)="onOpening($event)" (onSelection)="onSelectionLogger($event)" height='400px'>
95+
<igx-drop-down-item *ngFor="let item of items" [value]="item" [disabled]="item.disabled"
96+
[isHeader]="item.header">
97+
<div class="igx-drop-down__item-template">
8098
{{ item.field }}
99+
</div>
81100
</igx-drop-down-item>
82101
</igx-drop-down>
102+
<button igxButton="raised" igxRipple (click)="clearSelection()" style="display: block">
103+
Clear selection
104+
</button>
83105
</section>
84-
</div>
106+
</div>

src/app/drop-down/drop-down.sample.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { foods } from './foods';
1616
})
1717
export class DropDownSampleComponent implements OnInit {
1818
@ViewChild(IgxDropDownComponent, { static: true }) public igxDropDown: IgxDropDownComponent;
19+
@ViewChild('dropdown3', { static: true }) public igxDropDownSelection: IgxDropDownComponent;
1920
@ViewChild('button', { static: true }) public button: ElementRef;
2021

2122
@ViewChild(IgxOverlayOutletDirective, { static: true }) public igxOverlayOutlet: IgxOverlayOutletDirective;
@@ -147,13 +148,22 @@ export class DropDownSampleComponent implements OnInit {
147148
this.igxDropDown.close();
148149
}
149150

151+
public clearSelection() {
152+
this.igxDropDownSelection.clearSelection();
153+
}
154+
150155
onSelection(event) {
151156
console.log(event);
152157
const old = event.oldSelection;
153158
event.oldSelection = event.newSelection;
154159
event.newSelection = old;
155160
}
156161

162+
onSelectionLogger(event) {
163+
// event.cancel = true;
164+
console.log(event);
165+
}
166+
157167
onSelectionMenu(eventArgs) {
158168
eventArgs.cancel = true;
159169

0 commit comments

Comments
 (0)