Skip to content

Commit dccc990

Browse files
authored
Merge pull request #6118 from IgniteUI/amarinov/issue6081_82
2 parents fcb3b88 + a48e6b1 commit dccc990

File tree

11 files changed

+277
-13
lines changed

11 files changed

+277
-13
lines changed

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
11
# Ignite UI for Angular Change Log
22

33
All notable changes for each version of this project will be documented in this file.
4+
## 8.2.8
5+
### New Features
6+
- `IgxRowDragGhost` directive is added. It allows providing a custom template for the drag ghost when dragging a row.
7+
```html
8+
<igx-grid #grid1 [data]="remote | async" primaryKey="ProductID"
9+
[rowDraggable]="true">
10+
<igx-column field="ProductName"></igx-column>
11+
<igx-column field="ProductID"></igx-column>
12+
<igx-column field="UnitsInStock"></igx-column>
13+
<ng-template let-data igxRowDragGhost>
14+
<div>
15+
Moving {{data.ProductName}}!
16+
</div>
17+
</ng-template>
18+
</igx-grid>
19+
```
20+
421
## 8.2.6
522
### New Features
623
- `IgxSelectItem`

projects/igniteui-angular/src/lib/directives/drag-drop/drag-drop.directive.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ export class IgxDragLocation {
151151
})
152152
export class IgxDragDirective implements AfterContentInit, OnDestroy {
153153

154+
protected ghostContext: any = null;
155+
154156
/**
155157
* - Save data inside the `igxDrag` directive. This can be set when instancing `igxDrag` on an element.
156158
* ```html
@@ -1099,7 +1101,7 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy {
10991101

11001102
let dynamicGhostRef;
11011103
if (this.ghostTemplate) {
1102-
dynamicGhostRef = this.viewContainer.createEmbeddedView(this.ghostTemplate);
1104+
dynamicGhostRef = this.viewContainer.createEmbeddedView(this.ghostTemplate, this.ghostContext);
11031105
this.ghostElement = dynamicGhostRef.rootNodes[0];
11041106
} else {
11051107
this.ghostElement = node ? node.cloneNode(true) : this.element.nativeElement.cloneNode(true);

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ import { DeprecateProperty } from '../core/deprecateDecorators';
103103
import { IFilteringStrategy } from '../data-operations/filtering-strategy';
104104
import { IgxRowExpandedIndicatorDirective, IgxRowCollapsedIndicatorDirective,
105105
IgxHeaderExpandIndicatorDirective, IgxHeaderCollapseIndicatorDirective } from './grid/grid.directives';
106+
import { IgxRowDragGhostDirective } from './row-drag.directive';
106107
import { GridKeydownTargetType, GridSelectionMode, GridSummaryPosition, GridSummaryCalculationMode, FilterMode } from './common/enums';
107108

108109
const MINIMUM_COLUMN_WIDTH = 136;
@@ -1937,6 +1938,13 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements
19371938
@ContentChildren(IgxRowSelectorDirective, { read: IgxRowSelectorDirective, descendants: false })
19381939
public rowSelectorsTemplates: QueryList<IgxRowSelectorDirective>;
19391940

1941+
/**
1942+
* @hidden
1943+
* @internal
1944+
*/
1945+
@ContentChildren(IgxRowDragGhostDirective, { read: TemplateRef, descendants: false })
1946+
public dragGhostCustomTemplates: QueryList<TemplateRef<any>>;
1947+
19401948
/**
19411949
* @hidden
19421950
*/
@@ -3183,6 +3191,18 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements
31833191
}
31843192
}
31853193

3194+
/**
3195+
* @hidden
3196+
* @internal
3197+
*/
3198+
public getDragGhostCustomTemplate() {
3199+
if (this.dragGhostCustomTemplates && this.dragGhostCustomTemplates.first) {
3200+
return this.dragGhostCustomTemplates.first;
3201+
}
3202+
3203+
return null;
3204+
}
3205+
31863206
/**
31873207
* @hidden
31883208
*/

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<div class="igx-grid__row-indentation igx-grid__row-indentation--level-{{grid.groupingExpressions.length}}"></div>
33
</ng-container>
44
<ng-container *ngIf="rowDraggable">
5-
<div [class]="resolveDragIndicatorClasses" [igxRowDrag]="this" (click)="$event.stopPropagation()">
5+
<div [class]="resolveDragIndicatorClasses" [igxRowDrag]="this" (click)="$event.stopPropagation()" [ghostTemplate]="this.grid.getDragGhostCustomTemplate()">
66
<ng-container *ngTemplateOutlet="this.grid.dragIndicatorIconTemplate ? this.grid.dragIndicatorIconTemplate : this.grid.dragIndicatorIconBase"></ng-container>
77
</div>
88
</ng-container>

projects/igniteui-angular/src/lib/grids/grid/row-drag.directive.spec.ts

Lines changed: 184 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@ describe('IgxGrid - Row Drag Tests #grid', () => {
4343
TestBed.configureTestingModule({
4444
declarations: [
4545
IgxGridRowDraggableComponent,
46+
IgxGridRowCustomGhostDraggableComponent,
4647
IgxGridFeaturesRowDragComponent,
4748
IgxHierarchicalGridTestComponent,
49+
IgxHierarchicalGridCustomGhostTestComponent,
4850
IgxTreeGridTestComponent
4951
],
5052
imports: [
@@ -383,6 +385,33 @@ describe('IgxGrid - Row Drag Tests #grid', () => {
383385
const ghostElements = document.getElementsByClassName(CSS_CLASS_GHOST_ROW);
384386
expect(ghostElements.length).toEqual(0);
385387
}));
388+
389+
it('should correctly create custom ghost element', (async () => {
390+
fixture = TestBed.createComponent(IgxGridRowCustomGhostDraggableComponent);
391+
grid = fixture.componentInstance.instance;
392+
fixture.detectChanges();
393+
dragIndicatorElements = fixture.debugElement.queryAll(By.css('.' + CSS_CLASS_DRAG_INDICATOR));
394+
dragRows = fixture.debugElement.queryAll(By.directive(IgxRowDragDirective));
395+
const rowDragDirective = dragRows[1].injector.get(IgxRowDragDirective) as any;
396+
const dragIndicatorElement = dragIndicatorElements[2].nativeElement;
397+
const startPoint: Point = UIInteractions.getPointFromElement(dragIndicatorElement);
398+
const movePoint: Point = UIInteractions.getPointFromElement(rows[4].nativeElement);
399+
const dropPoint: Point = UIInteractions.getPointFromElement(dropAreaElement);
400+
let ghostElements: HTMLCollection;
401+
402+
await pointerDown(dragIndicatorElement, startPoint, fixture);
403+
await pointerMove(dragIndicatorElement, movePoint, fixture);
404+
await pointerMove(dragIndicatorElement, dropPoint, fixture);
405+
ghostElements = document.getElementsByClassName(CSS_CLASS_GHOST_ROW);
406+
expect(ghostElements.length).toEqual(1);
407+
408+
expect(rowDragDirective.ghostContext.data.ProductName).toEqual('NetAdvantage');
409+
expect(rowDragDirective.ghostContext.data.ID).toEqual(2);
410+
expect(rowDragDirective.ghostContext.grid).toEqual(grid);
411+
412+
const ghostText = document.getElementsByClassName(CSS_CLASS_GHOST_ROW)[0].textContent;
413+
expect(ghostText).toEqual(' Moving a row! ');
414+
}));
386415
});
387416
describe('Grid Features Integration Tests', () => {
388417
let dragGrid: IgxGridComponent;
@@ -634,8 +663,8 @@ describe('IgxGrid - Row Drag Tests #grid', () => {
634663
expect(row.grid.rowDragging).toBeTruthy();
635664

636665
const ghostElements = document.getElementsByClassName(CSS_CLASS_GHOST_ROW);
637-
const ghostElement = ghostElements[0];
638-
expect(ghostElements.length).toEqual(1);
666+
const ghostElement = ghostElements[1];
667+
expect(ghostElements.length).toEqual(2);
639668
expect(ghostElement.classList.contains(CSS_CLASS_SELECTED_ROW)).toBeFalsy();
640669

641670
await pointerMove(dragIndicatorElement, dropPoint, fixture);
@@ -771,7 +800,7 @@ describe('IgxGrid - Row Drag Tests #grid', () => {
771800
expect(dragCell.value).toEqual(newCellValue);
772801
}));
773802
});
774-
describe('Hiearchical Grid Tests', () => {
803+
describe('Hierarchical Grid Tests', () => {
775804
let dragGrid: IgxHierarchicalGridComponent;
776805
let dropGrid: IgxHierarchicalGridComponent;
777806
let dragRows: DebugElement[];
@@ -786,7 +815,7 @@ describe('IgxGrid - Row Drag Tests #grid', () => {
786815
dragRows = fixture.debugElement.queryAll(By.directive(IgxRowDragDirective));
787816
}));
788817

789-
it('should be able to drag row on every hiearchical level', (async () => {
818+
it('should be able to drag row on every hierarchical level', (async () => {
790819
// first level row
791820
let dragIndicatorElement: Element = dragIndicatorElements[1].nativeElement;
792821
let rowToDrag = dragGrid.getRowByIndex(0);
@@ -840,6 +869,47 @@ describe('IgxGrid - Row Drag Tests #grid', () => {
840869
await pointerUp(dragIndicatorElement, dropPoint, fixture);
841870
verifyRowDragEndEvent(nestedChildGrid, rowToDrag, rowDragDirective, false, 1);
842871
}));
872+
873+
it('should correctly create custom ghost element', (async () => {
874+
fixture = TestBed.createComponent(IgxHierarchicalGridCustomGhostTestComponent );
875+
dragGrid = fixture.componentInstance.hDragGrid;
876+
fixture.detectChanges();
877+
dragIndicatorElements = fixture.debugElement.queryAll(By.css('.' + CSS_CLASS_DRAG_INDICATOR));
878+
dragRows = fixture.debugElement.queryAll(By.directive(IgxRowDragDirective));
879+
880+
// first level row
881+
let dragIndicatorElement: Element = dragIndicatorElements[1].nativeElement;
882+
let rowToDrag = dragGrid.getRowByIndex(0);
883+
let rowDragDirective = dragRows[0].injector.get(IgxRowDragDirective) as any;
884+
885+
let startPoint: Point = UIInteractions.getPointFromElement(dragIndicatorElement);
886+
const movePoint: Point = UIInteractions.getPointFromElement(dragGrid.getRowByIndex(3).nativeElement);
887+
const dropPoint: Point = UIInteractions.getPointFromElement(dropAreaElement);
888+
889+
await pointerDown(dragIndicatorElement, startPoint, fixture);
890+
await pointerMove(dragIndicatorElement, movePoint, fixture);
891+
await pointerMove(dragIndicatorElement, dropPoint, fixture);
892+
await pointerUp(dragIndicatorElement, dropPoint, fixture);
893+
894+
expect(rowDragDirective.ghostContext.data.ProductName).toEqual('Product: A0');
895+
expect(rowDragDirective.ghostContext.grid).toEqual(dragGrid);
896+
897+
// second level row
898+
dragIndicatorElement = dragIndicatorElements[8].nativeElement;
899+
const childGrid = dragGrid.hgridAPI.getChildGrids(false)[0];
900+
rowToDrag = childGrid.getRowByIndex(0);
901+
rowDragDirective = dragRows[4].injector.get(IgxRowDragDirective);
902+
startPoint = UIInteractions.getPointFromElement(dragIndicatorElement);
903+
904+
await pointerDown(dragIndicatorElement, startPoint, fixture);
905+
await pointerMove(dragIndicatorElement, movePoint, fixture);
906+
await pointerMove(dragIndicatorElement, dropPoint, fixture);
907+
await pointerUp(dragIndicatorElement, dropPoint, fixture);
908+
909+
expect(rowDragDirective.ghostContext.data.ProductName).toEqual('Product: A0');
910+
expect(rowDragDirective.ghostContext.data.ChildLevels).toEqual(2);
911+
expect(rowDragDirective.ghostContext.grid).toEqual(childGrid);
912+
}));
843913
});
844914
describe('Tree Grid Tests', () => {
845915
let dragGrid: IgxTreeGridComponent;
@@ -959,6 +1029,65 @@ export class IgxGridRowDraggableComponent extends DataParent {
9591029
}
9601030
}
9611031

1032+
@Component({
1033+
template: `
1034+
<igx-grid #grid
1035+
[width]='width'
1036+
[height]='height'
1037+
primaryKey="ID"
1038+
[data]="data"
1039+
[autoGenerate]="true" (onColumnInit)="columnsCreated($event)" (onGroupingDone)="onGroupingDoneHandler($event)"
1040+
[rowEditable]="true" [rowDraggable]="enableRowDraggable"
1041+
>
1042+
<ng-template let-data igxRowDragGhost>
1043+
<div class="dragGhost">
1044+
<igx-icon fontSet="material"></igx-icon>
1045+
Moving a row!
1046+
</div>
1047+
</ng-template>
1048+
</igx-grid>
1049+
<div #dropArea class="droppable-area" igxDrop (dropped)="onRowDrop($event)"
1050+
[ngStyle]="{width:'100px', height:'100px', backgroundColor:'red'}">
1051+
</div>
1052+
<div #nonDroppableArea class="non-droppable-area"
1053+
[ngStyle]="{width:'100px', height:'100px', backgroundColor:'yellow'}">
1054+
</div>
1055+
`
1056+
})
1057+
export class IgxGridRowCustomGhostDraggableComponent extends DataParent {
1058+
public width = '800px';
1059+
public height = null;
1060+
1061+
@ViewChild(IgxGridComponent, { read: IgxGridComponent, static: true })
1062+
public instance: IgxGridComponent;
1063+
1064+
@ViewChild('dropArea', { read: IgxDropDirective, static: true })
1065+
public dropArea: IgxDropDirective;
1066+
1067+
public enableSorting = false;
1068+
public enableFiltering = false;
1069+
public enableResizing = false;
1070+
public enableEditing = true;
1071+
public enableGrouping = true;
1072+
public enableRowEditing = true;
1073+
public enableRowDraggable = true;
1074+
public currentSortExpressions;
1075+
1076+
public columnsCreated(column: IgxColumnComponent) {
1077+
column.sortable = this.enableSorting;
1078+
column.filterable = this.enableFiltering;
1079+
column.resizable = this.enableResizing;
1080+
column.editable = this.enableEditing;
1081+
column.groupable = this.enableGrouping;
1082+
}
1083+
public onGroupingDoneHandler(sortExpr) {
1084+
this.currentSortExpressions = sortExpr;
1085+
}
1086+
public onRowDrop(args) {
1087+
args.cancel = true;
1088+
}
1089+
}
1090+
9621091
@Component({
9631092
template: `
9641093
<igx-grid #dragGrid
@@ -1055,6 +1184,57 @@ export class IgxHierarchicalGridTestComponent {
10551184
}
10561185
}
10571186

1187+
@Component({
1188+
template: `
1189+
<igx-hierarchical-grid #hierarchicalDragGrid [data]="data"
1190+
[autoGenerate]="true" [height]="'500px'" [width]="'1500px'"
1191+
primaryKey="ID" [expandChildren]='true' [rowDraggable]="true">
1192+
<igx-row-island [key]="'childData'" [expandChildren]='true' [autoGenerate]="true" [rowDraggable]="true" #rowIsland>
1193+
<igx-row-island [key]="'childData2'" [autoGenerate]="true" [rowDraggable]="true" #rowIsland2 >
1194+
</igx-row-island>
1195+
<ng-template let-data igxRowDragGhost>
1196+
<div>
1197+
Moving {{data.ProductName}}!
1198+
</div>
1199+
</ng-template>
1200+
</igx-row-island>
1201+
<ng-template let-data igxRowDragGhost>
1202+
<div>
1203+
Moving {{data.ProductName}}!
1204+
</div>
1205+
</ng-template>
1206+
</igx-hierarchical-grid>`
1207+
})
1208+
export class IgxHierarchicalGridCustomGhostTestComponent {
1209+
public data;
1210+
newData = [];
1211+
@ViewChild('hierarchicalDragGrid', { read: IgxHierarchicalGridComponent, static: true }) public hDragGrid: IgxHierarchicalGridComponent;
1212+
@ViewChild('rowIsland', { read: IgxRowIslandComponent, static: true }) public rowIsland: IgxRowIslandComponent;
1213+
@ViewChild('rowIsland2', { read: IgxRowIslandComponent, static: true }) public rowIsland2: IgxRowIslandComponent;
1214+
1215+
constructor() {
1216+
this.data = this.generateData(2, 3);
1217+
}
1218+
generateData(count: number, level: number) {
1219+
const prods = [];
1220+
const currLevel = level;
1221+
let children;
1222+
for (let i = 0; i < count; i++) {
1223+
const item = {
1224+
ID: i, ChildLevels: currLevel, ProductName: 'Product: A' + i, 'Col1': i,
1225+
'Col2': i, 'Col3': i
1226+
};
1227+
if (currLevel > 1) {
1228+
children = this.generateData(count / 2, currLevel - 1);
1229+
const childProp = currLevel === 3 ? 'childData' : 'childData2';
1230+
item[childProp] = children;
1231+
}
1232+
prods.push(item);
1233+
}
1234+
return prods;
1235+
}
1236+
}
1237+
10581238
@Component({
10591239
template: `
10601240
<igx-tree-grid #treeGrid [data]="data" primaryKey="employeeID" foreignKey="PID" width="900px" height="500px" [rowDraggable]="true">

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,17 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseCompone
662662
}
663663
}
664664

665+
/**
666+
* @hidden
667+
* @internal
668+
*/
669+
public getDragGhostCustomTemplate(): TemplateRef<any> {
670+
if (this.parentIsland) {
671+
return this.parentIsland.getDragGhostCustomTemplate();
672+
}
673+
return super.getDragGhostCustomTemplate();
674+
}
675+
665676
/**
666677
* @hidden
667678
*/

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
</ng-template>
1616

1717
<ng-container *ngIf="rowDraggable">
18-
<div [class]="resolveDragIndicatorClasses" [igxRowDrag]="this" (click)="$event.stopPropagation()">
18+
<div [class]="resolveDragIndicatorClasses" [igxRowDrag]="this" (click)="$event.stopPropagation()" [ghostTemplate]="this.grid.getDragGhostCustomTemplate()">
1919
<ng-container *ngTemplateOutlet="this.grid.dragIndicatorIconTemplate ? this.grid.dragIndicatorIconTemplate : this.grid.dragIndicatorIconBase"></ng-container>
2020
</div>
2121
</ng-container>

0 commit comments

Comments
 (0)