Skip to content

Commit

Permalink
Merge pull request #5461 from IgniteUI/dpetev/ios-grid-edit-7-2
Browse files Browse the repository at this point in the history
fix(grids): handle double tap to allow editing on iOS #2538
  • Loading branch information
Lipata committed Aug 5, 2019
2 parents 0213744 + 2051d12 commit 2e62f6e
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 12 deletions.
10 changes: 5 additions & 5 deletions projects/igniteui-angular/src/lib/core/touch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ export class HammerGesturesManager {
inputClass: Hammer.TouchInput,
recognizers: [
[ Hammer.Pan, { threshold: 0 } ],
[ Hammer.Pinch, { enable: true } ],
[ Hammer.Rotate, { enable: true } ],
[ Hammer.Swipe, {
direction: Hammer.DIRECTION_HORIZONTAL
}]
}],
[Hammer.Tap],
[Hammer.Tap, { event: 'doubletap', taps: 2 }, ['tap']]
]
};

Expand All @@ -43,14 +43,14 @@ export class HammerGesturesManager {
public addEventListener(element: HTMLElement,
eventName: string,
eventHandler: (eventObj) => void,
options: object = null): () => void {
options: HammerOptions = null): () => void {

// Creating the manager bind events, must be done outside of angular
return this._zone.runOutsideAngular(() => {
let mc: HammerManager = this.getManagerForElement(element);
if (mc === null) {
// new Hammer is a shortcut for Manager with defaults
mc = new Hammer(element, this.hammerOptions);
mc = new Hammer(element, Object.assign(this.hammerOptions, options));
this.addManagerForElement(element, mc);
}
const handler = (eventObj) => { this._zone.run(() => { eventHandler(eventObj); }); };
Expand Down
17 changes: 14 additions & 3 deletions projects/igniteui-angular/src/lib/grids/cell.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { State } from '../services/index';
import { IgxGridBaseComponent, IGridEditEventArgs, IGridDataBindable } from './grid-base.component';
import { IgxGridSelectionService, ISelectionNode, IgxGridCRUDService } from '../core/grid-selection';
import { DeprecateProperty } from '../core/deprecateDecorators';
import { HammerGesturesManager } from '../core/touch';

/**
* Providing reference to `IgxGridCellComponent`:
Expand All @@ -40,7 +41,8 @@ import { DeprecateProperty } from '../core/deprecateDecorators';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'igx-grid-cell',
templateUrl: './cell.component.html'
templateUrl: './cell.component.html',
providers: [HammerGesturesManager]
})
export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy {

Expand Down Expand Up @@ -482,7 +484,8 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy {
public selection: IgxSelectionAPIService,
public cdr: ChangeDetectorRef,
private element: ElementRef,
protected zone: NgZone) { }
protected zone: NgZone,
private touchManager: HammerGesturesManager) { }


/**
Expand Down Expand Up @@ -510,6 +513,9 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy {
this.nativeElement.addEventListener('focusout', this.focusOut);
}
});
this.touchManager.addEventListener(this.nativeElement, 'doubletap', this.onDoubleClick, {
cssProps: { } /* don't disable user-select, etc */
} as HammerOptions);
}

/**
Expand All @@ -529,6 +535,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy {
this.nativeElement.removeEventListener('focusout', this.focusOut);
}
});
this.touchManager.destroy();
}

/**
Expand Down Expand Up @@ -674,7 +681,11 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy {
* @internal
*/
@HostListener('dblclick', ['$event'])
public onDoubleClick(event: MouseEvent) {
public onDoubleClick = (event: MouseEvent | HammerInput) => {
if (event.type === 'doubletap') {
// prevent double-tap to zoom on iOS
(event as HammerInput).preventDefault();
}
if (this.editable && !this.editMode && !this.row.deleted) {
this.crudService.begin(this);
}
Expand Down
34 changes: 34 additions & 0 deletions projects/igniteui-angular/src/lib/grids/grid/cell.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { UIInteractions, wait } from '../../test-utils/ui-interactions.spec';
import { configureTestSuite } from '../../test-utils/configure-suite';
import { IgxStringFilteringOperand, IgxNumberFilteringOperand } from '../../data-operations/filtering-condition';
import { SampleTestData } from '../../test-utils/sample-test-data.spec';
import { HammerGesturesManager } from '../../core/touch';

const DEBOUNCETIME = 30;

Expand Down Expand Up @@ -171,6 +172,7 @@ describe('IgxGrid - Cell component', () => {

spyOn(grid.onDoubleClick, 'emit').and.callThrough();
const event = new Event('dblclick');
spyOn(event, 'preventDefault');
cellElem.nativeElement.dispatchEvent(event);
const args: IGridCellEventArgs = {
cell: firstCell,
Expand All @@ -179,6 +181,38 @@ describe('IgxGrid - Cell component', () => {

fix.detectChanges();

expect(event.preventDefault).not.toHaveBeenCalled();
expect(grid.onDoubleClick.emit).toHaveBeenCalledWith(args);
expect(firstCell).toBe(fix.componentInstance.clickedCell);
});

it('Should handle doubletap, trigger onDoubleClick event', () => {
const addListenerSpy = spyOn(HammerGesturesManager.prototype, 'addEventListener');
const fix = TestBed.createComponent(DefaultGridComponent);
fix.detectChanges();

const grid = fix.componentInstance.instance;
const cellElem = fix.debugElement.query(By.css(CELL_CSS_CLASS));
const firstCell = grid.getCellByColumn(0, 'index');

// should attach 'doubletap'
expect(addListenerSpy.calls.count()).toBeGreaterThan(1);
expect(addListenerSpy).toHaveBeenCalledWith(firstCell.nativeElement, 'doubletap', firstCell.onDoubleClick, { cssProps: { } });

spyOn(grid.onDoubleClick, 'emit').and.callThrough();

const event = {
type: 'doubletap',
preventDefault: jasmine.createSpy('preventDefault')
};
firstCell.onDoubleClick(event as any);
const args: IGridCellEventArgs = {
cell: firstCell,
event
} as any;

fix.detectChanges();
expect(event.preventDefault).toHaveBeenCalled();
expect(grid.onDoubleClick.emit).toHaveBeenCalledWith(args);
expect(firstCell).toBe(fix.componentInstance.clickedCell);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import { ChangeDetectorRef, ElementRef, ChangeDetectionStrategy, Component,
import { IgxHierarchicalGridComponent } from './hierarchical-grid.component';
import { IgxHierarchicalSelectionAPIService } from './selection';
import { IgxGridSelectionService, IgxGridCRUDService } from '../../core/grid-selection';
import { HammerGesturesManager } from '../../core/touch';

@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
preserveWhitespaces: false,
selector: 'igx-hierarchical-grid-cell',
templateUrl: './../cell.component.html'
templateUrl: './../cell.component.html',
providers: [HammerGesturesManager]
})
export class IgxHierarchicalGridCellComponent extends IgxGridCellComponent implements OnInit {

Expand All @@ -25,8 +27,9 @@ export class IgxHierarchicalGridCellComponent extends IgxGridCellComponent imple
public cdr: ChangeDetectorRef,
private helement: ElementRef,
protected zone: NgZone,
touchManager: HammerGesturesManager
) {
super(selectionService, crudService, gridAPI, selection, cdr, helement, zone);
super(selectionService, crudService, gridAPI, selection, cdr, helement, zone, touchManager);
this.hSelection = <IgxHierarchicalSelectionAPIService>selection;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import { getNodeSizeViaRange } from '../../core/utils';
import { DOCUMENT } from '@angular/common';
import { IgxGridBaseComponent, IGridDataBindable } from '../grid';
import { IgxGridSelectionService, IgxGridCRUDService } from '../../core/grid-selection';
import { HammerGesturesManager } from '../../core/touch';

@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'igx-tree-grid-cell',
templateUrl: 'tree-cell.component.html'
templateUrl: 'tree-cell.component.html',
providers: [HammerGesturesManager]
})
export class IgxTreeGridCellComponent extends IgxGridCellComponent implements OnInit {
private treeGridAPI: IgxTreeGridAPIService;
Expand All @@ -24,8 +26,9 @@ export class IgxTreeGridCellComponent extends IgxGridCellComponent implements On
cdr: ChangeDetectorRef,
element: ElementRef,
protected zone: NgZone,
touchManager: HammerGesturesManager,
@Inject(DOCUMENT) public document) {
super(selectionService, crudService, gridAPI, selection, cdr, element, zone);
super(selectionService, crudService, gridAPI, selection, cdr, element, zone, touchManager);
this.treeGridAPI = <IgxTreeGridAPIService>gridAPI;
}

Expand Down

0 comments on commit 2e62f6e

Please sign in to comment.