Skip to content

Commit 7bce412

Browse files
committed
feat(row-drag): Adding igxDragCustomGhost directive #6081
1 parent 2602e09 commit 7bce412

File tree

10 files changed

+160
-11
lines changed

10 files changed

+160
-11
lines changed

CHANGELOG.md

+17
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

+3-1
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

+20
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,25 @@ 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+
public get dragGhostCustomTemplate(): TemplateRef<IgxRowDragGhostDirective> {
1946+
if (this.dragGhostCustomTemplates && this.dragGhostCustomTemplates.first) {
1947+
return this.dragGhostCustomTemplates.first.templateRef;
1948+
}
1949+
1950+
return null;
1951+
}
1952+
1953+
/**
1954+
* @hidden
1955+
* @internal
1956+
*/
1957+
@ContentChildren(IgxRowDragGhostDirective, { read: IgxRowDragGhostDirective, descendants: false })
1958+
public dragGhostCustomTemplates: QueryList<IgxRowDragGhostDirective>;
1959+
19401960
/**
19411961
* @hidden
19421962
*/

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

+1-1
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.dragGhostCustomTemplate">
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

+84-2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ describe('IgxGrid - Row Drag Tests #grid', () => {
4343
TestBed.configureTestingModule({
4444
declarations: [
4545
IgxGridRowDraggableComponent,
46+
IgxGridRowCustomGhostDraggableComponent,
4647
IgxGridFeaturesRowDragComponent,
4748
IgxHierarchicalGridTestComponent,
4849
IgxTreeGridTestComponent
@@ -383,6 +384,28 @@ describe('IgxGrid - Row Drag Tests #grid', () => {
383384
const ghostElements = document.getElementsByClassName(CSS_CLASS_GHOST_ROW);
384385
expect(ghostElements.length).toEqual(0);
385386
}));
387+
388+
it('should correctly create custom ghost element', (async () => {
389+
fixture = TestBed.createComponent(IgxGridRowCustomGhostDraggableComponent);
390+
grid = fixture.componentInstance.instance;
391+
fixture.detectChanges();
392+
dragIndicatorElements = fixture.debugElement.queryAll(By.css('.' + CSS_CLASS_DRAG_INDICATOR));
393+
dragRows = fixture.debugElement.queryAll(By.directive(IgxRowDragDirective));
394+
const dragIndicatorElement = dragIndicatorElements[2].nativeElement;
395+
const startPoint: Point = UIInteractions.getPointFromElement(dragIndicatorElement);
396+
const movePoint: Point = UIInteractions.getPointFromElement(rows[4].nativeElement);
397+
const dropPoint: Point = UIInteractions.getPointFromElement(dropAreaElement);
398+
let ghostElements: HTMLCollection;
399+
400+
await pointerDown(dragIndicatorElement, startPoint, fixture);
401+
await pointerMove(dragIndicatorElement, movePoint, fixture);
402+
await pointerMove(dragIndicatorElement, dropPoint, fixture);
403+
ghostElements = document.getElementsByClassName(CSS_CLASS_GHOST_ROW);
404+
expect(ghostElements.length).toEqual(1);
405+
406+
const ghostText = document.getElementsByClassName(CSS_CLASS_GHOST_ROW)[0].textContent;
407+
expect(ghostText).toEqual(' Moving a row! ');
408+
}));
386409
});
387410
describe('Grid Features Integration Tests', () => {
388411
let dragGrid: IgxGridComponent;
@@ -634,8 +657,8 @@ describe('IgxGrid - Row Drag Tests #grid', () => {
634657
expect(row.grid.rowDragging).toBeTruthy();
635658

636659
const ghostElements = document.getElementsByClassName(CSS_CLASS_GHOST_ROW);
637-
const ghostElement = ghostElements[0];
638-
expect(ghostElements.length).toEqual(1);
660+
const ghostElement = ghostElements[1];
661+
expect(ghostElements.length).toEqual(2);
639662
expect(ghostElement.classList.contains(CSS_CLASS_SELECTED_ROW)).toBeFalsy();
640663

641664
await pointerMove(dragIndicatorElement, dropPoint, fixture);
@@ -959,6 +982,65 @@ export class IgxGridRowDraggableComponent extends DataParent {
959982
}
960983
}
961984

985+
@Component({
986+
template: `
987+
<igx-grid #grid
988+
[width]='width'
989+
[height]='height'
990+
primaryKey="ID"
991+
[data]="data"
992+
[autoGenerate]="true" (onColumnInit)="columnsCreated($event)" (onGroupingDone)="onGroupingDoneHandler($event)"
993+
[rowEditable]="true" [rowDraggable]="enableRowDraggable"
994+
>
995+
<ng-template let-data igxRowDragGhost>
996+
<div class="dragGhost">
997+
<igx-icon fontSet="material"></igx-icon>
998+
Moving a row!
999+
</div>
1000+
</ng-template>
1001+
</igx-grid>
1002+
<div #dropArea class="droppable-area" igxDrop (dropped)="onRowDrop($event)"
1003+
[ngStyle]="{width:'100px', height:'100px', backgroundColor:'red'}">
1004+
</div>
1005+
<div #nonDroppableArea class="non-droppable-area"
1006+
[ngStyle]="{width:'100px', height:'100px', backgroundColor:'yellow'}">
1007+
</div>
1008+
`
1009+
})
1010+
export class IgxGridRowCustomGhostDraggableComponent extends DataParent {
1011+
public width = '800px';
1012+
public height = null;
1013+
1014+
@ViewChild(IgxGridComponent, { read: IgxGridComponent, static: true })
1015+
public instance: IgxGridComponent;
1016+
1017+
@ViewChild('dropArea', { read: IgxDropDirective, static: true })
1018+
public dropArea: IgxDropDirective;
1019+
1020+
public enableSorting = false;
1021+
public enableFiltering = false;
1022+
public enableResizing = false;
1023+
public enableEditing = true;
1024+
public enableGrouping = true;
1025+
public enableRowEditing = true;
1026+
public enableRowDraggable = true;
1027+
public currentSortExpressions;
1028+
1029+
public columnsCreated(column: IgxColumnComponent) {
1030+
column.sortable = this.enableSorting;
1031+
column.filterable = this.enableFiltering;
1032+
column.resizable = this.enableResizing;
1033+
column.editable = this.enableEditing;
1034+
column.groupable = this.enableGrouping;
1035+
}
1036+
public onGroupingDoneHandler(sortExpr) {
1037+
this.currentSortExpressions = sortExpr;
1038+
}
1039+
public onRowDrop(args) {
1040+
args.cancel = true;
1041+
}
1042+
}
1043+
9621044
@Component({
9631045
template: `
9641046
<igx-grid #dragGrid

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

+1-1
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.dragGhostCustomTemplate">
1919
<ng-container *ngTemplateOutlet="this.grid.dragIndicatorIconTemplate ? this.grid.dragIndicatorIconTemplate : this.grid.dragIndicatorIconBase"></ng-container>
2020
</div>
2121
</ng-container>

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

+19-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Directive, Input, OnDestroy, NgModule } from '@angular/core';
1+
import { Directive, Input, OnDestroy, NgModule, TemplateRef } from '@angular/core';
22
import { IgxDragDirective } from '../directives/drag-drop/drag-drop.directive';
33
import { IRowDragEndEventArgs, IRowDragStartEventArgs } from './grid-base.component';
44
import { KEYS } from '../core/utils';
@@ -99,6 +99,11 @@ export class IgxRowDragDirective extends IgxDragDirective implements OnDestroy {
9999
protected createGhost(pageX, pageY) {
100100
this.row.grid.endEdit(true);
101101
this.row.grid.markForCheck();
102+
this.ghostContext = {
103+
$implicit: this.row.rowData,
104+
data: this.row.rowData,
105+
grid: this.row.grid
106+
};
102107
super.createGhost(pageX, pageY, this.row.nativeElement);
103108

104109
const ghost = this.ghostElement;
@@ -151,10 +156,21 @@ export class IgxRowDragDirective extends IgxDragDirective implements OnDestroy {
151156
export class IgxDragIndicatorIconDirective {
152157
}
153158

159+
/**
160+
* @hidden
161+
*/
162+
@Directive({
163+
selector: '[igxRowDragGhost]'
164+
})
165+
166+
export class IgxRowDragGhostDirective {
167+
constructor(public templateRef: TemplateRef<any>) { }
168+
}
169+
154170
@NgModule({
155-
declarations: [IgxRowDragDirective, IgxDragIndicatorIconDirective],
171+
declarations: [IgxRowDragDirective, IgxDragIndicatorIconDirective, IgxRowDragGhostDirective],
156172
entryComponents: [],
157-
exports: [IgxRowDragDirective, IgxDragIndicatorIconDirective],
173+
exports: [IgxRowDragDirective, IgxDragIndicatorIconDirective, IgxRowDragGhostDirective],
158174
imports: []
159175
})
160176

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<ng-container *ngIf="rowDraggable">
2-
<div [class]="resolveDragIndicatorClasses" [igxRowDrag]="this" (click)="$event.stopPropagation()">
2+
<div [class]="resolveDragIndicatorClasses" [igxRowDrag]="this" (click)="$event.stopPropagation()" [ghostTemplate]="this.grid.dragGhostCustomTemplate">
33
<ng-container *ngTemplateOutlet="this.grid.dragIndicatorIconTemplate ? this.grid.dragIndicatorIconTemplate : this.grid.dragIndicatorIconBase"></ng-container>
44
</div>
55
</ng-container>

src/app/grid-row-draggable/grid-row-draggable.sample.html

+6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@
1313
<igx-icon fontSet="material" [igxRowDrag]="cell.row">info</igx-icon>
1414
</ng-template>
1515
</igx-column>
16+
<ng-template let-data igxRowDragGhost>
17+
<div class="dragGhost">
18+
<igx-icon fontSet="material"></igx-icon>
19+
Moving {{data.ProductName}}!
20+
</div>
21+
</ng-template>
1622
</igx-grid>
1723
<igx-grid #grid2 igxDrop [data]="newData" [primaryKey]="'ProductID'"
1824
[displayDensity]="density" [width]="'500px'" [height]="'600px'" [emptyGridTemplate]="dragHereTemplate"

src/app/hierarchical-grid/hierarchical-grid.sample.html

+8-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ <h4 class="sample-title">Sample One</h4>
44
<igx-buttongroup [values]="displayDensities" (onSelect)="selectDensity($event)" style="display: block; width: 500px"></igx-buttongroup>
55
</div>
66
<button igxButton="raised" (click)="getState()">Get state</button>
7-
<igx-hierarchical-grid [(hierarchicalState)]="hgridState" [showExpandAll]='true' [hasChildrenKey]='"hasChild"' class="hgrid" [allowFiltering]='true' #grid1 [data]="localData" [displayDensity]="density" [rowSelectable]="true" [autoGenerate]="false" [allowFiltering]='true' [paging]="true"
7+
<igx-hierarchical-grid [rowDraggable]="true" [(hierarchicalState)]="hgridState" [showExpandAll]='true' [hasChildrenKey]='"hasChild"' class="hgrid" [allowFiltering]='true' #grid1 [data]="localData" [displayDensity]="density" [rowSelectable]="true" [autoGenerate]="false" [allowFiltering]='true' [paging]="true"
88
[height]="'600px'" [width]="'800px'" [expandChildren]="rootExpanded" #hGrid>
99
<igx-column field="ID" [resizable]="true" [pinned]="true" [filterable]='true'></igx-column>
1010
<igx-column-group header="Information">
@@ -23,7 +23,7 @@ <h4 class="sample-title">Sample One</h4>
2323
<ng-template igxRowCollapsedIndicator>
2424
<igx-icon role="button" fontSet="material">add</igx-icon>
2525
</ng-template>
26-
<igx-row-island [showExpandAll]='true' [key]="'childData'" [autoGenerate]="false" [allowFiltering]='false' [rowSelectable]='isRowSelectable' [expandChildren]="firstLevelExpanded" #layout1 >
26+
<igx-row-island [rowDraggable]="true" [showExpandAll]='true' [key]="'childData'" [autoGenerate]="false" [allowFiltering]='false' [rowSelectable]='isRowSelectable' [expandChildren]="firstLevelExpanded" #layout1 >
2727
<igx-column field="ID" [hasSummary]='true' [dataType]="'number'"></igx-column>
2828
<igx-column-group header="Information2">
2929
<igx-column field="ChildLevels" [resizable]="true" [groupable]='true'></igx-column>
@@ -53,6 +53,12 @@ <h4 class="sample-title">Sample One</h4>
5353
<igx-column field="ChildLevels" [groupable]='true'></igx-column>
5454
<igx-column field="ProductName" [groupable]='true'></igx-column>
5555
</igx-row-island> -->
56+
<ng-template let-data igxRowDragGhost>
57+
<div class="dragGhost">
58+
<igx-icon fontSet="material"></igx-icon>
59+
Moving {{data.ProductName}}!
60+
</div>
61+
</ng-template>
5662
</igx-hierarchical-grid>
5763

5864
<h4 class="sample-title">Sample two</h4>

0 commit comments

Comments
 (0)