Skip to content

Commit 8b62d1a

Browse files
committed
feat(igx-grid): Copy behavior for the grids
Moved copy handler on the tbody Copy with column formatters Refactored some dead code Closes #4907
1 parent 1194f84 commit 8b62d1a

File tree

12 files changed

+65
-40
lines changed

12 files changed

+65
-40
lines changed

projects/igniteui-angular/src/lib/core/grid-selection.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,11 +371,14 @@ export class IgxGridSelectionService {
371371
}
372372
}
373373

374-
keyboardStateOnFocus(node: ISelectionNode, emitter: EventEmitter<GridSelectionRange>): void {
374+
keyboardStateOnFocus(node: ISelectionNode, emitter: EventEmitter<GridSelectionRange>, dom): void {
375375
const kbState = this.keyboardState;
376376

377377
// Focus triggered by keyboard navigation
378378
if (kbState.active) {
379+
if (isChromium()) {
380+
this._moveSelectionChrome(dom);
381+
}
379382
// Start generating a range if shift is hold
380383
if (kbState.shift) {
381384
this.dragSelect(node, kbState);
@@ -524,4 +527,22 @@ export class IgxGridSelectionService {
524527
selection.addRange(this._selectionRange || document.createRange());
525528
}
526529
}
530+
531+
/**
532+
* (╯°□°)╯︵ ┻━┻
533+
* Chrome and Chromium don't care about the active
534+
* range after keyboard navigation, thus this.
535+
*/
536+
_moveSelectionChrome(node: Node) {
537+
const selection = window.getSelection();
538+
selection.removeAllRanges();
539+
const range = new Range();
540+
range.selectNode(node);
541+
range.collapse(true);
542+
selection.addRange(range);
543+
}
544+
}
545+
546+
export function isChromium(): boolean {
547+
return (/Chrom|e?ium/g.test(navigator.userAgent) || /Google Inc/g.test(navigator.vendor)) && !/Edge/g.test(navigator.userAgent);
527548
}

projects/igniteui-angular/src/lib/grids/cell.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<ng-template #defaultCell>
2-
<div igxTextHighlight [cssClass]="highlightClass" [activeCssClass]="activeHighlightClass" [groupName]="gridID"
2+
<div igxTextHighlight style="pointer-events: none" [cssClass]="highlightClass" [activeCssClass]="activeHighlightClass" [groupName]="gridID"
33
[value]="formatter ? formatter(value) : column.dataType === 'number' ? (value | igxdecimal: grid.locale) : column.dataType === 'date' ? (value | igxdate: grid.locale) : value"
44
[row]="rowData" [column]="this.column.field" [containerClass]="'igx-grid__td-text'"
55
class="igx-grid__td-text">{{ formatter ? formatter(value) : column.dataType === 'number' ? (value | igxdecimal:

projects/igniteui-angular/src/lib/grids/cell.component.ts

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -520,8 +520,6 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy {
520520
protected isInCompositionMode = false;
521521
protected compositionStartHandler;
522522
protected compositionEndHandler;
523-
protected focusHandlerIE;
524-
protected focusOut;
525523
private _highlight: IgxTextHighlightDirective;
526524

527525

@@ -552,12 +550,6 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy {
552550
// Hitting Enter with IME submits and exits from edit mode instead of first closing the IME dialog
553551
this.nativeElement.addEventListener('compositionstart', this.compositionStartHandler);
554552
this.nativeElement.addEventListener('compositionend', this.compositionEndHandler);
555-
556-
// https://stackoverflow.com/q/51404782
557-
this.focusHandlerIE = (e: FocusEvent) => this.onFocus(e);
558-
this.focusOut = () => this.onBlur();
559-
this.nativeElement.addEventListener('focusin', this.focusHandlerIE);
560-
this.nativeElement.addEventListener('focusout', this.focusOut);
561553
}
562554
});
563555
}
@@ -575,8 +567,6 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy {
575567
if (isIE()) {
576568
this.nativeElement.removeEventListener('compositionstart', this.compositionStartHandler);
577569
this.nativeElement.removeEventListener('compositionend', this.compositionEndHandler);
578-
this.nativeElement.removeEventListener('focusin', this.focusHandlerIE);
579-
this.nativeElement.removeEventListener('focusout', this.focusOut);
580570
}
581571
});
582572
}
@@ -792,7 +782,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy {
792782
}
793783

794784
this.selectionService.primaryButton = true;
795-
this.selectionService.keyboardStateOnFocus(node, this.grid.onRangeSelection);
785+
this.selectionService.keyboardStateOnFocus(node, this.grid.onRangeSelection, this.nativeElement);
796786
}
797787

798788
/**

projects/igniteui-angular/src/lib/grids/grid-base.component.ts

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ const MIN_ROW_EDITING_COUNT_THRESHOLD = 2;
105105
export const IgxGridTransaction = new InjectionToken<string>('IgxGridTransaction');
106106

107107
export interface IGridClipboardEvent {
108-
type: string;
109108
data: any[];
110109
cancel: boolean;
111110
}
@@ -2334,6 +2333,7 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements
23342333
clipboardOptions = {
23352334
enabled: true,
23362335
copyHeaders: true,
2336+
copyFormatters: true,
23372337
separator: '\t'
23382338
};
23392339

@@ -2601,9 +2601,10 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements
26012601

26022602
private keydownHandler(event) {
26032603
const key = event.key.toLowerCase();
2604-
if (event.ctrlKey && key === 'c' && this.clipboardOptions.enabled) {
2605-
isIE() ? this.copyHandler(null, true) : this.document.execCommand('copy');
2606-
}
2604+
// TODO: Move in a separate handler on the `grid body`.
2605+
// if (event.ctrlKey && key === 'c' && isIE()) {
2606+
// this.copyHandler(null, true);
2607+
// }
26072608
if ((isNavigationKey(key) && event.keyCode !== 32) || key === 'tab' || key === 'pagedown' || key === 'pageup') {
26082609
event.preventDefault();
26092610
if (key === 'pagedown') {
@@ -4814,7 +4815,7 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements
48144815
return this.selectionService.ranges;
48154816
}
48164817

4817-
extractDataFromSelection(source: any[]): any[] {
4818+
extractDataFromSelection(source: any[], applyColumnFormatters = false): any[] {
48184819
let column: IgxColumnComponent;
48194820
let record = {};
48204821
const selectedData = [];
@@ -4835,7 +4836,8 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements
48354836
for (const each of temp) {
48364837
column = visibleColumns[each];
48374838
if (column) {
4838-
record[column.field] = source[row][column.field];
4839+
record[column.field] = applyColumnFormatters && column.formatter ? column.formatter(source[row][column.field])
4840+
: source[row][column.field];
48394841
}
48404842
}
48414843
if (Object.keys(record).length) {
@@ -4846,10 +4848,9 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements
48464848
return selectedData;
48474849
}
48484850

4849-
getSelectedData() {
4851+
getSelectedData(applyColumnFormatters = false) {
48504852
const source = this.verticalScrollContainer.igxForOf;
4851-
4852-
return this.extractDataFromSelection(source);
4853+
return this.extractDataFromSelection(source, applyColumnFormatters);
48534854
}
48544855

48554856
/**
@@ -4873,7 +4874,6 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements
48734874
/**
48744875
* @hidden
48754876
*/
4876-
// @HostListener('scroll', ['$event'])
48774877
public scrollHandler(event) {
48784878
this.parentVirtDir.getHorizontalScroll().scrollLeft += event.target.scrollLeft;
48794879
this.verticalScrollContainer.getVerticalScroll().scrollTop += event.target.scrollTop;
@@ -4885,13 +4885,13 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements
48854885
* @hidden
48864886
* @internal
48874887
*/
4888-
@HostListener('copy', ['$event'])
48894888
public copyHandler(event, ie11 = false) {
4890-
if (!this.clipboardOptions.enabled) {
4889+
if (!this.clipboardOptions.enabled || this.crudService.inEditMode) {
48914890
return;
48924891
}
4893-
const data = this.getSelectedData();
4894-
const ev = { type: 'copy', data, cancel: false } as IGridClipboardEvent;
4892+
4893+
const data = this.getSelectedData(this.clipboardOptions.copyFormatters);
4894+
const ev = { data, cancel: false } as IGridClipboardEvent;
48954895
this.onGridCopy.emit(ev);
48964896

48974897
if (ev.cancel) {
@@ -4911,6 +4911,11 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements
49114911
}
49124912

49134913
event.preventDefault();
4914+
4915+
/* Necessary for the hiearachical case but will probably have to
4916+
change how getSelectedData is propagated in the hiearachical grid
4917+
*/
4918+
event.stopPropagation();
49144919
event.clipboardData.setData('text/plain', result);
49154920
}
49164921

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@
126126
<div class="igx-grid__thead-thumb" [hidden]='!hasVerticalSroll()' [style.width.px]="scrollWidth"></div>
127127
</div>
128128

129-
<div igxGridBody class="igx-grid__tbody">
129+
<div igxGridBody (copy)="copyHandler($event)" class="igx-grid__tbody">
130130
<div class="igx-grid__tbody-content" role="rowgroup" (onDragStop)="selectionService.dragMode = $event"
131131
(onDragScroll)="dragScroll($event)" [igxGridDragSelect]="selectionService.dragMode"
132132
[style.height.px]='calcHeight' [style.width.px]='calcWidth + 1' #tbody (scroll)='scrollHandler($event)'
@@ -263,4 +263,4 @@
263263
</ng-template>
264264

265265
<igx-grid-column-resizer *ngIf="colResizingService.showResizer"></igx-grid-column-resizer>
266-
<div class="igx-grid__outlet" #igxFilteringOverlayOutlet igxOverlayOutlet></div>
266+
<div class="igx-grid__outlet" #igxFilteringOverlayOutlet igxOverlayOutlet></div>

projects/igniteui-angular/src/lib/grids/grid/grid.component.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -933,7 +933,7 @@ export class IgxGridComponent extends IgxGridBaseComponent implements IGridDataB
933933
}
934934
}
935935

936-
getSelectedData(): any[] {
936+
getSelectedData(applyColumnFormatters = false): any[] {
937937
if (this.groupingExpressions.length) {
938938
const source = [];
939939

@@ -947,9 +947,9 @@ export class IgxGridComponent extends IgxGridBaseComponent implements IGridDataB
947947
};
948948

949949
this.verticalScrollContainer.igxForOf.forEach(process);
950-
return this.extractDataFromSelection(source);
950+
return this.extractDataFromSelection(source, applyColumnFormatters);
951951
} else {
952-
return super.getSelectedData();
952+
return super.getSelectedData(applyColumnFormatters);
953953
}
954954
}
955955

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
<div class="igx-grid__thead-thumb" [hidden]='!hasVerticalSroll()' [style.width.px]="scrollWidth"></div>
9494
</div>
9595

96-
<div igxGridBody class="igx-grid__tbody">
96+
<div igxGridBody (copy)="copyHandler($event)" class="igx-grid__tbody">
9797
<div class="igx-grid__tbody-content" (onDragStop)="selectionService.dragMode = $event"
9898
(onDragScroll)="dragScroll($event)" [igxGridDragSelect]="selectionService.dragMode" role="rowgroup"
9999
[style.height.px]='calcHeight' [style.width.px]='calcWidth + 1' #tbody (scroll)='scrollHandler($event)'>

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<ng-template #defaultCell>
2-
<div igxTextHighlight [cssClass]="highlightClass" [activeCssClass]="activeHighlightClass" [groupName]="gridID"
2+
<div igxTextHighlight style="pointer-events: none" [cssClass]="highlightClass" [activeCssClass]="activeHighlightClass" [groupName]="gridID"
33
[value]="formatter ? formatter(value) : column.dataType === 'number' ? (value | igxdecimal: grid.locale) : column.dataType === 'date' ? (value | igxdate: grid.locale) : value"
44
[row]="rowData" [column]="this.column.field" [containerClass]="'igx-grid__td-text'"
55
class="igx-grid__td-text">{{ formatter ? formatter(value) : column.dataType === 'number' ? (value | igxdecimal:
@@ -11,7 +11,7 @@
1111
<input igxInput [(ngModel)]="editValue" [igxFocus]="focused">
1212
</igx-input-group>
1313
</ng-container>
14-
<ng-container *ngIf="column.dataType === 'number'">
14+
<ng-container *ngIf="column.dataType === 'number'">
1515
<igx-input-group displayDensity="compact">
1616
<input igxInput [(ngModel)]="editValue" [igxFocus]="focused" type="number">
1717
</igx-input-group>

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
id="right" class="igx-grid__scroll-on-drag-right"></span>
8484
</div>
8585

86-
<div igxGridBody class="igx-grid__tbody">
86+
<div igxGridBody (copy)="copyHandler($event)" class="igx-grid__tbody">
8787
<div class="igx-grid__tbody-content" role="rowgroup" (onDragStop)="selectionService.dragMode = $event"
8888
(onDragScroll)="dragScroll($event)" [igxGridDragSelect]="selectionService.dragMode"
8989
[style.height.px]='calcHeight' [style.width.px]='calcWidth' #tbody (scroll)='scrollHandler($event)'
@@ -197,4 +197,4 @@
197197
</ng-template>
198198

199199
<igx-grid-column-resizer *ngIf="colResizingService.showResizer"></igx-grid-column-resizer>
200-
<div class="igx-grid__outlet" #igxFilteringOverlayOutlet igxOverlayOutlet></div>
200+
<div class="igx-grid__outlet" #igxFilteringOverlayOutlet igxOverlayOutlet></div>

projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -729,7 +729,7 @@ export class IgxTreeGridComponent extends IgxGridBaseComponent implements IGridD
729729
};
730730
}
731731

732-
getSelectedData(): any[] {
732+
getSelectedData(applyColumnFormatters = false): any[] {
733733
const source = [];
734734

735735
const process = (record) => {
@@ -741,7 +741,7 @@ export class IgxTreeGridComponent extends IgxGridBaseComponent implements IGridD
741741
};
742742

743743
this.verticalScrollContainer.igxForOf.forEach(process);
744-
return this.extractDataFromSelection(source);
744+
return this.extractDataFromSelection(source, applyColumnFormatters);
745745
}
746746

747747
/**

0 commit comments

Comments
 (0)