Skip to content

Commit 18c3964

Browse files
authored
Merge branch 'master' into mkirova/expose-grid-sort-template-inputs
2 parents dab0655 + 668b954 commit 18c3964

File tree

8 files changed

+181
-22
lines changed

8 files changed

+181
-22
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ All notable changes for each version of this project will be documented in this
1010
- `sortHeaderIconTemplate` - Gets/Sets a custom template that should be used when rendering a header sorting indicator when columns are not sorted.
1111
- `sortAscendingHeaderIconTemplate` - Gets/Sets a custom template that should be used when rendering a header sorting indicator when columns are sorted in asc order.
1212
- `sortDescendingHeaderIconTemplate` - Gets/Sets a custom template that should be used when rendering a header sorting indicator when columns are sorted in desc order.
13+
- `dragGhostCustomTemplate` - Gets/Sets the custom template used for row drag.
14+
- `dragIndicatorIconTemplate` - Gets/Sets the custom template used for row drag indicator.
15+
- `detailTemplate` - Gets/Sets the master-detail template.
1316

1417
## 14.2.0
1518

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

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,6 +1227,33 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
12271227
@ContentChildren(IgxRowDragGhostDirective, { read: TemplateRef, descendants: false })
12281228
public dragGhostCustomTemplates: QueryList<TemplateRef<IgxGridRowDragGhostContext>>;
12291229

1230+
1231+
/**
1232+
* Gets the custom template, if any, used for row drag ghost.
1233+
*/
1234+
@Input()
1235+
public get dragGhostCustomTemplate() {
1236+
return this._dragGhostCustomTemplate || this.dragGhostCustomTemplates.first;
1237+
}
1238+
1239+
/**
1240+
* Sets a custom template for the row drag ghost.
1241+
*```html
1242+
* <ng-template #template igxRowDragGhost>
1243+
* <igx-icon>menu</igx-icon>
1244+
* </ng-template>
1245+
* ```
1246+
* ```typescript
1247+
* @ViewChild("'template'", {read: TemplateRef })
1248+
* public template: TemplateRef<any>;
1249+
* this.grid.dragGhostCustomTemplate = this.template;
1250+
* ```
1251+
*/
1252+
public set dragGhostCustomTemplate(template: TemplateRef<IgxGridRowDragGhostContext>) {
1253+
this._dragGhostCustomTemplate = template;
1254+
}
1255+
1256+
12301257
/**
12311258
* @hidden @internal
12321259
*/
@@ -2475,10 +2502,24 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
24752502
/**
24762503
* The custom template, if any, that should be used when rendering the row drag indicator icon
24772504
*/
2505+
@Input()
24782506
public get dragIndicatorIconTemplate(): TemplateRef<IgxGridEmptyTemplateContext> {
24792507
return this._customDragIndicatorIconTemplate || this.dragIndicatorIconTemplates.first;
24802508
}
24812509

2510+
/**
2511+
* Sets a custom template that should be used when rendering the row drag indicator icon.
2512+
*```html
2513+
* <ng-template #template igxDragIndicatorIcon>
2514+
* <igx-icon>expand_less</igx-icon>
2515+
* </ng-template>
2516+
* ```
2517+
* ```typescript
2518+
* @ViewChild("'template'", {read: TemplateRef })
2519+
* public template: TemplateRef<any>;
2520+
* this.grid.dragIndicatorIconTemplate = this.template;
2521+
* ```
2522+
*/
24822523
public set dragIndicatorIconTemplate(val: TemplateRef<IgxGridEmptyTemplateContext>) {
24832524
this._customDragIndicatorIconTemplate = val;
24842525
}
@@ -2949,6 +2990,7 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
29492990
private _filteredSortedData = null;
29502991

29512992
private _customDragIndicatorIconTemplate: TemplateRef<IgxGridEmptyTemplateContext>;
2993+
private _dragGhostCustomTemplate: TemplateRef<IgxGridRowDragGhostContext>;
29522994
private _cdrRequests = false;
29532995
private _resourceStrings;
29542996
private _emptyGridMessage = null;
@@ -3854,11 +3896,8 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
38543896
* @internal
38553897
*/
38563898
public getDragGhostCustomTemplate() {
3857-
if (this.dragGhostCustomTemplates && this.dragGhostCustomTemplates.first) {
3858-
return this.dragGhostCustomTemplates.first;
3859-
}
38603899

3861-
return null;
3900+
return this.dragGhostCustomTemplate;
38623901
}
38633902

38643903
/**

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@
124124
<div class="igx-grid__row-indentation igx-grid__row-indentation--level-{{groupingExpressions.length}}"></div>
125125
</ng-container>
126126
<ng-template
127-
[ngTemplateOutlet]='detailTemplate.first'
127+
[ngTemplateOutlet]='detailTemplate'
128128
[ngTemplateOutletContext]='getDetailsContext(rowData, rowIndex)'>
129129
</ng-template>
130130
</div>

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

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,43 @@ export class IgxGridComponent extends IgxGridBaseDirective implements GridType,
154154
/**
155155
* @hidden @internal
156156
*/
157-
@ContentChildren(IgxGridDetailTemplateDirective, { read: TemplateRef })
158-
public detailTemplate: QueryList<TemplateRef<IgxGridMasterDetailContext>> = new QueryList();
157+
@ContentChild(IgxGridDetailTemplateDirective, { read: TemplateRef })
158+
public detailTemplateDirective: TemplateRef<IgxGridMasterDetailContext>;
159+
160+
161+
/**
162+
* Returns a reference to the master-detail template.
163+
* ```typescript
164+
* let detailTemplate = this.grid.detailTemplate;
165+
* ```
166+
*
167+
* @memberof IgxColumnComponent
168+
*/
169+
@Input('detailTemplate')
170+
public get detailTemplate(): TemplateRef<IgxGridMasterDetailContext> {
171+
return this._detailTemplate;
172+
}
173+
/**
174+
* Sets the master-detail template.
175+
* ```html
176+
* <ng-template #detailTemplate igxGridDetail let-dataItem>
177+
* <div>
178+
* <div><span class='categoryStyle'>City:</span> {{dataItem.City}}</div>
179+
* <div><span class='categoryStyle'>Address:</span> {{dataItem.Address}}</div>
180+
* </div>
181+
* </ng-template>
182+
* ```
183+
* ```typescript
184+
* @ViewChild("'detailTemplate'", {read: TemplateRef })
185+
* public detailTemplate: TemplateRef<any>;
186+
* this.grid.detailTemplate = this.detailTemplate;
187+
* ```
188+
*
189+
* @memberof IgxColumnComponent
190+
*/
191+
public set detailTemplate(template: TemplateRef<IgxGridMasterDetailContext>) {
192+
this._detailTemplate = template;
193+
}
159194

160195
/**
161196
* @hidden @internal
@@ -268,6 +303,7 @@ export class IgxGridComponent extends IgxGridBaseDirective implements GridType,
268303
private _hideGroupedColumns = false;
269304
private _dropAreaMessage = null;
270305
private _showGroupArea = true;
306+
private _detailTemplate;
271307

272308
/**
273309
* Gets/Sets the array of data that populates the `IgxGridComponent`.
@@ -562,7 +598,7 @@ export class IgxGridComponent extends IgxGridBaseDirective implements GridType,
562598
* @hidden @internal
563599
*/
564600
public get hasDetails() {
565-
return !!this.detailTemplate.length;
601+
return !!this.detailTemplate;
566602
}
567603

568604
/**
@@ -921,6 +957,10 @@ export class IgxGridComponent extends IgxGridBaseDirective implements GridType,
921957
this._groupRowTemplate = this.groupTemplate.template;
922958
}
923959

960+
if (this.detailTemplateDirective) {
961+
this._detailTemplate = this.detailTemplateDirective;
962+
}
963+
924964

925965
if (this.hideGroupedColumns && this._columns && this.groupingExpressions) {
926966
this._setGroupColsVisibility(this.hideGroupedColumns);

projects/igniteui-angular/src/lib/grids/grid/grid.master-detail.spec.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, ViewChild, OnInit, DebugElement, QueryList } from '@angular/core';
1+
import { Component, ViewChild, OnInit, DebugElement, QueryList, TemplateRef } from '@angular/core';
22
import { TestBed, ComponentFixture, fakeAsync, tick } from '@angular/core/testing';
33
import { configureTestSuite } from '../../test-utils/configure-suite';
44
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
@@ -346,6 +346,17 @@ describe('IgxGrid Master Detail #grid', () => {
346346
expect(row.expanded).toBeFalsy();
347347
});
348348
});
349+
350+
it('should allow setting external details template via Input.', () => {
351+
grid = fix.componentInstance.grid;
352+
grid.detailTemplate = fix.componentInstance.detailTemplate;
353+
fix.detectChanges();
354+
grid.toggleRow(fix.componentInstance.data[0].ID);
355+
fix.detectChanges();
356+
const gridRows = grid.rowList.toArray();
357+
const firstDetail = GridFunctions.getMasterRowDetail(gridRows[0]);
358+
expect(firstDetail.textContent.trim()).toBe('NEW TEMPLATE');
359+
});
349360
});
350361

351362
describe('Keyboard Navigation ', () => {
@@ -1257,12 +1268,20 @@ describe('IgxGrid Master Detail #grid', () => {
12571268
</div>
12581269
</ng-template>
12591270
</igx-grid>
1271+
<ng-template igxGridDetail let-dataItem #detailTemplate>
1272+
<div>
1273+
NEW TEMPLATE
1274+
</div>
1275+
</ng-template>
12601276
`
12611277
})
12621278
export class DefaultGridMasterDetailComponent {
12631279
@ViewChild(IgxGridComponent, { read: IgxGridComponent, static: true })
12641280
public grid: IgxGridComponent;
12651281

1282+
@ViewChild('detailTemplate', { read: TemplateRef, static: true })
1283+
public detailTemplate: TemplateRef<any>;
1284+
12661285
public width = '800px';
12671286
public height = '500px';
12681287
public data = SampleTestData.contactInfoDataFull();

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

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, ViewChild, DebugElement, QueryList } from '@angular/core';
1+
import { Component, ViewChild, DebugElement, QueryList, TemplateRef } from '@angular/core';
22
import { TestBed, ComponentFixture, fakeAsync, tick } from '@angular/core/testing';
33
import { FormsModule } from '@angular/forms';
44
import { By } from '@angular/platform-browser';
@@ -420,10 +420,12 @@ describe('Row Drag Tests #grid', () => {
420420
]
421421
});
422422
}));
423-
it('should correctly create custom ghost element', () => {
423+
beforeEach(fakeAsync(() => {
424424
fixture = TestBed.createComponent(IgxGridRowCustomGhostDraggableComponent);
425425
grid = fixture.componentInstance.instance;
426426
fixture.detectChanges();
427+
}));
428+
it('should correctly create custom ghost element', () => {
427429
dropAreaElement = fixture.debugElement.query(By.css(CSS_CLASS_DROPPABLE_AREA)).nativeElement;
428430
rows = grid.rowList.toArray();
429431
dragIndicatorElements = fixture.debugElement.queryAll(By.css(CSS_CLASS_DRAG_INDICATOR));
@@ -449,6 +451,42 @@ describe('Row Drag Tests #grid', () => {
449451

450452
const ghostText = document.getElementsByClassName(CSS_CLASS_GHOST_ROW)[0].textContent;
451453
expect(ghostText).toEqual(' Moving a row! ');
454+
pointerUpEvent = UIInteractions.createPointerEvent('pointerup', dropPoint);
455+
rowDragDirective.onPointerUp(pointerUpEvent);
456+
});
457+
458+
it('should allow setting custom drag icon and ghost element via Input.', () => {
459+
dropAreaElement = fixture.debugElement.query(By.css(CSS_CLASS_DROPPABLE_AREA)).nativeElement;
460+
grid.dragIndicatorIconTemplate = fixture.componentInstance.rowDragTemplate;
461+
grid.dragGhostCustomTemplate = fixture.componentInstance.rowDragGhostTemplate;
462+
fixture.detectChanges();
463+
rows = grid.rowList.toArray();
464+
dragIndicatorElements = fixture.debugElement.queryAll(By.css(CSS_CLASS_DRAG_INDICATOR));
465+
dragIndicatorElement = dragIndicatorElements[2].nativeElement;
466+
dragRows = fixture.debugElement.queryAll(By.directive(IgxRowDragDirective));
467+
rowDragDirective = dragRows[1].injector.get(IgxRowDragDirective);
468+
469+
expect(dragIndicatorElement.textContent.trim()).toBe('expand_less');
470+
471+
startPoint = UIInteractions.getPointFromElement(dragIndicatorElement);
472+
movePoint = UIInteractions.getPointFromElement(rows[4].nativeElement);
473+
dropPoint = UIInteractions.getPointFromElement(dropAreaElement);
474+
pointerDownEvent = UIInteractions.createPointerEvent('pointerdown', startPoint);
475+
pointerMoveEvent = UIInteractions.createPointerEvent('pointermove', movePoint);
476+
477+
rowDragDirective.onPointerDown(pointerDownEvent);
478+
rowDragDirective.onPointerMove(pointerMoveEvent);
479+
pointerMoveEvent = UIInteractions.createPointerEvent('pointermove', dropPoint);
480+
rowDragDirective.onPointerMove(pointerMoveEvent);
481+
const ghostElements: HTMLCollection = document.getElementsByClassName(CSS_CLASS_GHOST_ROW);
482+
expect(ghostElements.length).toEqual(1);
483+
484+
const ghostText = document.getElementsByClassName(CSS_CLASS_GHOST_ROW)[0].textContent;
485+
expect(ghostText.trim()).toEqual('CUSTOM');
486+
487+
pointerUpEvent = UIInteractions.createPointerEvent('pointerup', dropPoint);
488+
rowDragDirective.onPointerUp(pointerUpEvent);
489+
452490
});
453491
});
454492
});
@@ -751,7 +789,7 @@ describe('Row Drag Tests #grid', () => {
751789

752790
const ghostElements = document.getElementsByClassName(CSS_CLASS_GHOST_ROW);
753791
const ghostElement = ghostElements[0];
754-
expect(ghostElements.length).toEqual(2);
792+
expect(ghostElements.length).toEqual(1);
755793
expect(ghostElement.classList.contains(CSS_CLASS_SELECTED_ROW)).toBeFalsy();
756794

757795
pointerMoveEvent = UIInteractions.createPointerEvent('pointermove', dropPoint);
@@ -1228,12 +1266,27 @@ export class IgxGridRowDraggableComponent extends DataParent {
12281266
<div #nonDroppableArea class="non-droppable-area"
12291267
[ngStyle]="{width:'100px', height:'100px', backgroundColor:'yellow'}">
12301268
</div>
1269+
1270+
<ng-template #rowDragGhostTemplate let-data igxRowDragGhost>
1271+
<div class="dragGhost">
1272+
CUSTOM
1273+
</div>
1274+
</ng-template>
1275+
<ng-template #rowDragTemplate let-data igxDragIndicatorIcon>
1276+
<igx-icon>expand_less</igx-icon>
1277+
</ng-template>
12311278
`
12321279
})
12331280
export class IgxGridRowCustomGhostDraggableComponent extends DataParent {
12341281
@ViewChild(IgxGridComponent, { read: IgxGridComponent, static: true })
12351282
public instance: IgxGridComponent;
12361283

1284+
@ViewChild('rowDragGhostTemplate', {read: TemplateRef, static: true })
1285+
public rowDragGhostTemplate: TemplateRef<any>;
1286+
1287+
@ViewChild('rowDragTemplate', {read: TemplateRef, static: true })
1288+
public rowDragTemplate: TemplateRef<any>;
1289+
12371290
@ViewChild('dropArea', { read: IgxDropDirective, static: true })
12381291
public dropArea: IgxDropDirective;
12391292

src/app/grid-master-detail/grid-master-detail.sample.html

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,17 @@
2424
<igx-column-layout field='group1'>
2525
<igx-column [rowStart]="1" [colStart]="1" [rowEnd]="4" field="ID"></igx-column>
2626
</igx-column-layout> -->
27-
<ng-template igxGridDetail let-dataItem>
28-
<div>
29-
<div *ngIf='true'>Test</div>
30-
<div *ngIf="dataItem.Country"><span class='categoryStyle'>Country:</span> {{dataItem.Country}}</div>
31-
<div><span class='categoryStyle'>City:</span> {{dataItem.City}}</div>
32-
<div><span class='categoryStyle'>Address:</span> {{dataItem.Address}}</div>
33-
</div>
34-
</ng-template>
27+
3528
</igx-grid>
3629
<br />
37-
30+
<ng-template igxGridDetail let-dataItem #detailTemplate>
31+
<div>
32+
<div *ngIf='true'>Test</div>
33+
<div *ngIf="dataItem.Country"><span class='categoryStyle'>Country:</span> {{dataItem.Country}}</div>
34+
<div><span class='categoryStyle'>City:</span> {{dataItem.City}}</div>
35+
<div><span class='categoryStyle'>Address:</span> {{dataItem.Address}}</div>
36+
</div>
37+
</ng-template>
3838
<button igxButton="raised" (click)="grid1.expandAll()">Expand All</button>
3939
<button igxButton="raised" (click)="grid1.collapseAll()">Collapse All</button>
4040
<button igxButton="raised" (click)="expandFirstRow()">Expand first</button>

src/app/grid-master-detail/grid-master-detail.sample.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* eslint-disable max-len */
2-
import { Component, ViewChild, OnInit, Inject } from '@angular/core';
2+
import { Component, ViewChild, OnInit, Inject, TemplateRef } from '@angular/core';
33

44
import { IgxGridComponent, IgxGridStateDirective } from 'igniteui-angular';
55
import { DisplayDensity, IDisplayDensityOptions, DisplayDensityToken } from 'projects/igniteui-angular/src/lib/core/density';
@@ -15,6 +15,9 @@ export class GridMasterDetailSampleComponent implements OnInit {
1515
public data: Array<any>;
1616
public expState = [];
1717
public columns: Array<any>;
18+
@ViewChild('detailTemplate', {read: TemplateRef, static: true })
19+
public detailTemplate: TemplateRef<any>;
20+
1821
constructor(@Inject(DisplayDensityToken) public displayDensityOptions: IDisplayDensityOptions) {}
1922
public ngOnInit(): void {
2023
this.columns = [
@@ -51,6 +54,8 @@ export class GridMasterDetailSampleComponent implements OnInit {
5154
{ Salary: '6600',ID: 'FRANR', CompanyName: 'France restauration', ContactName: 'Carine Schmitt', ContactTitle: 'Marketing Manager', Address: '54, rue Royale', City: 'Nantes', Region: null, PostalCode: '44000', Country: 'France', Phone: '40.32.21.21', Fax: '40.32.21.20' },
5255
{ Salary: '4900',ID: 'FRANS', CompanyName: 'Franchi S.p.A.', ContactName: 'Paolo Accorti', ContactTitle: 'Sales Representative', Address: 'Via Monte Bianco 34', City: 'Torino', Region: null, PostalCode: '10100', Country: 'Italy', Phone: '011-4988260', Fax: '011-4988261' }
5356
];
57+
58+
this.grid1.detailTemplate = this.detailTemplate;
5459
}
5560

5661
public expandFirstRow() {

0 commit comments

Comments
 (0)