Skip to content

Commit

Permalink
fix(combo, dropdown): emit owner in opening and closing events, #8326 (
Browse files Browse the repository at this point in the history
  • Loading branch information
ViktorSlavov authored Oct 13, 2020
1 parent 23be00c commit 71eb4d3
Show file tree
Hide file tree
Showing 12 changed files with 118 additions and 53 deletions.
4 changes: 2 additions & 2 deletions projects/igniteui-angular/src/lib/combo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -336,9 +336,9 @@ Setting `[displayDensity]` affects the control's items' and inputs' css properti
| `onSearchInput` | Emitted when an the search input's input event is triggered | true | { searchValue: `string` } |
| `onAddition` | Emitted when an item is being added to the data collection | false | { oldCollection: `any[]`, addedItem: `<any>`, newCollection: `any[]` }|
| `onDataPreLoad` | Emitted when new chunk of data is loaded from the virtualization | false | { event: `Event` } |
| `onOpening` | Emitted before the dropdown is opened | false | { event: `Event` } |
| `onOpening` | Emitted before the dropdown is opened | false | `IBaseCancelableBrowserEventArgs` |
| `onOpened` | Emitted after the dropdown is opened | false | { event: `Event` } |
| `onClosing` | Emitted before the dropdown is closed | false | { event: `Event` } |
| `onClosing` | Emitted before the dropdown is closed | false | `IBaseCancelableBrowserEventArgs` |
| `onClosed` | Emitted after the dropdown is closed | false | { event: `Event` } |

### Methods
Expand Down
69 changes: 60 additions & 9 deletions projects/igniteui-angular/src/lib/combo/combo.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { DisplayDensity } from '../core/density';
import { AbsoluteScrollStrategy, ConnectedPositioningStrategy } from '../services/public_api';
import { IgxSelectionAPIService } from '../core/selection';
import { IgxIconService } from '../icon/public_api';
import { IBaseCancelableBrowserEventArgs } from '../core/utils';

const CSS_CLASS_COMBO = 'igx-combo';
const CSS_CLASS_COMBO_DROPDOWN = 'igx-combo__drop-down';
Expand Down Expand Up @@ -282,6 +283,45 @@ describe('igxCombo', () => {
combo.selectItems([], true);
expect(combo.selectedItems()).toEqual([]);
});
it('should emit owner on `onOpening` and `onClosing`', () => {
combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService,
mockIconService, null, null, mockInjector);
spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null);
combo.ngOnInit();
spyOn(combo.onOpening, 'emit').and.callThrough();
spyOn(combo.onClosing, 'emit').and.callThrough();
const mockObj = {};
const inputEvent: IBaseCancelableBrowserEventArgs = {
cancel: false,
owner: mockObj,
};
combo.comboInput = <any>{
nativeElement: {
focus: () => {}
}
};
combo.handleOpening(inputEvent);
const expectedCall: IBaseCancelableBrowserEventArgs = Object.assign({}, inputEvent, { owner: combo });
expect(combo.onOpening.emit).toHaveBeenCalledWith(expectedCall);
expect(inputEvent.owner).toEqual(mockObj);
combo.handleClosing(inputEvent);
expect(combo.onClosing.emit).toHaveBeenCalledWith(expectedCall);
expect(inputEvent.owner).toEqual(mockObj);
let sub = combo.onOpening.subscribe((e: IBaseCancelableBrowserEventArgs) => {
e.cancel = true;
});
combo.handleOpening(inputEvent);
expect(inputEvent.cancel).toEqual(true);
sub.unsubscribe();
inputEvent.cancel = false;

sub = combo.onClosing.subscribe((e: IBaseCancelableBrowserEventArgs) => {
e.cancel = true;
});
combo.handleClosing(inputEvent);
expect(inputEvent.cancel).toEqual(true);
sub.unsubscribe();
});
it('should fire onSelectionChange event on item selection', () => {
const selectionService = new IgxSelectionAPIService();
combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService,
Expand All @@ -299,12 +339,13 @@ describe('igxCombo', () => {

combo.selectItems(newSelection);
expect(combo.onSelectionChange.emit).toHaveBeenCalledTimes(1);
expect(combo.onSelectionChange.emit).toHaveBeenCalledWith({
expect(combo.onSelectionChange.emit).toHaveBeenCalledWith(<IComboSelectionChangeEventArgs>{
oldSelection: oldSelection,
newSelection: newSelection,
added: newSelection,
removed: [],
event: undefined,
owner: combo,
displayText: `${newSelection.join(', ')}`,
cancel: false
});
Expand All @@ -314,12 +355,13 @@ describe('igxCombo', () => {
oldSelection = [...newSelection];
newSelection.push(newItem);
expect(combo.onSelectionChange.emit).toHaveBeenCalledTimes(2);
expect(combo.onSelectionChange.emit).toHaveBeenCalledWith({
expect(combo.onSelectionChange.emit).toHaveBeenCalledWith(<IComboSelectionChangeEventArgs>{
oldSelection: oldSelection,
newSelection: newSelection,
removed: [],
added: [combo.data[3]],
event: undefined,
owner: combo,
displayText: `${newSelection.join(', ')}`,
cancel: false
});
Expand All @@ -328,12 +370,13 @@ describe('igxCombo', () => {
newSelection = [combo.data[0]];
combo.selectItems(newSelection, true);
expect(combo.onSelectionChange.emit).toHaveBeenCalledTimes(3);
expect(combo.onSelectionChange.emit).toHaveBeenCalledWith({
expect(combo.onSelectionChange.emit).toHaveBeenCalledWith(<IComboSelectionChangeEventArgs>{
oldSelection: oldSelection,
newSelection: newSelection,
removed: oldSelection,
added: newSelection,
event: undefined,
owner: combo,
displayText: `${newSelection.join(', ')}`,
cancel: false
});
Expand All @@ -344,12 +387,13 @@ describe('igxCombo', () => {
combo.deselectItems([newItem]);
expect(combo.selectedItems().length).toEqual(0);
expect(combo.onSelectionChange.emit).toHaveBeenCalledTimes(4);
expect(combo.onSelectionChange.emit).toHaveBeenCalledWith({
expect(combo.onSelectionChange.emit).toHaveBeenCalledWith(<IComboSelectionChangeEventArgs>{
oldSelection: oldSelection,
newSelection: newSelection,
removed: [combo.data[0]],
added: [],
event: undefined,
owner: combo,
displayText: `${newSelection.join(', ')}`,
cancel: false
});
Expand All @@ -372,6 +416,7 @@ describe('igxCombo', () => {
added: [combo.data[0][combo.valueKey]],
removed: [],
event: undefined,
owner: combo,
displayText: `${combo.data[0][combo.displayKey]}`,
cancel: false
};
Expand Down Expand Up @@ -408,6 +453,7 @@ describe('igxCombo', () => {
added: newSelection.map(e => e[combo.valueKey]),
removed: [],
event: undefined,
owner: combo,
displayText: `${newSelection.map(entry => entry[combo.displayKey]).join(', ')}`,
cancel: false
};
Expand Down Expand Up @@ -472,11 +518,12 @@ describe('igxCombo', () => {
combo.selectAllItems(true);
expect(combo.selectedItems()).toEqual(data);
expect(combo.onSelectionChange.emit).toHaveBeenCalledTimes(1);
expect(combo.onSelectionChange.emit).toHaveBeenCalledWith({
expect(combo.onSelectionChange.emit).toHaveBeenCalledWith(<IComboSelectionChangeEventArgs>{
oldSelection: [],
newSelection: data,
added: data,
removed: [],
owner: combo,
event: undefined,
displayText: `${combo.data.join(', ')}`,
cancel: false
Expand All @@ -485,11 +532,12 @@ describe('igxCombo', () => {
combo.deselectAllItems(true);
expect(combo.selectedItems()).toEqual([]);
expect(combo.onSelectionChange.emit).toHaveBeenCalledTimes(2);
expect(combo.onSelectionChange.emit).toHaveBeenCalledWith({
expect(combo.onSelectionChange.emit).toHaveBeenCalledWith(<IComboSelectionChangeEventArgs>{
oldSelection: data,
newSelection: [],
added: [],
removed: data,
owner: combo,
event: undefined,
displayText: '',
cancel: false
Expand Down Expand Up @@ -1879,12 +1927,13 @@ describe('igxCombo', () => {
expect(selectedItem_1.element.nativeElement.classList.contains(CSS_CLASS_SELECTED)).toBeTruthy();
expect(combo.onSelectionChange.emit).toHaveBeenCalledTimes(1);
expect(combo.onSelectionChange.emit).toHaveBeenCalledWith(
{
<IComboSelectionChangeEventArgs>{
newSelection: [selectedItem_1.value[combo.valueKey]],
oldSelection: [],
added: [selectedItem_1.value[combo.valueKey]],
removed: [],
event: UIInteractions.getMouseEvent('click'),
owner: combo,
displayText: selectedItem_1.value[combo.valueKey],
cancel: false
});
Expand All @@ -1896,12 +1945,13 @@ describe('igxCombo', () => {
expect(selectedItem_2.element.nativeElement.classList.contains(CSS_CLASS_SELECTED)).toBeTruthy();
expect(combo.onSelectionChange.emit).toHaveBeenCalledTimes(2);
expect(combo.onSelectionChange.emit).toHaveBeenCalledWith(
{
<IComboSelectionChangeEventArgs>{
newSelection: [selectedItem_1.value[combo.valueKey], selectedItem_2.value[combo.valueKey]],
oldSelection: [selectedItem_1.value[combo.valueKey]],
added: [selectedItem_2.value[combo.valueKey]],
removed: [],
event: UIInteractions.getMouseEvent('click'),
owner: combo,
displayText: selectedItem_1.value[combo.valueKey] + ', ' + selectedItem_2.value[combo.valueKey],
cancel: false
});
Expand All @@ -1914,12 +1964,13 @@ describe('igxCombo', () => {
expect(unselectedItem.element.nativeElement.classList.contains(CSS_CLASS_SELECTED)).toBeFalsy();
expect(combo.onSelectionChange.emit).toHaveBeenCalledTimes(3);
expect(combo.onSelectionChange.emit).toHaveBeenCalledWith(
{
<IComboSelectionChangeEventArgs>{
newSelection: [selectedItem_2.value[combo.valueKey]],
oldSelection: [selectedItem_1.value[combo.valueKey], selectedItem_2.value[combo.valueKey]],
added: [],
removed: [unselectedItem.value[combo.valueKey]],
event: UIInteractions.getMouseEvent('click'),
owner: combo,
displayText: selectedItem_2.value[combo.valueKey],
cancel: false
});
Expand Down
35 changes: 19 additions & 16 deletions projects/igniteui-angular/src/lib/combo/combo.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
import { FormsModule, ReactiveFormsModule, ControlValueAccessor, NG_VALUE_ACCESSOR, NgControl, AbstractControl } from '@angular/forms';
import { IgxCheckboxModule } from '../checkbox/checkbox.component';
import { IgxSelectionAPIService } from '../core/selection';
import { cloneArray, CancelableEventArgs, CancelableBrowserEventArgs, IBaseEventArgs } from '../core/utils';
import { cloneArray, IBaseEventArgs, IBaseCancelableBrowserEventArgs, IBaseCancelableEventArgs } from '../core/utils';
import { IgxStringFilteringOperand, IgxBooleanFilteringOperand } from '../data-operations/filtering-condition';
import { FilteringLogic } from '../data-operations/filtering-expression.interface';
import { IgxForOfModule, IForOfState, IgxForOfDirective } from '../directives/for-of/for_of.directive';
Expand Down Expand Up @@ -89,7 +89,7 @@ export interface IComboFilteringOptions {
}

/** Event emitted when an igx-combo's selection is changing */
export interface IComboSelectionChangeEventArgs extends CancelableEventArgs, IBaseEventArgs {
export interface IComboSelectionChangeEventArgs extends IBaseCancelableEventArgs {
/** An array containing the values that are currently selected */
oldSelection: any[];
/** An array containing the values that will be selected after this event */
Expand All @@ -105,7 +105,7 @@ export interface IComboSelectionChangeEventArgs extends CancelableEventArgs, IBa
}

/** Event emitted when the igx-combo's search input changes */
export interface IComboSearchInputEventArgs extends CancelableEventArgs, IBaseEventArgs {
export interface IComboSearchInputEventArgs extends IBaseCancelableEventArgs {
/** The text that has been typed into the search input */
searchText: string;
}
Expand Down Expand Up @@ -453,7 +453,7 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
* ```
*/
@Output()
public onOpening = new EventEmitter<CancelableEventArgs & IBaseEventArgs>();
public onOpening = new EventEmitter<IBaseCancelableBrowserEventArgs>();

/**
* Emitted after the dropdown is opened
Expand All @@ -473,7 +473,7 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
* ```
*/
@Output()
public onClosing = new EventEmitter<CancelableBrowserEventArgs & IBaseEventArgs>();
public onClosing = new EventEmitter<IBaseCancelableBrowserEventArgs>();

/**
* Emitted after the dropdown is closed
Expand Down Expand Up @@ -513,7 +513,7 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
* ```
*/
@Output()
public onDataPreLoad = new EventEmitter<any>();
public onDataPreLoad = new EventEmitter<IForOfState>();

/**
* Gets/gets combo id.
Expand Down Expand Up @@ -1145,7 +1145,7 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
const newCollection = [...this.data];
newCollection.push(addedItem);
const args: IComboItemAdditionEvent = {
oldCollection, addedItem, newCollection
oldCollection, addedItem, newCollection, owner: this
};
this.onAddition.emit(args);
this.data.push(addedItem);
Expand Down Expand Up @@ -1238,8 +1238,9 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
this.manageRequiredAsterisk();
this.cdr.detectChanges();
}
this.virtDir.onChunkPreload.pipe(takeUntil(this.destroy$)).subscribe((e) => {
this.onDataPreLoad.emit(e);
this.virtDir.onChunkPreload.pipe(takeUntil(this.destroy$)).subscribe((e: IForOfState) => {
const eventArgs: IForOfState = Object.assign({}, e, { owner: this });
this.onDataPreLoad.emit(eventArgs);
});
}

Expand Down Expand Up @@ -1489,6 +1490,7 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
added,
removed,
event,
owner: this,
displayText,
cancel: false
};
Expand Down Expand Up @@ -1549,11 +1551,10 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
* @hidden
* @internal
*/
public handleOpening(event: CancelableEventArgs) {
this.onOpening.emit(event);
if (event.cancel) {
return;
}
public handleOpening(event: IBaseCancelableBrowserEventArgs) {
const eventArgs: IBaseCancelableBrowserEventArgs = Object.assign({}, event, { owner: this });
this.onOpening.emit(eventArgs);
event.cancel = eventArgs.cancel;
}

/**
Expand All @@ -1576,8 +1577,10 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
/**
* @hidden @internal
*/
public handleClosing(event) {
this.onClosing.emit(event);
public handleClosing(event: IBaseCancelableBrowserEventArgs) {
const eventArgs: IBaseCancelableBrowserEventArgs = Object.assign({}, event, { owner: this });
this.onClosing.emit(eventArgs);
event.cancel = eventArgs.cancel;
if (event.cancel) {
return;
}
Expand Down
4 changes: 4 additions & 0 deletions projects/igniteui-angular/src/lib/core/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,10 @@ export interface CancelableBrowserEventArgs extends CancelableEventArgs {
event?: Event;
}

export interface IBaseCancelableBrowserEventArgs extends CancelableBrowserEventArgs, IBaseEventArgs {}

export interface IBaseCancelableEventArgs extends CancelableEventArgs, IBaseEventArgs {}

export const HORIZONTAL_NAV_KEYS = new Set(['arrowleft', 'left', 'arrowright', 'right', 'home', 'end']);

export const NAVIGATION_KEYS = new Set([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ import {
} from './date-picker.utils';
import { DatePickerDisplayValuePipe, DatePickerInputValuePipe } from './date-picker.pipes';
import { IDatePicker } from './date-picker.common';
import { KEYS, CancelableBrowserEventArgs, isIE, isEqual, IBaseEventArgs, mkenum } from '../core/utils';
import { KEYS, isIE, isEqual, IBaseEventArgs, mkenum, IBaseCancelableBrowserEventArgs } from '../core/utils';
import { IgxDatePickerTemplateDirective, IgxDatePickerActionsDirective } from './date-picker.directives';
import { IgxCalendarContainerComponent } from './calendar-container.component';
import { InteractionMode } from '../core/enums';
Expand Down Expand Up @@ -605,7 +605,7 @@ export class IgxDatePickerComponent implements IDatePicker, ControlValueAccessor
* Emitted when the `IgxDatePickerComponent` is being closed.
*/
@Output()
public onClosing = new EventEmitter<CancelableBrowserEventArgs & IBaseEventArgs>();
public onClosing = new EventEmitter<IBaseCancelableBrowserEventArgs>();

/**
* Emitted when selection is made in the calendar.
Expand Down
4 changes: 2 additions & 2 deletions projects/igniteui-angular/src/lib/date-range-picker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,9 @@ With projected inputs:
| Name | Type | Description |
|:-----------------|:----------------------|:------------|
| rangeSelected | IgxDateRangePickerComponent | Emitted when a full range was selected in the `IgxDateRangePickerComponent`. |
| onOpening | CancelableBrowserEventArgs & IBaseEventArgs | Emitted when the calendar starts opening, cancelable. |
| onOpening | IBaseCancelableBrowserEventArgs | Emitted when the calendar starts opening, cancelable. |
| onOpened | IBaseEventArgs | Emitted when the `IgxDateRangePickerComponent` is opened. |
| onClosing | CancelableBrowserEventArgs & IBaseEventArgs | Emitted when the calendar starts closing, cancelable. |
| onClosing | IBaseCancelableBrowserEventArgs | Emitted when the calendar starts closing, cancelable. |
| onClosed | IBaseEventArgs | Emitted when the `IgxDateRangePickerComponent` is closed. |

### Methods
Expand Down
Loading

0 comments on commit 71eb4d3

Please sign in to comment.