Skip to content

Grid Master Detail #6119

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 65 commits into from
Nov 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
32ff076
feat(igxGrid): Master-detail view in grid - initial commit.
Oct 31, 2019
66d2d66
chore(*): KB expand/collapse with Alt+arrow keys.
Nov 1, 2019
7ec8158
chore(*): In case template is destroyed make sure cached view is deta…
Nov 1, 2019
52ab3a2
chore(*): Adding dev sample. Including public APIs.
Nov 1, 2019
a42a70d
chore(*): Fixing template. Adding kb nav handling for detail row. Upd…
Nov 4, 2019
941460c
chore(*): Minor fixes.
Nov 4, 2019
3b8c4a6
chore(*): Fixing some tests.
Nov 4, 2019
8d857c5
chore(*): Fixing additional template issues.
Nov 4, 2019
5899855
chore(*): Fixing mrl tests.
Nov 4, 2019
bb21829
chore(*): Fixing lint.
Nov 5, 2019
12a3d65
chore(*): Apply group row offsets to details content so that they rem…
Nov 5, 2019
450d8d9
chore(*): Handling additional edge cases for kb nav with tab/shift+ta…
Nov 5, 2019
a834456
Merge branch 'master' into mkirova/grid-master-detail
ChronosSF Nov 6, 2019
a0b537d
chore(*): Adding toggleRow API as per the spec.
Nov 7, 2019
2f6fcb8
chore(*): Merge from master.
Nov 8, 2019
48598fd
tests(master-detail): Add initial igxGrid Master Detail spec and scen…
skrustev Nov 8, 2019
901d8b8
Merge branch 'master' into mkirova/grid-master-detail
ChronosSF Nov 8, 2019
0ce0048
Merge branch 'master' into mkirova/grid-master-detail
ChronosSF Nov 11, 2019
bbed683
chore(*): Adding basic API tests.
Nov 11, 2019
882f6d7
chore(*): Adding kb up/down tests.
Nov 11, 2019
58c6bbf
test(mdv): adding paging tests #5880
ChronosSF Nov 11, 2019
c06a86e
chore(*): cross merge from upstream
ChronosSF Nov 11, 2019
eaaa95c
test(mdv): adding more integration tests #5880
ChronosSF Nov 11, 2019
4f856d7
chore(*): Adding more kbnav tests.
Nov 11, 2019
2e7da3a
chore(*): Fixing minor bug. Re-enabling related test.
Nov 11, 2019
769b457
chore(*): Fixing lint.
Nov 12, 2019
5c81779
chore(*): Fixing test imports.
Nov 12, 2019
2fa0a2d
Merge branch 'master' into mkirova/grid-master-detail
ChronosSF Nov 12, 2019
35f4f73
chore(*): Adding more intergration scenarios.
Nov 12, 2019
705e1a0
Merge branch 'mkirova/grid-master-detail' of https://github.com/Ignit…
Nov 12, 2019
973ea9d
chore(*): Adding a few more kb nav scenarios + minor fix.
Nov 12, 2019
f1b60e0
chore(*): Add more test scenarios
skrustev Nov 12, 2019
300002d
chore(*): Adding a few more tests and minor fixes.
Nov 12, 2019
9d48617
Merge branch 'mkirova/grid-master-detail' of https://github.com/Ignit…
Nov 12, 2019
9e4a82c
test(mdv): adding cell selection test #5880
ChronosSF Nov 12, 2019
51da071
chore(*): cross merge from upstream
ChronosSF Nov 12, 2019
e2e414a
Merge branch 'master' into mkirova/grid-master-detail
ChronosSF Nov 12, 2019
ef753df
test(mdv): adding row selection tests #5880
ChronosSF Nov 12, 2019
798de0c
chore(*): Adding more tests + fixes for MRL + Details Views kb nav.
Nov 13, 2019
20f3ec6
Merge branch 'mkirova/grid-master-detail' of https://github.com/Ignit…
Nov 13, 2019
1c3a068
chore(*): Adding more tests.
Nov 13, 2019
8a3977a
Merge branch 'master' into mkirova/grid-master-detail
ChronosSF Nov 13, 2019
349787e
Merge branch 'master' into mkirova/grid-master-detail
ChronosSF Nov 13, 2019
a2a95a9
chore(*): Fix issue with navigation in case details view contain a grid.
Nov 13, 2019
19a5909
Merge branch 'mkirova/grid-master-detail' of https://github.com/Ignit…
Nov 13, 2019
0c417eb
Merge branch 'master' into mkirova/grid-master-detail
kdinev Nov 18, 2019
ed7f2ff
docs(*): adding changelog for MDV #5880
ChronosSF Nov 18, 2019
df111a4
chore(*): Fix failing tests.
Nov 18, 2019
1467d27
Merge branch 'mkirova/grid-master-detail' of https://github.com/Ignit…
Nov 18, 2019
c692ef3
chore(*): Fix for additional mdv + kb nav scenarios.
Nov 18, 2019
90794be
Merge branch 'master' into mkirova/grid-master-detail
ChronosSF Nov 19, 2019
fbe2c28
chore(*): Fix for intergration scenarios with pinning when expandable…
Nov 20, 2019
d628aa7
Merge branch 'mkirova/grid-master-detail' of https://github.com/Ignit…
Nov 20, 2019
1c49aac
Merge branch 'master' into mkirova/grid-master-detail
kdinev Nov 20, 2019
4dc6372
chore(*): Applying changes after code review.
Nov 20, 2019
086d377
Merge branch 'mkirova/grid-master-detail' of https://github.com/Ignit…
Nov 20, 2019
d905ea2
Merge branch 'master' into mkirova/grid-master-detail
ChronosSF Nov 21, 2019
a14d068
chore(*): Removing handling for tab/shift+tab from/to last element fo…
Nov 22, 2019
eff1249
Merge branch 'mkirova/grid-master-detail' of https://github.com/Ignit…
Nov 22, 2019
f82b923
chore(*): Fixing test.
Nov 22, 2019
1442945
Merge branch 'master' into mkirova/grid-master-detail
ChronosSF Nov 23, 2019
a57ddc6
Merge branch 'master' into mkirova/grid-master-detail
MayaKirova Nov 25, 2019
41e5472
Merge branch 'master' into mkirova/grid-master-detail
ChronosSF Nov 27, 2019
2424060
Merge branch 'master' into mkirova/grid-master-detail
ChronosSF Nov 27, 2019
f958a91
Merge branch 'master' into mkirova/grid-master-detail
ChronosSF Nov 27, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ All notable changes for each version of this project will be documented in this

### New Features
- `IgxGrid`, `IgxTreeGrid`, `IgxHierarchicalGrid`:
- Master-Detail visualization added for `igxGrid`. Users may now define templates that show additional context for rows when expanded. For more information, please take a look at the [official documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/grid/master_detail.html).
- `sortStrategy` input is added, which can be used to set a global sorting strategy for the entire grid.
(**NOTE**: The grid's `sortStrategy` is of different type compared to the column's `sortStrategy`.)
- `NoopSortingStrategy` is added, which can be used to disable the default sorting of the grid by assigning its instance to the grid's `sortStrategy` input. (Useful for remote sorting.)
Expand Down
21 changes: 21 additions & 0 deletions projects/igniteui-angular/src/lib/grids/cell.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { ColumnType } from './common/column.interface';
import { RowType } from './common/row.interface';
import { GridSelectionMode } from './common/enums';
import { GridType } from './common/grid.interface';
import { IgxGridComponent } from './grid';

/**
* Providing reference to `IgxGridCellComponent`:
Expand Down Expand Up @@ -850,6 +851,26 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy {
} else if (expand) {
(this.gridAPI as any).trigger_row_expansion_toggle(this.row.treeRow, !this.row.expanded, event, this.visibleColumnIndex);
}
} else if ((this.grid as IgxGridComponent).hasDetails && this.isToggleKey(key)) {
const collapse = (this.row as any).expanded && ROW_COLLAPSE_KEYS.has(key);
const expand = !(this.row as any).expanded && ROW_EXPAND_KEYS.has(key);
const expandedStates = this.grid.expansionStates;
if (expand) {
expandedStates.set(this.row.rowID, true);
} else if (collapse) {
expandedStates.set(this.row.rowID, false);
}
this.grid.expansionStates = expandedStates;
this.grid.notifyChanges();
const isVirtualized = !this.grid.verticalScrollContainer.dc.instance.notVirtual;
// persist focused cell
const el = this.grid.selectionService.activeElement;
if (isVirtualized && el) {
const cell = this.grid.gridAPI.get_cell_by_visible_index(el.row, el.column);
if (cell) {
cell.nativeElement.focus();
}
Comment on lines +866 to +872
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't always persist the focus on the right cell element as notifyChanges is run on the next detection cycle and the layout of the grid body can shift up/down

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related to #6191

}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export interface GridType extends IGridDataBindable {
allowFiltering: boolean;
rowDraggable: boolean;
primaryKey: any;
id: string;

filterMode: FilterMode;

Expand Down Expand Up @@ -51,6 +52,7 @@ export interface GridType extends IGridDataBindable {

firstEditableColumnIndex: number;
lastEditableColumnIndex: number;
hasDetails: boolean;

sortingExpressions: ISortingExpression[];
sortingExpressionsChange: EventEmitter<ISortingExpression[]>;
Expand All @@ -62,4 +64,5 @@ export interface GridType extends IGridDataBindable {
sort(expression: ISortingExpression | Array<ISortingExpression>): void;
clearSort(name?: string): void;
isColumnGrouped(fieldName: string): boolean;
isDetailRecord(rec: any): boolean;
}
16 changes: 16 additions & 0 deletions projects/igniteui-angular/src/lib/grids/grid-base.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2866,6 +2866,22 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
this.hideOverlays();
}

/**
* @hidden
* @internal
*/
public isDetailRecord(rec) {
return false;
}

/**
* @hidden
* @internal
*/
public get hasDetails() {
return false;
}

/**
* @hidden
* @internal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService {
}

private focusCellUpFromLayout(rowElement: HTMLElement, selectedNode: ISelectionNode) {
const isGroupRow = rowElement.tagName.toLowerCase() === 'igx-grid-groupby-row';
const isNonDataRow = rowElement.tagName.toLowerCase() === 'igx-grid-groupby-row' || this._isDetailRecordAt(selectedNode.row);
const currentRowStart = selectedNode.layout ? selectedNode.layout.rowStart : 1;
const currentColStart = this.applyNavigationCell(selectedNode.layout ? selectedNode.layout.colStart : 1,
currentRowStart,
Expand All @@ -197,7 +197,7 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService {
(c.rowEnd === currentRowStart || c.rowStart + c.gridRowSpan === currentRowStart) &&
c.colStart <= currentColStart &&
(currentColStart < c.colEnd || currentColStart < c.colStart + c.gridColumnSpan));
if (isGroupRow || !upperElementColumn) {
if (isNonDataRow || !upperElementColumn) {
// no prev row in current row layout, go to next row last rowstart
const layoutRowEnd = this.grid.multiRowLayoutRowSize + 1;
upperElementColumn = columnLayout.children.find(c =>
Expand All @@ -218,6 +218,9 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService {
this._focusCell(upperElementColumn.cells.find((c) => c.rowIndex === prevRow.index).nativeElement);
} else if (prevRow) {
prevRow.nativeElement.focus({ preventScroll: true });
} else {
const prevElem = this.getRowByIndex(rowIndex, '') as any;
prevElem.focus({ preventScroll: true });
}
};
if (this.shouldPerformVerticalScroll(rowIndex, upperElementColumn.visibleIndex)) {
Expand All @@ -229,7 +232,7 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService {
}

private focusCellDownFromLayout(rowElement: HTMLElement, selectedNode: ISelectionNode) {
const isGroupRow = rowElement.tagName.toLowerCase() === 'igx-grid-groupby-row';
const isNonDataRow = rowElement.tagName.toLowerCase() === 'igx-grid-groupby-row' || this._isDetailRecordAt(selectedNode.row);
const parentIndex = selectedNode.column;
const columnLayout = this.grid.columns.find( x => x.columnLayout && x.visibleIndex === parentIndex);
const currentRowEnd = selectedNode.layout ? selectedNode.layout.rowEnd || selectedNode.layout.rowStart + 1 : 2;
Expand All @@ -241,7 +244,7 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService {
let nextElementColumn = columnLayout.children.find(c => c.rowStart === currentRowEnd &&
c.colStart <= currentColStart &&
(currentColStart < c.colEnd || currentColStart < c.colStart + c.gridColumnSpan));
if (isGroupRow || !nextElementColumn) {
if (isNonDataRow || !nextElementColumn) {
// no next row in current row layout, go to next row first rowstart
nextElementColumn = columnLayout.children.find(c => c.rowStart === 1 &&
c.colStart <= currentColStart &&
Expand All @@ -260,6 +263,9 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService {
this._focusCell(nextElementColumn.cells.find((c) => c.rowIndex === nextRow.index).nativeElement);
} else if (nextRow) {
nextRow.nativeElement.focus({ preventScroll: true });
} else {
const nextElem = this.getRowByIndex(rowIndex, '') as any;
nextElem.focus({ preventScroll: true });
}
};
if (this.shouldPerformVerticalScroll(rowIndex, nextElementColumn.visibleIndex)) {
Expand Down Expand Up @@ -447,7 +453,7 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService {
}

public shouldPerformVerticalScroll(rowIndex: number, visibleColumnIndex: number): boolean {
if (this._isGroupRecordAt(rowIndex)) {
if (this._isGroupRecordAt(rowIndex) || this._isDetailRecordAt(rowIndex)) {
return super.shouldPerformVerticalScroll(rowIndex, visibleColumnIndex);
}
if (!super.shouldPerformVerticalScroll(rowIndex, visibleColumnIndex)) {return false; }
Expand All @@ -472,9 +478,13 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService {
const record = this.grid.dataView[rowIndex];
return record.records && record.records.length;
}
private _isDetailRecordAt(rowIndex: number) {
const record = this.grid.dataView[rowIndex];
return this.grid.isDetailRecord(record);
}

public performVerticalScrollToCell(rowIndex: number, visibleColumnIndex: number, cb?: () => void) {
if (this._isGroupRecordAt(rowIndex)) {
if (this._isGroupRecordAt(rowIndex) || this._isDetailRecordAt(rowIndex)) {
return super.performVerticalScrollToCell(rowIndex, visibleColumnIndex, cb);
}
const containerHeight = this.grid.calcHeight ? Math.ceil(this.grid.calcHeight) : 0;
Expand Down
75 changes: 56 additions & 19 deletions projects/igniteui-angular/src/lib/grids/grid-navigation.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ export class IgxGridNavigationService {
const cells = this.grid.nativeElement.querySelectorAll(
`${cellSelector}[data-visibleIndex="${visibleColumnIndex}"]`);
if (cells.length > 0) {
(cells[cells.length - 1] as HTMLElement).focus();
(cells[cells.length - 1] as HTMLElement).focus({preventScroll: true});
}
});
}
Expand All @@ -294,13 +294,7 @@ export class IgxGridNavigationService {
.pipe(first())
.subscribe(() => {
const tag = rowElement.tagName.toLowerCase();
const rowSelector = this.getRowSelector();
if (tag === rowSelector || tag === 'igx-grid-summary-row') {
rowElement = this.getRowByIndex(currentRowIndex, tag);
} else {
rowElement = this.grid.nativeElement.querySelector(
`igx-grid-groupby-row[data-rowindex="${currentRowIndex}"]`);
}
rowElement = this.getRowByIndex(currentRowIndex, tag);
this.focusPreviousElement(rowElement, visibleColumnIndex);
});
} else {
Expand Down Expand Up @@ -341,7 +335,7 @@ export class IgxGridNavigationService {
}

protected focusElem(rowElement, visibleColumnIndex) {
if (rowElement.tagName.toLowerCase() === 'igx-grid-groupby-row') {
if (rowElement.tagName.toLowerCase() === 'igx-grid-groupby-row' || rowElement.className === 'igx-grid__tr-container') {
rowElement.focus();
} else {
const isSummaryRow = rowElement.tagName.toLowerCase() === 'igx-grid-summary-row';
Expand Down Expand Up @@ -433,17 +427,24 @@ export class IgxGridNavigationService {
const rowIndex = selectedNode.row;
const visibleColumnIndex = selectedNode.column;
const isSummaryRow = selectedNode.isSummaryRow;
const nextIsDetailRow = rowIndex + 1 <= this.grid.dataView.length - 1 ?
this.grid.isDetailRecord(this.grid.dataView[rowIndex + 1]) : false;
const isLastColumn = this.grid.unpinnedColumns[this.grid.unpinnedColumns.length - 1].visibleIndex === visibleColumnIndex;
if (isSummaryRow && rowIndex === 0 &&
this.grid.unpinnedColumns[this.grid.unpinnedColumns.length - 1].visibleIndex === visibleColumnIndex) {
return;
}
if (nextIsDetailRow && isLastColumn) {
this.navigateDown(currentRowEl, { row: rowIndex, column: visibleColumnIndex });
return;
}

if (this.isRowInEditMode(rowIndex)) {
this.moveNextEditable(rowIndex, visibleColumnIndex);
return;
}

if (this.grid.unpinnedColumns[this.grid.unpinnedColumns.length - 1].visibleIndex === visibleColumnIndex) {
if (isLastColumn) {
const rowEl = this.grid.rowList.find(row => row.index === rowIndex + 1) ?
this.grid.rowList.find(row => row.index === rowIndex + 1) :
this.grid.summariesRowList.find(row => row.index === rowIndex + 1);
Expand Down Expand Up @@ -556,6 +557,24 @@ export class IgxGridNavigationService {
return;
}

const prevIsDetailRow = rowIndex > 0 ? this.grid.isDetailRecord(this.grid.dataView[rowIndex - 1]) : false;
if (visibleColumnIndex === 0 && prevIsDetailRow) {
let target = currentRowEl.previousElementSibling;
const applyFocusFunc = () => {
target = this.getRowByIndex(rowIndex - 1, '');
target.focus({ preventScroll: true });
};
if (target) {
applyFocusFunc();
} else {
this.performVerticalScrollToCell(rowIndex - 1, visibleColumnIndex, () => {
applyFocusFunc();
});
}

return;
}

if (visibleColumnIndex === 0) {
if (rowIndex === 0 && this.grid.allowFiltering && this.grid.filterMode === FilterMode.quickFilter) {
this.moveFocusToFilterCell();
Expand All @@ -576,13 +595,12 @@ export class IgxGridNavigationService {

public shouldPerformVerticalScroll(targetRowIndex: number, visibleColumnIndex: number): boolean {
const containerTopOffset = parseInt(this.verticalDisplayContainerElement.style.top, 10);
const targetRow = this.grid.summariesRowList.filter(s => s.index !== 0)
.concat(this.grid.rowList.toArray()).find(r => r.index === targetRowIndex);
const targetRow = this.getRowByIndex(targetRowIndex, '') as any;
const rowHeight = this.grid.verticalScrollContainer.getSizeAt(targetRowIndex);
const containerHeight = this.grid.calcHeight ? Math.ceil(this.grid.calcHeight) : 0;
const targetEndTopOffset = targetRow ? targetRow.nativeElement.offsetTop + rowHeight + containerTopOffset :
const targetEndTopOffset = targetRow ? targetRow.offsetTop + rowHeight + containerTopOffset :
containerHeight + rowHeight;
if (!targetRow || targetRow.nativeElement.offsetTop < Math.abs(containerTopOffset)
if (!targetRow || targetRow.offsetTop < Math.abs(containerTopOffset)
|| containerHeight && containerHeight < targetEndTopOffset) {
return true;
} else {
Expand Down Expand Up @@ -622,13 +640,18 @@ export class IgxGridNavigationService {
}

protected getRowByIndex(index, selector = this.getRowSelector()) {
return this.grid.nativeElement.querySelector(
`${selector}[data-rowindex="${index}"]`);
}
const gridTag = this.grid.nativeElement.tagName.toLocaleLowerCase();
const row = Array.from(this.grid.tbody.nativeElement.querySelectorAll(
`${selector}[data-rowindex="${index}"]`))
.find(x => this.getClosestElemByTag(x, gridTag).getAttribute('id') === this.grid.id);
return row;
}

protected getNextRowByIndex(nextIndex) {
return this.grid.tbody.nativeElement.querySelector(
`[data-rowindex="${nextIndex}"]`);
const gridTag = this.grid.nativeElement.tagName.toLocaleLowerCase();
const row = Array.from(this.grid.tbody.nativeElement.querySelectorAll(
`[data-rowindex="${nextIndex}"]`)).find(x => this.getClosestElemByTag(x, gridTag).getAttribute('id') === this.grid.id);
return row;
}

private getAllRows() {
Expand All @@ -637,10 +660,24 @@ export class IgxGridNavigationService {
}

protected getCellSelector(visibleIndex?: number, isSummary = false): string {
if (visibleIndex === 0 && this.grid.hasDetails && !isSummary) {
return 'igx-expandable-grid-cell';
}
return isSummary ? 'igx-grid-summary-cell' : 'igx-grid-cell';
}

protected getRowSelector(): string {
return 'igx-grid-row';
}

protected getClosestElemByTag(sourceElem, targetTag) {
let result = sourceElem;
while (result !== null && result.nodeType === 1) {
if (result.tagName.toLowerCase() === targetTag.toLowerCase()) {
return result;
}
result = result.parentNode;
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<ng-template #defaultCell>
<div igxTextHighlight style="pointer-events: none" [cssClass]="highlightClass" [activeCssClass]="activeHighlightClass" [groupName]="gridID"
[value]="formatter ? formatter(value) : column.dataType === 'number' ? (value | igxdecimal: grid.locale) : column.dataType === 'date' ? (value | igxdate: grid.locale) : value"
[row]="rowData" [column]="this.column.field" [containerClass]="'igx-grid__td-text'"
class="igx-grid__td-text">{{ formatter ? formatter(value) : column.dataType === 'number' ? (value | igxdecimal:
grid.locale) : column.dataType === 'date' ? (value | igxdate: grid.locale) : value }}</div>
</ng-template>
<ng-template #inlineEditor let-cell="cell">
<ng-container *ngIf="column.dataType === 'string'">
<igx-input-group displayDensity="compact">
<input igxInput [(ngModel)]="editValue" [igxFocus]="focused">
</igx-input-group>
</ng-container>
<ng-container *ngIf="column.dataType === 'number'">
<igx-input-group displayDensity="compact">
<input igxInput [(ngModel)]="editValue" [igxFocus]="focused" type="number">
</igx-input-group>
</ng-container>
<ng-container *ngIf="column.dataType === 'boolean'">
<igx-checkbox (change)="editValue = $event.checked" [value]="editValue" [checked]="editValue" [disableRipple]="true"></igx-checkbox>
</ng-container>
<ng-container *ngIf="column.dataType === 'date'">
<igx-date-picker [style.width.%]="100" [outlet]="grid.outletDirective" mode="dropdown"
[locale]="grid.locale" [(value)]="editValue" [igxFocus]="focused" [labelVisibility]="false">
</igx-date-picker>
</ng-container>
</ng-template>
<ng-container *ngIf="!editMode">
<div #indicator
class="igx-grid__tree-grouping-indicator"
(click)="toggle($event)" (focus)="onIndicatorFocus()" tabindex="-1">
<ng-container *ngTemplateOutlet="iconTemplate; context: { $implicit: this }">
</ng-container>
</div>
</ng-container>
<ng-container *ngTemplateOutlet="template; context: context">
</ng-container>
<ng-template #defaultExpandedTemplate>
<igx-icon fontSet="material">expand_more</igx-icon>
</ng-template>
<ng-template #defaultCollapsedTemplate>
<igx-icon fontSet="material">chevron_right</igx-icon>
</ng-template>
Loading