Skip to content

Commit 02afce5

Browse files
authored
Merge branch 'master' into AMarinov/issue5587_master
2 parents ed0b0b8 + 133eb69 commit 02afce5

File tree

5 files changed

+140
-32
lines changed

5 files changed

+140
-32
lines changed

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,22 @@
22

33
All notable changes for each version of this project will be documented in this file.
44

5+
## 8.1.3
6+
- `IgxCombo`
7+
- Combo `onSelectionChange` events now emits the item(s) that were added to or removed from the collection:
8+
```html
9+
<igx-combo (onSelectionChange)="handleChange($event)">
10+
```
11+
```typescript
12+
export class Example {
13+
...
14+
handleChange(event: IComboSelectionChangeEventArgs) {
15+
console.log("Items added: ", [...event.added]); // the items added to the selection in this change
16+
console.log("Items removed: ", [...event.removed]); // the items removed from the selection in this change
17+
}
18+
}
19+
```
20+
521
## 8.1.2
622

723
### New Features

projects/igniteui-angular/src/lib/combo/README.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -276,14 +276,14 @@ Setting `[displayDensity]` affects the control's items' and inputs' css properti
276276

277277
| Name | Description | Cancelable | Parameters |
278278
|------------------ |-------------------------------------------------------------------------|------------- |-----------------------------------------|
279-
| `onSelectionChange` | Emitted when item selection is changing, before the selection completes | true | { oldSelection: `Array<any>`, newSelection: `Array<any>`, event: Event } |
279+
| `onSelectionChange` | Emitted when item selection is changing, before the selection completes | true | [`IComboSelectionChangeEventArgs`](https://www.infragistics.com/products/ignite-ui-angular/docs/typescript/latest/interfaces/icomboselectionchangeeventargs.html) |
280280
| `onSearchInput` | Emitted when an the search input's input event is triggered | false | { searchValue: `string` } |
281-
| `onAddition` | Emitted when an item is being added to the data collection | false | { oldCollection: `Array<any>`, addedItem: `<any>`, newCollection: `Array<any>` }|
282-
| `onDataPreLoad` | Emitted when new chunk of data is loaded from the virtualization | false | { event: Event } |
283-
| `onOpening` | Emitted before the dropdown is opened | false | { event: Event } |
284-
| `onOpened` | Emitted after the dropdown is opened | false | { event: Event } |
285-
| `onClosing` | Emitted before the dropdown is closed | false | { event: Event } |
286-
| `onClosed` | Emitted after the dropdown is closed | false | { event: Event } |
281+
| `onAddition` | Emitted when an item is being added to the data collection | false | { oldCollection: `any[]`, addedItem: `<any>`, newCollection: `any[]` }|
282+
| `onDataPreLoad` | Emitted when new chunk of data is loaded from the virtualization | false | { event: `Event` } |
283+
| `onOpening` | Emitted before the dropdown is opened | false | { event: `Event` } |
284+
| `onOpened` | Emitted after the dropdown is opened | false | { event: `Event` } |
285+
| `onClosing` | Emitted before the dropdown is closed | false | { event: `Event` } |
286+
| `onClosed` | Emitted after the dropdown is closed | false | { event: `Event` } |
287287

288288
### Methods
289289

@@ -292,9 +292,9 @@ Setting `[displayDensity]` affects the control's items' and inputs' css properti
292292
| `open` | Opens drop down | `void` | `None` |
293293
| `close` | Closes drop down | `void` | `None` |
294294
| `toggle` | Toggles drop down | `void` | `None` |
295-
| `selectedItems` | Get current selection state | `Array<any>` | `None` |
296-
| `selectItems` | Select defined items | `void` | items: `Array<any>`, clearCurrentSelection: `boolean` |
297-
| `deselectItems` | Deselect defined items | `void` | items: `Array<any>` |
295+
| `selectedItems` | Get current selection state | `any[]` | `None` |
296+
| `selectItems` | Select defined items | `void` | items: `any[]`, clearCurrentSelection: `boolean` |
297+
| `deselectItems` | Deselect defined items | `void` | items: `any[]` |
298298
| `selectAllItems` | Select all (filtered) items | `void` | ignoreFilter?: `boolean` - if `true` selects **all** values |
299299
| `deselectAllItems` | Deselect (filtered) all items | `void` | ignoreFilter?: `boolean` - if `true` deselects **all** values |
300300
| `setSelectedItem` | Toggles (select/deselect) an item by key | `void` | itemID: any, select = true, event?: Event |

projects/igniteui-angular/src/lib/combo/combo.component.spec.ts

Lines changed: 81 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,8 @@ describe('igxCombo', () => {
10151015
expect(combo.onSelectionChange.emit).toHaveBeenCalledWith({
10161016
oldSelection: [],
10171017
newSelection: [targetItem.itemID],
1018+
added: [targetItem.itemID],
1019+
removed: [],
10181020
event: undefined,
10191021
cancel: false
10201022
});
@@ -1027,6 +1029,8 @@ describe('igxCombo', () => {
10271029
expect(combo.onSelectionChange.emit).toHaveBeenCalledWith({
10281030
oldSelection: [targetItem.itemID],
10291031
newSelection: [],
1032+
added: [],
1033+
removed: [targetItem.itemID],
10301034
event: undefined,
10311035
cancel: false
10321036
});
@@ -1049,6 +1053,8 @@ describe('igxCombo', () => {
10491053
expect(combo.onSelectionChange.emit).toHaveBeenCalledWith({
10501054
oldSelection: oldSelection,
10511055
newSelection: newSelection,
1056+
added: [combo.data[1], combo.data[5], combo.data[6]],
1057+
removed: [],
10521058
event: undefined,
10531059
cancel: false
10541060
});
@@ -1063,6 +1069,8 @@ describe('igxCombo', () => {
10631069
expect(combo.onSelectionChange.emit).toHaveBeenCalledWith({
10641070
oldSelection: oldSelection,
10651071
newSelection: newSelection,
1072+
removed: [],
1073+
added: [combo.data[3]],
10661074
event: undefined,
10671075
cancel: false
10681076
});
@@ -1076,6 +1084,8 @@ describe('igxCombo', () => {
10761084
expect(combo.onSelectionChange.emit).toHaveBeenCalledWith({
10771085
oldSelection: oldSelection,
10781086
newSelection: newSelection,
1087+
removed: oldSelection,
1088+
added: [combo.data[0]],
10791089
event: undefined,
10801090
cancel: false
10811091
});
@@ -1091,6 +1101,8 @@ describe('igxCombo', () => {
10911101
expect(combo.onSelectionChange.emit).toHaveBeenCalledWith({
10921102
oldSelection: oldSelection,
10931103
newSelection: newSelection,
1104+
removed: [combo.data[0]],
1105+
added: [],
10941106
event: undefined,
10951107
cancel: false
10961108
});
@@ -1410,6 +1422,8 @@ describe('igxCombo', () => {
14101422
const eventParams = {
14111423
oldSelection: [],
14121424
newSelection: [],
1425+
added: [],
1426+
removed: [],
14131427
event: mockEvent,
14141428
cancel: false
14151429
};
@@ -1427,29 +1441,23 @@ describe('igxCombo', () => {
14271441
expect(combo.onSelectionChange.emit).toHaveBeenCalledWith(eventParams);
14281442
};
14291443

1430-
eventParams.newSelection.push(dropdown.items[3].value);
1444+
eventParams.newSelection = [dropdown.items[3].value];
1445+
eventParams.added = [dropdown.items[3].value];
14311446
verifyOnSelectionChangeEventIsFired(3);
14321447
timesFired++;
14331448

1434-
eventParams.oldSelection.push(dropdown.items[3].value);
1435-
eventParams.newSelection.push(dropdown.items[7].value);
1449+
eventParams.oldSelection = [dropdown.items[3].value];
1450+
eventParams.newSelection = [dropdown.items[3].value, dropdown.items[7].value];
1451+
eventParams.added = [dropdown.items[7].value];
14361452
verifyOnSelectionChangeEventIsFired(7);
14371453
timesFired++;
14381454

1439-
eventParams.oldSelection.push(dropdown.items[7].value);
1440-
eventParams.newSelection.push(dropdown.items[1].value);
1441-
verifyOnSelectionChangeEventIsFired(1);
1442-
timesFired++;
1443-
14441455
// Deselecting an item
1445-
eventParams.oldSelection.push(dropdown.items[1].value);
1446-
eventParams.newSelection = eventParams.newSelection.filter(item => item !== dropdown.items[7].value);
1456+
eventParams.oldSelection = [dropdown.items[3].value, dropdown.items[7].value];
1457+
eventParams.newSelection = [dropdown.items[3].value];
1458+
eventParams.added = [];
1459+
eventParams.removed = [dropdown.items[7].value];
14471460
verifyOnSelectionChangeEventIsFired(7);
1448-
timesFired++;
1449-
1450-
eventParams.oldSelection = eventParams.oldSelection.filter(item => item !== dropdown.items[7].value);
1451-
eventParams.newSelection = eventParams.newSelection.filter(item => item !== dropdown.items[1].value);
1452-
verifyOnSelectionChangeEventIsFired(1);
14531461
}));
14541462
it('Should be able to select item when in grouped state', fakeAsync(() => {
14551463
const fixture = TestBed.createComponent(IgxComboSampleComponent);
@@ -1576,6 +1584,64 @@ describe('igxCombo', () => {
15761584
// onSelectionChange fires and overrides the selection to be [];
15771585
expect(combo.selectedItems()).toEqual([]);
15781586
}));
1587+
1588+
it('Should properly emit added and removed values in change event - single values', () => {
1589+
const fixture = TestBed.createComponent(IgxComboSampleComponent);
1590+
fixture.detectChanges();
1591+
const combo = fixture.componentInstance.combo;
1592+
const selectionSpy = spyOn(fixture.componentInstance, 'onSelectionChange');
1593+
const expectedResults = {
1594+
newSelection: [combo.data[0]],
1595+
oldSelection: [],
1596+
added: [combo.data[0]],
1597+
removed: [],
1598+
event: undefined,
1599+
cancel: false
1600+
};
1601+
combo.selectItems([combo.data[0]]);
1602+
expect(selectionSpy).toHaveBeenCalledWith(expectedResults);
1603+
Object.assign(expectedResults, {
1604+
newSelection: [],
1605+
oldSelection: [combo.data[0]],
1606+
added: [],
1607+
removed: [combo.data[0]]
1608+
});
1609+
combo.deselectItems([combo.data[0]]);
1610+
expect(selectionSpy).toHaveBeenCalledWith(expectedResults);
1611+
});
1612+
1613+
it('Should properly emit added and removed values in change event - multiple values', () => {
1614+
const fixture = TestBed.createComponent(IgxComboSampleComponent);
1615+
fixture.detectChanges();
1616+
const combo = fixture.componentInstance.combo;
1617+
const selectionSpy = spyOn(fixture.componentInstance, 'onSelectionChange');
1618+
const expectedResults = {
1619+
newSelection: [combo.data[0], combo.data[1], combo.data[2]],
1620+
oldSelection: [],
1621+
added: [combo.data[0], combo.data[1], combo.data[2]],
1622+
removed: [],
1623+
event: undefined,
1624+
cancel: false
1625+
};
1626+
combo.selectItems([combo.data[0], combo.data[1], combo.data[2]]);
1627+
expect(selectionSpy).toHaveBeenCalledWith(expectedResults);
1628+
combo.deselectItems([combo.data[0]]);
1629+
Object.assign(expectedResults, {
1630+
newSelection: [combo.data[1], combo.data[2]],
1631+
oldSelection: [combo.data[0], combo.data[1], combo.data[2]],
1632+
added: [],
1633+
removed: [combo.data[0]]
1634+
});
1635+
expect(selectionSpy).toHaveBeenCalledWith(expectedResults);
1636+
Object.assign(expectedResults, {
1637+
newSelection: [combo.data[4], combo.data[5], combo.data[6]],
1638+
oldSelection: [combo.data[1], combo.data[2]],
1639+
added: [combo.data[4], combo.data[5], combo.data[6]],
1640+
removed: [combo.data[1], combo.data[2]]
1641+
});
1642+
combo.selectItems([combo.data[4], combo.data[5], combo.data[6]], true);
1643+
expect(selectionSpy).toHaveBeenCalledWith(expectedResults);
1644+
});
15791645
});
15801646

15811647
describe('Rendering tests: ', () => {

projects/igniteui-angular/src/lib/combo/combo.component.ts

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,17 @@ export enum IgxComboState {
8383
INVALID
8484
}
8585

86+
/** Event emitted when an igx-combo's selection is changing */
8687
export interface IComboSelectionChangeEventArgs extends CancelableEventArgs {
88+
/** An array containing the values that are currently selected */
8789
oldSelection: any[];
90+
/** An array containing the values that will be selected after this event */
8891
newSelection: any[];
92+
/** An array containing the values that will be added to the selection (if any) */
93+
added: any[];
94+
/** An array containing the values that will be removed from the selection (if any) */
95+
removed: any[];
96+
/** The user interaction that triggered the selection change */
8997
event?: Event;
9098
}
9199

@@ -95,6 +103,20 @@ export interface IComboItemAdditionEvent {
95103
newCollection: any[];
96104
}
97105

106+
/**
107+
* When called with sets A & B, returns A - B (as array);
108+
* @hidden
109+
*/
110+
function diffInSets(set1: Set<any>, set2: Set<any>): any[] {
111+
const results = [];
112+
set1.forEach(entry => {
113+
if (!set2.has(entry)) {
114+
results.push(entry);
115+
}
116+
});
117+
return results;
118+
}
119+
98120
let NEXT_ID = 0;
99121
const noop = () => { };
100122

@@ -327,7 +349,7 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
327349
* <igx-combo #combo>
328350
* ...
329351
* <ng-template igxComboEmpty>
330-
* <div class="combo--emtpy">
352+
* <div class="combo--empty">
331353
* There are no items to display
332354
* </div>
333355
* </ng-template>
@@ -703,7 +725,7 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
703725
}
704726

705727
/**
706-
* Combo value data source propery.
728+
* Combo value data source property.
707729
*
708730
* ```typescript
709731
* // get
@@ -724,7 +746,7 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
724746
}
725747

726748
/**
727-
* Combo text data source propery.
749+
* Combo text data source property.
728750
*
729751
* ```typescript
730752
* // get
@@ -737,7 +759,7 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
737759
*
738760
* ```html
739761
* <!--set-->
740-
* <igx-combo [displayKey]='mydisplayKey'></igx-combo>
762+
* <igx-combo [displayKey]='myDisplayKey'></igx-combo>
741763
* ```
742764
*/
743765
get displayKey() {
@@ -1472,7 +1494,7 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
14721494
/**
14731495
* Selects/Deselects an item using it's valueKey value
14741496
* @param itemID the valueKey of the specified item
1475-
* @param select If the item should be selected (true) or deselcted (false)
1497+
* @param select If the item should be selected (true) or deselected (false)
14761498
*
14771499
* ```typescript
14781500
* items: { field: string, region: string}[] = data;
@@ -1496,11 +1518,15 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
14961518
}
14971519

14981520
protected setSelection(newSelection: Set<any>, event?: Event): void {
1521+
const removed = diffInSets(this.selection.get(this.id), newSelection);
1522+
const added = diffInSets(newSelection, this.selection.get(this.id));
14991523
const oldSelectionEmit = Array.from(this.selection.get(this.id) || []);
15001524
const newSelectionEmit = Array.from(newSelection || []);
15011525
const args: IComboSelectionChangeEventArgs = {
15021526
newSelection: newSelectionEmit,
15031527
oldSelection: oldSelectionEmit,
1528+
added,
1529+
removed,
15041530
event,
15051531
cancel: false
15061532
};

projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
<span *ngIf="hasMovableColumns && draggedColumn && pinnedColumns.length > 0"
1212
[igxColumnMovingDrop]="parentVirtDir" [attr.droppable]="true" id="left"
1313
class="igx-grid__scroll-on-drag-pinned" [style.left.px]="pinnedWidth"></span>
14-
<div class="igx-grid__hierarchical-expander igx-grid__hierarchical-expander--header"
15-
#headerHierarchyExpander [hidden]='!hasExpandableChildren || !hasVisibleColumns' [ngClass]="{
14+
<div #headerHierarchyExpander [hidden]='!hasExpandableChildren || !hasVisibleColumns' [ngClass]="{
15+
'igx-grid__hierarchical-expander igx-grid__hierarchical-expander--header': hasExpandableChildren,
1616
'igx-grid__hierarchical-expander--push': filteringService.isFilterRowVisible,
1717
'igx-grid__hierarchical-expander--no-border': rowSelectable || rowDraggable
1818
}">

0 commit comments

Comments
 (0)