Skip to content
Permalink
Browse files

Merge pull request #5462 from IgniteUI/dpetev/ios-grid-edit-7-3

fix(grids): handle double tap to allow editing on iOS #2538
  • Loading branch information...
Lipata committed Aug 5, 2019
2 parents 0809cbc + e2f83d5 commit 83eabfa032371f2441affa5d53f395de041ee120
@@ -20,11 +20,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']]
]
};

@@ -44,14 +44,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); }); };
@@ -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`:
@@ -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 {
private _vIndex = -1;
@@ -532,7 +534,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) { }


/**
@@ -560,6 +563,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);
}

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

/**
@@ -726,7 +733,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);
}
@@ -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;

@@ -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,
@@ -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);
});
@@ -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 {

@@ -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;
}

@@ -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;
@@ -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;
}

0 comments on commit 83eabfa

Please sign in to comment.
You can’t perform that action at this time.