igniteui-angular-sovn
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
1,507 lines (1,371 loc) • 253 kB
text/typescript
import { DOCUMENT, formatNumber, getLocaleNumberFormat, NumberFormatStyle } from '@angular/common';
import {
AfterContentInit,
AfterViewInit,
ApplicationRef,
ChangeDetectorRef,
ComponentRef,
ContentChild,
ContentChildren,
createComponent,
Directive,
DoCheck,
ElementRef,
EnvironmentInjector,
EventEmitter,
HostBinding,
HostListener,
Inject,
Injector,
Input,
IterableChangeRecord,
IterableDiffers,
LOCALE_ID,
NgZone,
OnDestroy,
OnInit,
Optional,
Output,
QueryList,
TemplateRef,
ViewChild,
ViewChildren,
ViewContainerRef
} from '@angular/core';
import { formatDate, resizeObservable } from '../core/utils';
import 'igniteui-trial-watermark';
import { Subject, pipe, fromEvent, animationFrameScheduler, merge } from 'rxjs';
import { takeUntil, first, filter, throttleTime, map, shareReplay, takeWhile } from 'rxjs/operators';
import { cloneArray, mergeObjects, compareMaps, resolveNestedPath, isObject, PlatformUtil } from '../core/utils';
import { GridColumnDataType } from '../data-operations/data-util';
import { FilteringLogic, IFilteringExpression } from '../data-operations/filtering-expression.interface';
import { IGroupByRecord } from '../data-operations/groupby-record.interface';
import { IForOfDataChangingEventArgs, IgxGridForOfDirective } from '../directives/for-of/for_of.directive';
import { IgxTextHighlightDirective } from '../directives/text-highlight/text-highlight.directive';
import { ISummaryExpression } from './summaries/grid-summary';
import { RowEditPositionStrategy } from './grid.common';
import { IgxGridToolbarComponent } from './toolbar/grid-toolbar.component';
import { IgxRowDirective } from './row.directive';
import { IgxOverlayOutletDirective, IgxToggleDirective } from '../directives/toggle/toggle.directive';
import {
FilteringExpressionsTree, IFilteringExpressionsTree, FilteringExpressionsTreeType
} from '../data-operations/filtering-expressions-tree';
import { IFilteringOperation } from '../data-operations/filtering-condition';
import { Transaction, TransactionType, TransactionService, State } from '../services/public_api';
import {
IgxRowAddTextDirective,
IgxRowEditTemplateDirective,
IgxRowEditTabStopDirective,
IgxRowEditTextDirective,
IgxRowEditActionsDirective
} from './grid.rowEdit.directive';
import { IgxGridNavigationService, IActiveNode } from './grid-navigation.service';
import { IDisplayDensityOptions, DisplayDensityToken, DisplayDensityBase, DisplayDensity } from '../core/density';
import { IgxFilteringService } from './filtering/grid-filtering.service';
import { IgxGridFilteringCellComponent } from './filtering/base/grid-filtering-cell.component';
import { WatchChanges } from './watch-changes';
import { IgxGridHeaderGroupComponent } from './headers/grid-header-group.component';
import { IGridResourceStrings } from '../core/i18n/grid-resources';
import { CurrentResourceStrings } from '../core/i18n/resources';
import { IgxGridSummaryService } from './summaries/grid-summary.service';
import { IgxSummaryRowComponent } from './summaries/summary-row.component';
import { IgxGridSelectionService } from './selection/selection.service';
import { IgxEditRow, IgxCell, IgxAddRow } from './common/crud.service';
import { ICachedViewLoadedEventArgs, IgxTemplateOutletDirective } from '../directives/template-outlet/template_outlet.directive';
import { IgxExcelStyleLoadingValuesTemplateDirective } from './filtering/excel-style/excel-style-search.component';
import { IgxGridColumnResizerComponent } from './resizing/resizer.component';
import { CharSeparatedValueData } from '../services/csv/char-separated-value-data';
import { IgxColumnResizingService } from './resizing/resizing.service';
import { FilteringStrategy, IFilteringStrategy } from '../data-operations/filtering-strategy';
import {
IgxRowExpandedIndicatorDirective, IgxRowCollapsedIndicatorDirective, IgxHeaderExpandedIndicatorDirective,
IgxHeaderCollapsedIndicatorDirective, IgxExcelStyleHeaderIconDirective, IgxSortAscendingHeaderIconDirective,
IgxSortDescendingHeaderIconDirective, IgxSortHeaderIconDirective
} from './grid/grid.directives';
import {
GridKeydownTargetType,
GridSelectionMode,
GridSummaryPosition,
GridSummaryCalculationMode,
FilterMode,
ColumnPinningPosition,
RowPinningPosition,
GridPagingMode,
GridValidationTrigger
} from './common/enums';
import {
IGridCellEventArgs,
IRowSelectionEventArgs,
IPinColumnEventArgs,
IGridEditEventArgs,
IRowDataEventArgs,
IColumnResizeEventArgs,
IColumnMovingStartEventArgs,
IColumnMovingEventArgs,
IColumnMovingEndEventArgs,
IGridKeydownEventArgs,
IRowDragStartEventArgs,
IRowDragEndEventArgs,
IGridClipboardEvent,
IGridToolbarExportEventArgs,
ISearchInfo,
ICellPosition,
IRowToggleEventArgs,
IColumnSelectionEventArgs,
IPinRowEventArgs,
IGridScrollEventArgs,
IGridEditDoneEventArgs,
IActiveNodeChangeEventArgs,
ISortingEventArgs,
IFilteringEventArgs,
IColumnVisibilityChangedEventArgs,
IColumnVisibilityChangingEventArgs,
IPinColumnCancellableEventArgs
} from './common/events';
import { IgxAdvancedFilteringDialogComponent } from './filtering/advanced-filtering/advanced-filtering-dialog.component';
import {
ColumnType,
GridServiceType,
GridType,
IGridFormGroupCreatedEventArgs,
IGridValidationStatusEventArgs,
IgxGridEmptyTemplateContext,
IgxGridHeaderTemplateContext,
IgxGridRowDragGhostContext,
IgxGridRowEditActionsTemplateContext,
IgxGridRowEditTemplateContext,
IgxGridRowEditTextTemplateContext,
IgxGridRowTemplateContext,
IgxGridTemplateContext,
IgxHeadSelectorTemplateContext,
IgxRowSelectorTemplateContext,
IGX_GRID_SERVICE_BASE,
ISizeInfo,
RowType,
IPinningConfig
} from './common/grid.interface';
import { DropPosition } from './moving/moving.service';
import { IgxHeadSelectorDirective, IgxRowSelectorDirective } from './selection/row-selectors';
import { IgxColumnComponent } from './columns/column.component';
import { IgxColumnGroupComponent } from './columns/column-group.component';
import { IgxRowDragGhostDirective, IgxDragIndicatorIconDirective } from './row-drag.directive';
import { IgxSnackbarComponent } from '../snackbar/snackbar.component';
import { v4 as uuidv4 } from 'uuid';
import { IgxActionStripComponent } from '../action-strip/action-strip.component';
import { IgxGridRowComponent } from './grid/grid-row.component';
import { IgxPaginatorComponent } from '../paginator/paginator.component';
import { IgxGridHeaderRowComponent } from './headers/grid-header-row.component';
import { IgxGridGroupByAreaComponent } from './grouping/grid-group-by-area.component';
import { IgxFlatTransactionFactory, TRANSACTION_TYPE } from '../services/transaction/transaction-factory.service';
import { ISortingOptions } from './columns/interfaces';
import { GridSelectionRange, IgxGridTransaction } from './common/types';
import { VerticalAlignment, HorizontalAlignment, PositionSettings, OverlaySettings } from '../services/overlay/utilities';
import { IgxOverlayService } from '../services/overlay/overlay';
import { ConnectedPositioningStrategy } from '../services/overlay/position/connected-positioning-strategy';
import { ContainerPositionStrategy } from '../services/overlay/position/container-position-strategy';
import { AbsoluteScrollStrategy } from '../services/overlay/scroll/absolute-scroll-strategy';
import { Action, StateUpdateEvent, TransactionEventOrigin } from '../services/transaction/transaction';
import { ISortingExpression } from '../data-operations/sorting-strategy';
import { IGridSortingStrategy } from './common/strategy';
import { IgxGridExcelStyleFilteringComponent } from './filtering/excel-style/excel-style-filtering.component';
import { IgxGridHeaderComponent } from './headers/grid-header.component';
import { IgxGridFilteringRowComponent } from './filtering/base/grid-filtering-row.component';
import { DefaultDataCloneStrategy, IDataCloneStrategy } from '../data-operations/data-clone-strategy';
import { IgxGridCellComponent } from './cell.component';
import { IgxGridValidationService } from './grid/grid-validation.service';
let FAKE_ROW_ID = -1;
const DEFAULT_ITEMS_PER_PAGE = 15;
const MINIMUM_COLUMN_WIDTH = 136;
// By default row editing overlay outlet is inside grid body so that overlay is hidden below grid header when scrolling.
// In cases when grid has 1-2 rows there isn't enough space in grid body and row editing overlay should be shown above header.
// Default row editing overlay height is higher then row height that is why the case is valid also for row with 2 rows.
// More accurate calculation is not possible, cause row editing overlay is still not shown and we don't know its height,
// but in the same time we need to set row editing overlay outlet before opening the overlay itself.
const MIN_ROW_EDITING_COUNT_THRESHOLD = 2;
@Directive()
export abstract class IgxGridBaseDirective extends DisplayDensityBase implements GridType,
OnInit, DoCheck, OnDestroy, AfterContentInit, AfterViewInit {
/**
* Gets/Sets the display time for the row adding snackbar notification.
*
* @remarks
* By default it is 6000ms.
*/
@Input()
public snackbarDisplayTime = 6000;
/**
* Gets/Sets whether to auto-generate the columns.
*
* @remarks
* The default value is false. When set to true, it will override all columns declared through code or in markup.
* @example
* ```html
* <igx-grid [data]="Data" [autoGenerate]="true"></igx-grid>
* ```
*/
@Input()
public autoGenerate = false;
/**
* Gets/Sets a list of property keys to be excluded from the generated column collection
* @remarks
* The collection is only used during initialization and changing it will not cause any changes in the generated columns at runtime
* unless the grid is destroyed and recreated. To modify the columns visible in the UI at runtime, please use their
* [hidden](https://www.infragistics.com/products/ignite-ui-angular/docs/typescript/latest/classes/IgxColumnComponent.html#hidden) property.
* @example
* ```html
* <igx-grid data=[Data] [autoGenerate]="true" [autoGenerateExclude]="['ProductName', 'Count']"></igx-grid>
* ```
* ```typescript
* const Data = [{ 'Id': '1', 'ProductName': 'name1', 'Description': 'description1', 'Count': 5 }]
* ```
*/
@Input()
public autoGenerateExclude: string[] = [];
/**
* Controls whether columns moving is enabled in the grid.
*
*/
@Input()
public moving = false;
/**
* Gets/Sets a custom template when empty.
*
* @example
* ```html
* <igx-grid [id]="'igx-grid-1'" [data]="Data" [emptyGridTemplate]="myTemplate" [autoGenerate]="true"></igx-grid>
* ```
*/
@Input()
public emptyGridTemplate: TemplateRef<void>;
/**
* Gets/Sets a custom template for adding row UI when grid is empty.
*
* @example
* ```html
* <igx-grid [id]="'igx-grid-1'" [data]="Data" [addRowEmptyTemplate]="myTemplate" [autoGenerate]="true"></igx-grid>
* ```
*/
@Input()
public addRowEmptyTemplate: TemplateRef<void>;
/**
* Gets/Sets a custom template when loading.
*
* @example
* ```html
* <igx-grid [id]="'igx-grid-1'" [data]="Data" [loadingGridTemplate]="myTemplate" [autoGenerate]="true"></igx-grid>
* ```
*/
@Input()
public loadingGridTemplate: TemplateRef<void>;
/**
* Get/Set IgxSummaryRow height
*/
@Input()
public set summaryRowHeight(value: number) {
this._summaryRowHeight = value | 0;
this.summaryService.summaryHeight = value;
if (!this._init) {
this.reflow();
}
}
public get summaryRowHeight(): number {
if (this.hasSummarizedColumns && this.rootSummariesEnabled) {
return this._summaryRowHeight || this.summaryService.calcMaxSummaryHeight();
}
return 0;
}
/** @hidden @internal */
public get hasColumnsToAutosize() {
return this._columns.some(x => x.width === 'fit-content');
}
/**
* Gets/Sets the data clone strategy of the grid when in edit mode.
*
* @example
* ```html
* <igx-grid #grid [data]="localData" [dataCloneStrategy]="customCloneStrategy"></igx-grid>
* ```
*/
@Input()
public get dataCloneStrategy(): IDataCloneStrategy {
return this._dataCloneStrategy;
}
public set dataCloneStrategy(strategy: IDataCloneStrategy) {
if (strategy) {
this._dataCloneStrategy = strategy;
this._transactions.cloneStrategy = strategy;
}
}
/**
* Controls the copy behavior of the grid.
*/
@Input()
public clipboardOptions = {
/**
* Enables/disables the copy behavior
*/
enabled: true,
/**
* Include the columns headers in the clipboard output.
*/
copyHeaders: true,
/**
* Apply the columns formatters (if any) on the data in the clipboard output.
*/
copyFormatters: true,
/**
* The separator used for formatting the copy output. Defaults to `\t`.
*/
separator: '\t'
};
/**
* Emitted after filtering is performed.
*
* @remarks
* Returns the filtering expressions tree of the column for which filtering was performed.
* @example
* ```html
* <igx-grid #grid [data]="localData" [height]="'305px'" [autoGenerate]="true"
* (filteringExpressionsTreeChange)="filteringExprTreeChange($event)"></igx-grid>
* ```
*/
@Output()
public filteringExpressionsTreeChange = new EventEmitter<IFilteringExpressionsTree>();
/**
* Emitted after advanced filtering is performed.
*
* @remarks
* Returns the advanced filtering expressions tree.
* @example
* ```html
* <igx-grid #grid [data]="localData" [height]="'305px'" [autoGenerate]="true"
* (advancedFilteringExpressionsTreeChange)="advancedFilteringExprTreeChange($event)"></igx-grid>
* ```
*/
@Output()
public advancedFilteringExpressionsTreeChange = new EventEmitter<IFilteringExpressionsTree>();
/**
* Emitted when grid is scrolled horizontally/vertically.
*
* @example
* ```html
* <igx-grid #grid [data]="localData" [height]="'305px'" [autoGenerate]="true"
* (gridScroll)="onScroll($event)"></igx-grid>
* ```
*/
@Output()
public gridScroll = new EventEmitter<IGridScrollEventArgs>();
/**
* Sets a conditional class selector to the grid's row element.
* Accepts an object literal, containing key-value pairs,
* where the key is the name of the CSS class and the value is
* either a callback function that returns a boolean, or boolean, like so:
* ```typescript
* callback = (row: RowType) => { return row.selected > 6; }
* rowClasses = { 'className' : this.callback };
* ```
* ```html
* <igx-grid #grid [data]="Data" [rowClasses] = "rowClasses" [autoGenerate]="true"></igx-grid>
* ```
*
* @memberof IgxColumnComponent
*/
@Input()
public rowClasses: any;
/**
* Sets conditional style properties on the grid row element.
* It accepts an object literal where the keys are
* the style properties and the value is an expression to be evaluated.
* ```typescript
* styles = {
* background: 'yellow',
* color: (row: RowType) => row.selected : 'red': 'white'
* }
* ```
* ```html
* <igx-grid #grid [data]="Data" [rowStyles]="styles" [autoGenerate]="true"></igx-grid>
* ```
*
* @memberof IgxColumnComponent
*/
@Input()
public rowStyles = null;
/**
* Gets/Sets the primary key.
*
* @example
* ```html
* <igx-grid #grid [data]="localData" [primaryKey]="'ProductID'" [autoGenerate]="true"></igx-grid>
* ```
*/
@WatchChanges()
@Input()
public primaryKey: any;
/**
* Gets/Sets a unique values strategy used by the Excel Style Filtering
*
* @remarks
* Provides a callback for loading unique column values on demand.
* If this property is provided, the unique values it generates will be used by the Excel Style Filtering.
* @example
* ```html
* <igx-grid [data]="localData" [filterMode]="'excelStyleFilter'" [uniqueColumnValuesStrategy]="columnValuesStrategy"></igx-grid>
* ```
*/
@Input()
public uniqueColumnValuesStrategy: (column: ColumnType,
filteringExpressionsTree: IFilteringExpressionsTree,
done: (values: any[]) => void) => void;
/** @hidden @internal */
@ContentChildren(IgxGridExcelStyleFilteringComponent, { read: IgxGridExcelStyleFilteringComponent, descendants: false })
public excelStyleFilteringComponents: QueryList<IgxGridExcelStyleFilteringComponent>;
/** @hidden @internal */
public get excelStyleFilteringComponent() {
return this.excelStyleFilteringComponents?.first;
}
/** @hidden @internal */
public get headerGroups() {
return this.theadRow.groups;
}
/**
* Emitted when a cell is clicked.
*
* @remarks
* Returns the `IgxGridCell`.
* @example
* ```html
* <igx-grid #grid (cellClick)="cellClick($event)" [data]="localData" [height]="'305px'" [autoGenerate]="true"></igx-grid>
* ```
*/
@Output()
public cellClick = new EventEmitter<IGridCellEventArgs>();
/**
* Emitted when formGroup is created on edit of row/cell.
*
* @example
* ```html
* <igx-grid #grid (formGroupCreated)="formGroupCreated($event)" [data]="localData" [height]="'305px'" [autoGenerate]="true"></igx-grid>
* ```
*/
@Output()
public formGroupCreated = new EventEmitter<IGridFormGroupCreatedEventArgs>();
/**
* Emitted when grid's validation status changes.
*
* @example
* ```html
* <igx-grid #grid (validationStatusChange)="validationStatusChange($event)" [data]="localData" [height]="'305px'" [autoGenerate]="true"></igx-grid>
* ```
*/
@Output()
public validationStatusChange = new EventEmitter<IGridValidationStatusEventArgs>();
/**
* Emitted when a cell is selected.
*
* @remarks
* Returns the `IgxGridCell`.
* @example
* ```html
* <igx-grid #grid (selected)="onCellSelect($event)" [data]="localData" [height]="'305px'" [autoGenerate]="true"></igx-grid>
* ```
*/
@Output()
public selected = new EventEmitter<IGridCellEventArgs>();
/**
* Emitted when `IgxGridRowComponent` is selected.
*
* @example
* ```html
* <igx-grid #grid (rowSelectionChanging)="rowSelectionChanging($event)" [data]="localData" [autoGenerate]="true"></igx-grid>
* ```
*/
@Output()
public rowSelectionChanging = new EventEmitter<IRowSelectionEventArgs>();
/**
* Emitted when `IgxColumnComponent` is selected.
*
* @example
* ```html
* <igx-grid #grid (columnSelectionChanging)="columnSelectionChanging($event)" [data]="localData" [autoGenerate]="true"></igx-grid>
* ```
*/
@Output()
public columnSelectionChanging = new EventEmitter<IColumnSelectionEventArgs>();
/**
* Emitted before `IgxColumnComponent` is pinned.
*
* @remarks
* The index at which to insert the column may be changed through the `insertAtIndex` property.
* @example
* ```typescript
* public columnPinning(event) {
* if (event.column.field === "Name") {
* event.insertAtIndex = 0;
* }
* }
* ```
*/
@Output()
public columnPin = new EventEmitter<IPinColumnCancellableEventArgs>();
/**
* Emitted after `IgxColumnComponent` is pinned.
*
* @remarks
* The index that the column is inserted at may be changed through the `insertAtIndex` property.
* @example
* ```typescript
* public columnPinning(event) {
* if (event.column.field === "Name") {
* event.insertAtIndex = 0;
* }
* }
* ```
*/
@Output()
public columnPinned = new EventEmitter<IPinColumnEventArgs>();
/**
* Emitted when cell enters edit mode.
*
* @remarks
* This event is cancelable.
* @example
* ```html
* <igx-grid #grid3 (cellEditEnter)="editStart($event)" [data]="data" [primaryKey]="'ProductID'">
* </igx-grid>
* ```
*/
@Output()
public cellEditEnter = new EventEmitter<IGridEditEventArgs>();
/**
* Emitted when cell exits edit mode.
*
* @example
* ```html
* <igx-grid #grid3 (cellEditExit)="editExit($event)" [data]="data" [primaryKey]="'ProductID'">
* </igx-grid>
* ```
*/
@Output()
public cellEditExit = new EventEmitter<IGridEditDoneEventArgs>();
/**
* Emitted when cell has been edited.
*
* @remarks
* Event is fired after editing is completed, when the cell is exiting edit mode.
* This event is cancelable.
* @example
* ```html
* <igx-grid #grid3 (cellEdit)="editDone($event)" [data]="data" [primaryKey]="'ProductID'">
* </igx-grid>
* ```
*/
@Output()
public cellEdit = new EventEmitter<IGridEditEventArgs>();
/**
* Emitted after cell has been edited and editing has been committed.
*
* @example
* ```html
* <igx-grid #grid3 (cellEditDone)="editDone($event)" [data]="data" [primaryKey]="'ProductID'">
* </igx-grid>
* ```
*/
@Output()
public cellEditDone = new EventEmitter<IGridEditDoneEventArgs>();
/**
* Emitted when a row enters edit mode.
*
* @remarks
* Emitted when [rowEditable]="true".
* This event is cancelable.
* @example
* ```html
* <igx-grid #grid3 (rowEditEnter)="editStart($event)" [primaryKey]="'ProductID'" [rowEditable]="true">
* </igx-grid>
* ```
*/
@Output()
public rowEditEnter = new EventEmitter<IGridEditEventArgs>();
/**
* Emitted when exiting edit mode for a row.
*
* @remarks
* Emitted when [rowEditable]="true" & `endEdit(true)` is called.
* Emitted when changing rows during edit mode, selecting an un-editable cell in the edited row,
* performing paging operation, column resizing, pinning, moving or hitting `Done`
* button inside of the rowEditingOverlay, or hitting the `Enter` key while editing a cell.
* This event is cancelable.
* @example
* ```html
* <igx-grid #grid3 (rowEdit)="editDone($event)" [data]="data" [primaryKey]="'ProductID'" [rowEditable]="true">
* </igx-grid>
* ```
*/
@Output()
public rowEdit = new EventEmitter<IGridEditEventArgs>();
/**
* Emitted after exiting edit mode for a row and editing has been committed.
*
* @remarks
* Emitted when [rowEditable]="true" & `endEdit(true)` is called.
* Emitted when changing rows during edit mode, selecting an un-editable cell in the edited row,
* performing paging operation, column resizing, pinning, moving or hitting `Done`
* button inside of the rowEditingOverlay, or hitting the `Enter` key while editing a cell.
* @example
* ```html
* <igx-grid #grid3 (rowEditDone)="editDone($event)" [data]="data" [primaryKey]="'ProductID'" [rowEditable]="true">
* </igx-grid>
* ```
*/
@Output()
public rowEditDone = new EventEmitter<IGridEditDoneEventArgs>();
/**
* Emitted when row editing is canceled.
*
* @remarks
* Emits when [rowEditable]="true" & `endEdit(false)` is called.
* Emitted when changing hitting `Esc` key during cell editing and when click on the `Cancel` button
* in the row editing overlay.
* @example
* ```html
* <igx-grid #grid3 (rowEditExit)="editExit($event)" [data]="data" [primaryKey]="'ProductID'" [rowEditable]="true">
* </igx-grid>
* ```
*/
@Output()
public rowEditExit = new EventEmitter<IGridEditDoneEventArgs>();
/**
* Emitted when a column is initialized.
*
* @remarks
* Returns the column object.
* @example
* ```html
* <igx-grid #grid [data]="localData" (columnInit)="initColumns($event)" [autoGenerate]="true"></igx-grid>
* ```
*/
@Output()
public columnInit = new EventEmitter<IgxColumnComponent>();
/**
* Emitted before sorting expressions are applied.
*
* @remarks
* Returns an `ISortingEventArgs` object. `sortingExpressions` key holds the sorting expressions.
* @example
* ```html
* <igx-grid #grid [data]="localData" [autoGenerate]="true" (sorting)="sorting($event)"></igx-grid>
* ```
*/
@Output()
public sorting = new EventEmitter<ISortingEventArgs>();
/**
* Emitted after sorting is completed.
*
* @remarks
* Returns the sorting expression.
* @example
* ```html
* <igx-grid #grid [data]="localData" [autoGenerate]="true" (sortingDone)="sortingDone($event)"></igx-grid>
* ```
*/
@Output()
public sortingDone = new EventEmitter<ISortingExpression | ISortingExpression[]>();
/**
* Emitted before filtering expressions are applied.
*
* @remarks
* Returns an `IFilteringEventArgs` object. `filteringExpressions` key holds the filtering expressions for the column.
* @example
* ```html
* <igx-grid #grid [data]="localData" [height]="'305px'" [autoGenerate]="true" (filtering)="filtering($event)"></igx-grid>
* ```
*/
@Output()
public filtering = new EventEmitter<IFilteringEventArgs>();
/**
* Emitted after filtering is performed through the UI.
*
* @remarks
* Returns the filtering expressions tree of the column for which filtering was performed.
* @example
* ```html
* <igx-grid #grid [data]="localData" [height]="'305px'" [autoGenerate]="true" (filteringDone)="filteringDone($event)"></igx-grid>
* ```
*/
@Output()
public filteringDone = new EventEmitter<IFilteringExpressionsTree>();
/**
* Emitted when a row is added.
*
* @remarks
* Returns the data for the new `IgxGridRowComponent` object.
* @example
* ```html
* <igx-grid #grid [data]="localData" (rowAdded)="rowAdded($event)" [height]="'305px'" [autoGenerate]="true"></igx-grid>
* ```
*/
@Output()
public rowAdded = new EventEmitter<IRowDataEventArgs>();
/**
* Emitted when a row is deleted.
*
* @remarks
* Returns an `IRowDataEventArgs` object.
* @example
* ```html
* <igx-grid #grid [data]="localData" (rowDeleted)="rowDeleted($event)" [height]="'305px'" [autoGenerate]="true"></igx-grid>
* ```
*/
@Output()
public rowDeleted = new EventEmitter<IRowDataEventArgs>();
/**
* Emmited when deleting a row.
*
* @remarks
* This event is cancelable.
* Returns an `IGridEditEventArgs` object.
* @example
* ```html
* <igx-grid #grid [data]="localData" (rowDelete)="rowDelete($event)" [height]="'305px'" [autoGenerate]="true"></igx-grid>
* ```
*/
@Output()
public rowDelete = new EventEmitter<IGridEditEventArgs>();
/**
* Emmited just before the newly added row is commited.
*
* @remarks
* This event is cancelable.
* Returns an `IGridEditEventArgs` object.
* @example
* ```html
* <igx-grid #grid [data]="localData" (rowAdd)="rowAdd($event)" [height]="'305px'" [autoGenerate]="true"></igx-grid>
* ```
*/
@Output()
public rowAdd = new EventEmitter<IGridEditEventArgs>();
/**
* Emitted after column is resized.
*
* @remarks
* Returns the `IgxColumnComponent` object's old and new width.
* @example
* ```html
* <igx-grid #grid [data]="localData" (columnResized)="resizing($event)" [autoGenerate]="true"></igx-grid>
* ```
*/
@Output()
public columnResized = new EventEmitter<IColumnResizeEventArgs>();
/**
* Emitted when a cell is right clicked.
*
* @remarks
* Returns the `IgxGridCell` object.
* ```html
* <igx-grid #grid [data]="localData" (contextMenu)="contextMenu($event)" [autoGenerate]="true"></igx-grid>
* ```
*/
@Output()
public contextMenu = new EventEmitter<IGridCellEventArgs>();
/**
* Emitted when a cell is double clicked.
*
* @remarks
* Returns the `IgxGridCell` object.
* @example
* ```html
* <igx-grid #grid [data]="localData" (doubleClick)="dblClick($event)" [autoGenerate]="true"></igx-grid>
* ```
*/
@Output()
public doubleClick = new EventEmitter<IGridCellEventArgs>();
/**
* Emitted before column visibility is changed.
*
* @remarks
* Args: { column: any, newValue: boolean }
* @example
* ```html
* <igx-grid (columnVisibilityChanging)="visibilityChanging($event)"></igx-grid>
* ```
*/
@Output()
public columnVisibilityChanging = new EventEmitter<IColumnVisibilityChangingEventArgs>();
/**
* Emitted after column visibility is changed.
*
* @remarks
* Args: { column: IgxColumnComponent, newValue: boolean }
* @example
* ```html
* <igx-grid (columnVisibilityChanged)="visibilityChanged($event)"></igx-grid>
* ```
*/
@Output()
public columnVisibilityChanged = new EventEmitter<IColumnVisibilityChangedEventArgs>();
/**
* Emitted when column moving starts.
*
* @remarks
* Returns the moved `IgxColumnComponent` object.
* @example
* ```html
* <igx-grid (columnMovingStart)="movingStart($event)"></igx-grid>
* ```
*/
@Output()
public columnMovingStart = new EventEmitter<IColumnMovingStartEventArgs>();
/**
* Emitted during the column moving operation.
*
* @remarks
* Returns the source and target `IgxColumnComponent` objects. This event is cancelable.
* @example
* ```html
* <igx-grid (columnMoving)="moving($event)"></igx-grid>
* ```
*/
@Output()
public columnMoving = new EventEmitter<IColumnMovingEventArgs>();
/**
* Emitted when column moving ends.
*
* @remarks
* Returns the source and target `IgxColumnComponent` objects.
* @example
* ```html
* <igx-grid (columnMovingEnd)="movingEnds($event)"></igx-grid>
* ```
*/
@Output()
public columnMovingEnd = new EventEmitter<IColumnMovingEndEventArgs>();
/**
* Emitted when keydown is triggered over element inside grid's body.
*
* @remarks
* This event is fired only if the key combination is supported in the grid.
* Return the target type, target object and the original event. This event is cancelable.
* @example
* ```html
* <igx-grid (gridKeydown)="customKeydown($event)"></igx-grid>
* ```
*/
@Output()
public gridKeydown = new EventEmitter<IGridKeydownEventArgs>();
/**
* Emitted when start dragging a row.
*
* @remarks
* Return the dragged row.
*/
@Output()
public rowDragStart = new EventEmitter<IRowDragStartEventArgs>();
/**
* Emitted when dropping a row.
*
* @remarks
* Return the dropped row.
*/
@Output()
public rowDragEnd = new EventEmitter<IRowDragEndEventArgs>();
/**
* Emitted when a copy operation is executed.
*
* @remarks
* Fired only if copy behavior is enabled through the [`clipboardOptions`]{@link IgxGridBaseDirective#clipboardOptions}.
*/
@Output()
public gridCopy = new EventEmitter<IGridClipboardEvent>();
/**
* @hidden @internal
*/
@Output()
public expansionStatesChange = new EventEmitter<Map<any, boolean>>();
/**
* Emitted when the expanded state of a row gets changed.
*
* @example
* ```html
* <igx-grid [data]="employeeData" (rowToggle)="rowToggle($event)" [autoGenerate]="true"></igx-grid>
* ```
*/
@Output()
public rowToggle = new EventEmitter<IRowToggleEventArgs>();
/**
* Emitted when the pinned state of a row is changed.
*
* @example
* ```html
* <igx-grid [data]="employeeData" (rowPinning)="rowPin($event)" [autoGenerate]="true"></igx-grid>
* ```
*/
@Output()
public rowPinning = new EventEmitter<IPinRowEventArgs>();
/**
* Emitted when the pinned state of a row is changed.
*
* @example
* ```html
* <igx-grid [data]="employeeData" (rowPinned)="rowPin($event)" [autoGenerate]="true"></igx-grid>
* ```
*/
@Output()
public rowPinned = new EventEmitter<IPinRowEventArgs>();
/**
* Emmited when the active node is changed.
*
* @example
* ```
* <igx-grid [data]="data" [autoGenerate]="true" (activeNodeChange)="activeNodeChange($event)"></igx-grid>
* ```
*/
@Output()
public activeNodeChange = new EventEmitter<IActiveNodeChangeEventArgs>();
/**
* Emitted before sorting is performed.
*
* @remarks
* Returns the sorting expressions.
* @example
* ```html
* <igx-grid #grid [data]="localData" [autoGenerate]="true" (sortingExpressionsChange)="sortingExprChange($event)"></igx-grid>
* ```
*/
@Output()
public sortingExpressionsChange = new EventEmitter<ISortingExpression[]>();
/**
* Emitted when an export process is initiated by the user.
*
* @example
* ```typescript
* toolbarExporting(event: IGridToolbarExportEventArgs){
* const toolbarExporting = event;
* }
* ```
*/
@Output()
public toolbarExporting = new EventEmitter<IGridToolbarExportEventArgs>();
/* End of toolbar related definitions */
/**
* Emitted when making a range selection.
*
* @remarks
* Range selection can be made either through drag selection or through keyboard selection.
*/
@Output()
public rangeSelected = new EventEmitter<GridSelectionRange>();
/** Emitted after the ngAfterViewInit hook. At this point the grid exists in the DOM */
@Output()
public rendered = new EventEmitter<boolean>();
/**
* @hidden @internal
*/
@Output()
public localeChange = new EventEmitter<boolean>();
/**
* Emitted before the grid's data view is changed because of a data operation, rebinding, etc.
*
* @example
* ```typescript
* <igx-grid #grid [data]="localData" [autoGenerate]="true" (dataChanging)='handleDataChangingEvent()'></igx-grid>
* ```
*/
@Output()
public dataChanging = new EventEmitter<IForOfDataChangingEventArgs>();
/**
* Emitted after the grid's data view is changed because of a data operation, rebinding, etc.
*
* @example
* ```typescript
* <igx-grid #grid [data]="localData" [autoGenerate]="true" (dataChanged)='handleDataChangedEvent()'></igx-grid>
* ```
*/
@Output()
public dataChanged = new EventEmitter<any>();
/**
* @hidden @internal
*/
@ViewChild(IgxSnackbarComponent)
public addRowSnackbar: IgxSnackbarComponent;
/**
* @hidden @internal
*/
@ViewChild(IgxGridColumnResizerComponent)
public resizeLine: IgxGridColumnResizerComponent;
/**
* @hidden @internal
*/
@ViewChild('loadingOverlay', { read: IgxToggleDirective, static: true })
public loadingOverlay: IgxToggleDirective;
/**
* @hidden @internal
*/
@ViewChild('igxLoadingOverlayOutlet', { read: IgxOverlayOutletDirective, static: true })
public loadingOutlet: IgxOverlayOutletDirective;
/**
* @hidden @internal
*/
@ContentChildren(IgxColumnComponent, { read: IgxColumnComponent, descendants: true })
public columnList: QueryList<IgxColumnComponent> = new QueryList<IgxColumnComponent>();
/** @hidden @internal */
@ContentChild(IgxActionStripComponent)
public actionStrip: IgxActionStripComponent;
/**
* @hidden @internal
*/
@ContentChild(IgxExcelStyleLoadingValuesTemplateDirective, { read: IgxExcelStyleLoadingValuesTemplateDirective, static: true })
public excelStyleLoadingValuesTemplateDirective: IgxExcelStyleLoadingValuesTemplateDirective;
/** @hidden @internal */
@ViewChild('emptyFilteredGrid', { read: TemplateRef, static: true })
public emptyFilteredGridTemplate: TemplateRef<any>;
/** @hidden @internal */
@ViewChild('defaultEmptyGrid', { read: TemplateRef, static: true })
public emptyGridDefaultTemplate: TemplateRef<any>;
/**
* @hidden @internal
*/
@ViewChild('defaultLoadingGrid', { read: TemplateRef, static: true })
public loadingGridDefaultTemplate: TemplateRef<any>;
/**
* @hidden @internal
*/
@ViewChild('scrollContainer', { read: IgxGridForOfDirective, static: true })
public parentVirtDir: IgxGridForOfDirective<any, any[]>;
/**
* @hidden
* @internal
*/
@ContentChildren(IgxHeadSelectorDirective, { read: TemplateRef, descendants: false })
public headSelectorsTemplates: QueryList<TemplateRef<IgxHeadSelectorTemplateContext>>;
/**
* @hidden
* @internal
*/
@ContentChildren(IgxRowSelectorDirective, { read: TemplateRef, descendants: false })
public rowSelectorsTemplates: QueryList<TemplateRef<IgxRowSelectorTemplateContext>>;
/**
* @hidden
* @internal
*/
@ContentChildren(IgxRowDragGhostDirective, { read: TemplateRef, descendants: false })
public dragGhostCustomTemplates: QueryList<TemplateRef<IgxGridRowDragGhostContext>>;
/**
* Gets the custom template, if any, used for row drag ghost.
*/
@Input()
public get dragGhostCustomTemplate() {
return this._dragGhostCustomTemplate || this.dragGhostCustomTemplates?.first;
}
/**
* Sets a custom template for the row drag ghost.
*```html
* <ng-template #template igxRowDragGhost>
* <igx-icon>menu</igx-icon>
* </ng-template>
* ```
* ```typescript
* @ViewChild("'template'", {read: TemplateRef })
* public template: TemplateRef<any>;
* this.grid.dragGhostCustomTemplate = this.template;
* ```
*/
public set dragGhostCustomTemplate(template: TemplateRef<IgxGridRowDragGhostContext>) {
this._dragGhostCustomTemplate = template;
}
/**
* @hidden @internal
*/
@ViewChild('verticalScrollContainer', { read: IgxGridForOfDirective, static: true })
public verticalScrollContainer: IgxGridForOfDirective<any, any[]>;
/**
* @hidden @internal
*/
@ViewChild('verticalScrollHolder', { read: IgxGridForOfDirective, static: true })
public verticalScroll: IgxGridForOfDirective<any, any[]>;
/**
* @hidden @internal
*/
@ViewChild('scr', { read: ElementRef, static: true })
public scr: ElementRef;
/** @hidden @internal */
@ViewChild('headSelectorBaseTemplate', { read: TemplateRef, static: true })
public headerSelectorBaseTemplate: TemplateRef<any>;
/**
* @hidden @internal
*/
@ViewChild('footer', { read: ElementRef })
public footer: ElementRef;
/** @hidden @internal */
public get headerContainer() {
return this.theadRow?.headerForOf;
}
/** @hidden @internal */
public get headerSelectorContainer() {
return this.theadRow?.headerSelectorContainer;
}
/** @hidden @internal */
public get headerDragContainer() {
return this.theadRow?.headerDragContainer;
}
/** @hidden @internal */
public get headerGroupContainer() {
return this.theadRow?.headerGroupContainer;
}
/** @hidden @internal */
public get filteringRow(): IgxGridFilteringRowComponent {
return this.theadRow?.filterRow;
}
/** @hidden @internal */
@ViewChild(IgxGridHeaderRowComponent, { static: true })
public theadRow: IgxGridHeaderRowComponent;
/** @hidden @internal */
@ViewChild(IgxGridGroupByAreaComponent)
public groupArea: IgxGridGroupByAreaComponent;
/**
* @hidden @internal
*/
@ViewChild('tbody', { static: true })
public tbody: ElementRef;
/**
* @hidden @internal
*/
@ViewChild('pinContainer', { read: ElementRef })
public pinContainer: ElementRef;
/**
* @hidden @internal
*/
@ViewChild('tfoot', { static: true })
public tfoot: ElementRef<HTMLElement>;
/**
* @hidden @internal
*/
@ViewChild('igxRowEditingOverlayOutlet', { read: IgxOverlayOutletDirective, static: true })
public rowEditingOutletDirective: IgxOverlayOutletDirective;
/**
* @hidden @internal
*/
@ViewChildren(IgxTemplateOutletDirective, { read: IgxTemplateOutletDirective })
public tmpOutlets: QueryList<any> = new QueryList<any>();
/**
* @hidden
* @internal
*/
@ViewChild('dragIndicatorIconBase', { read: TemplateRef, static: true })
public dragIndicatorIconBase: TemplateRef<any>;
/**
* @hidden @internal
*/
@ContentChildren(IgxRowEditTemplateDirective, { descendants: false, read: TemplateRef })
public rowEditCustomDirectives: QueryList<TemplateRef<IgxGridRowEditTemplateContext>>;
/**
* @hidden @internal
*/
@ContentChildren(IgxRowEditTextDirective, { descendants: false, read: TemplateRef })
public rowEditTextDirectives: QueryList<TemplateRef<IgxGridRowEditTextTemplateContext>>;
/**
* Gets the row edit text template.
*/
@Input()
public get rowEditTextTemplate(): TemplateRef<IgxGridRowEditTextTemplateContext> {
return this._rowEditTextTemplate || this.rowEditTextDirectives?.first;
}
/**
* Sets the row edit text template.
*```html
* <ng-template #template igxRowEditText let-rowChangesCount>
* Changes: {{rowChangesCount}}
* </ng-template>
* ```
*```typescript
* @ViewChild('template', {read: TemplateRef })
* public template: TemplateRef<any>;
* this.grid.rowEditTextTemplate = this.template;
* ```
*/
public set rowEditTextTemplate(template: TemplateRef<IgxGridRowEditTextTemplateContext>) {
this._rowEditTextTemplate = template;
}
/**
* @hidden @internal
*/
@ContentChild(IgxRowAddTextDirective, { read: TemplateRef })
public rowAddText: TemplateRef<IgxGridEmptyTemplateContext>;
/**
* Gets the row add text template.
*/
@Input()
public get rowAddTextTemplate(): TemplateRef<IgxGridEmptyTemplateContext> {
return this._rowAddTextTemplate || this.rowAddText;
}
/**
* Sets the row add text template.
*```html
* <ng-template #template igxRowAddText>
* Adding Row
* </ng-template>
* ```
*```typescript
* @ViewChild('template', {read: TemplateRef })
* public template: TemplateRef<any>;
* this.grid.rowAddTextTemplate = this.template;
* ```
*/
public set rowAddTextTemplate(template: TemplateRef<IgxGridEmptyTemplateContext>) {
this._rowAddTextTemplate = template;
}
/**
* @hidden @internal
*/
@ContentChildren(IgxRowEditActionsDirective, { descendants: false, read: TemplateRef })
public rowEditActionsDirectives: QueryList<TemplateRef<IgxGridRowEditActionsTemplateContext>>;
/**
* Gets the row edit actions template.
*/
@Input()
public get rowEditActionsTemplate(): TemplateRef<IgxGridRowEditActionsTemplateContext> {
return this._rowEditActionsTemplate || this.rowEditActionsDirectives?.first;
}
/**
* Sets the row edit actions template.
*```html
* <ng-template #template igxRowEditActions let-endRowEdit>
* <button igxButton igxRowEditTabStop (click)="endRowEdit(false)">Cancel</button>
* <button igxButton igxRowEditTabStop (click)="endRowEdit(true)">Apply</button>
* </ng-template>
* ```
*```typescript
* @ViewChild('template', {read: TemplateRef })
* public template: TemplateRef<any>;
* this.grid.rowEditActionsTemplate = this.template;
* ```
*/
public set rowEditActionsTemplate(template: TemplateRef<IgxGridRowEditActionsTemplateContext>) {
this._rowEditActionsTemplate = template;
}
/**
* The custom template, if any, that should be used when rendering a row expand indicator.
*/
@ContentChild(IgxRowExpandedIndicatorDirective, { read: TemplateRef })
protected rowExpandedIndicatorDirectiveTemplate: TemplateRef<IgxGridRowTemplateContext> = null;
/**
* Gets the row expand indicator template.
*/
@Input()
public get rowExpandedIndicatorTemplate(): TemplateRef<IgxGridRowTemplateContext> {
return this._rowExpandedIndicatorTemplate || this.rowExpandedIndicatorDirectiveTemplate;
}
/**
* Sets the row expand indicator template.
*```html
*<ng-template igxRowExpandedIndicator>
* <igx-icon role="button">remove</igx-icon>
*</ng-template>
* ```
*```typescript
* @ViewChild('template', {read: TemplateRef })
* public template: TemplateRef<any>;
* this.grid.rowExpandedIndicatorTemplate = this.template;
* ```
*/
public set rowExpandedIndicatorTemplate(template: TemplateRef<IgxGridRowTemplateContext>) {
this._rowExpandedIndicatorTemplate = template;
}
/**
* The custom template, if any, that should be used when rendering a row collapse indicator.
*/
@ContentChild(IgxRowCollapsedIndicatorDirective, { read: TemplateRef })
protected rowCollapsedIndicatorDirectiveTemplate: TemplateRef<IgxGridRowTemplateContext> = null;
/**
* Gets the row collapse indicator template.
*/
@Input()
public get rowCollapsedIndicatorTemplate(): TemplateRef<IgxGridRowTemplateContext> {
return this._rowCollapsedIndicatorTemplate || this.rowCollapsedIndicatorDirectiveTemplate;
}
/**
* Sets the row collapse indicator template.
*```html
*<ng-template igxRowCollapsedIndicator>
* <igx-icon role="button">add</igx-icon>
*</ng-template>
* ```
*```typescript
* @ViewChild('template', {read: TemplateRef })
* public template: TemplateRef<any>;
* this.grid.rowCollapsedIndicatorTemplate = this.template;
* ```
*/
public set rowCollapsedIndicatorTemplate(template: TemplateRef<IgxGridRowTemplateContext>) {
this._rowCollapsedIndicatorTemplate = template;
}
/**
* The custom template, if any, that should be used when rendering a header expand indicator.
*/
@ContentChild(IgxHeaderExpandedIndicatorDirective, { read: TemplateRef })
protected headerExpandedIndicatorDirectiveTemplate: TemplateRef<IgxGridTemplateContext> = null;
/**
* Gets the header expand indicator template.
*/
@Input()
public get headerExpandedIndicatorTemplate(): TemplateRef<IgxGridTemplateContext> {
return this._headerExpandIndicatorTemplate || this.headerExpandedIndicatorDirectiveTemplate;
}
/**
* Sets the header expand indicator template.
*```html
*<ng-template igxHeaderExpandedIndicator>
* <igx-icon role="button">remove</igx-icon>
*</ng-template>
* ```
*```typescript
* @ViewChild('template', {read: TemplateRef })
* public template: TemplateRef<any>;
* this.grid.headerExpandedIndicatorTemplate = this.template;
* ```
*/
public set headerExpandedIndicatorTemplate(template: TemplateRef<IgxGridTemplateContext>) {
this._headerExpandIndicatorTemplate = template;
}
/**
* The custom template, if any, that should be used when rendering a header collapse indicator.
*/
@ContentChild(IgxHeaderCollapsedIndicatorDirective, { read: TemplateRef })
protected headerCollapsedIndicatorDirectiveTemplate: TemplateRef<IgxGridTemplateContext> = null;
/**
* Gets the row collapse indicator template.
*/
@Input()
public get headerCollapsedIndicatorTemplate(): TemplateRef<IgxGridTemplateContext> {
return this._headerCollapseIndicatorTemplate || this.headerCollapsedIndicatorDirectiveTemplate;
}
/**
* Sets the row collapse indicator template.
*```html
*<ng-template igxHeaderCollapsedIndicator>
* <igx-icon role="button">add</igx-icon>
*</ng-template>
* ```
*```typescript
* @ViewChild('template', {read: TemplateRef })
* public template: TemplateRef<any>;
* this.grid.headerCollapsedIndicatorTemplate = this.template;
* ```
*/
public set headerCollapsedIndicatorTemplate(template: TemplateRef<IgxGridTemplateContext>) {
this._headerCollapseIndicatorTemplate = template;
}
/** @hidden @internal */
@ContentChild(IgxExcelStyleHeaderIconDirective, { read: TemplateRef })
public excelStyleHeaderIconDirectiveTemplate: TemplateRef<IgxGridHeaderTemplateContext> = null;
/**
* Gets the excel style header icon.
*/
@Input()
public get excelStyleHeaderIconTemplate(): TemplateRef<IgxGridHeaderTemplateContext> {
return this._excelStyleHeaderIconTemplate || this.excelStyleHeaderIconDirectiveTemplate;
}
/**
* Sets the excel style header icon.
*```html
*<ng-template #template igxExcelStyleHeaderIcon>
* <igx-icon>fil