diff --git a/projects/igniteui-angular/src/lib/core/utils.ts b/projects/igniteui-angular/src/lib/core/utils.ts index 96301bbfc2f..e71f423447e 100644 --- a/projects/igniteui-angular/src/lib/core/utils.ts +++ b/projects/igniteui-angular/src/lib/core/utils.ts @@ -163,10 +163,10 @@ export const enum KEYS { * let range = document.createRange(); * let column = this.grid.columnList.filter(c => c.field === 'ID')[0]; * -* let size = valToPxlsUsingRange(range, column.cells[0].nativeElement); +* let size = getNodeSizeViaRange(range, column.cells[0].nativeElement); * ``` */ -export function valToPxlsUsingRange(range: Range, node: any): number { +export function getNodeSizeViaRange(range: Range, node: any): number { let overflow = null; if (isIE() || isEdge()) { overflow = node.style.overflow; @@ -194,7 +194,7 @@ export function valToPxlsUsingRange(range: Range, node: any): number { * let size = valToPxlsUsingCanvas(ctx, column.cells[0].nativeElement); * ``` */ -export function valToPxlsUsingCanvas(canvas2dCtx: any, node: any): number { +export function getNodeSizeViaCanvas(canvas2dCtx: any, node: any): number { const s = this.grid.document.defaultView.getComputedStyle(node); // need to set the font to get correct width @@ -230,6 +230,22 @@ export function isNavigationKey(key: string): boolean { 'home', 'end', 'space', 'spacebar', ' '].indexOf(key) !== -1; } +/** + *@hidden + */ +export function flatten(arr: any[]) { + let result = []; + + arr.forEach(el => { + result.push(el); + if (el.children) { + const children = Array.isArray(el.children) ? el.children : el.children.toArray(); + result = result.concat(flatten(children)); + } + }); + return result; +} + export interface CancelableEventArgs { /** * Provides the ability to cancel the event. diff --git a/projects/igniteui-angular/src/lib/directives/dragdrop/dragdrop.directive.ts b/projects/igniteui-angular/src/lib/directives/dragdrop/dragdrop.directive.ts index 56a37b5eb40..502be6d07ad 100644 --- a/projects/igniteui-angular/src/lib/directives/dragdrop/dragdrop.directive.ts +++ b/projects/igniteui-angular/src/lib/directives/dragdrop/dragdrop.directive.ts @@ -572,11 +572,14 @@ export class IgxDragDirective implements OnInit, OnDestroy { /** * @hidden - * Create dragGhost element - copy of the base element. Bind all needed events. + * Create dragGhost element - if a Node object is provided it creates a clone of that node, + * otherwise it clones the host element. + * Bind all needed events. * @param event Pointer event required when the dragGhost is being initialized. + * @param node The Node object to be cloned. */ - protected createDragGhost(event) { - this._dragGhost = this.element.nativeElement.cloneNode(true); + protected createDragGhost(event, node: any = null) { + this._dragGhost = node ? node.cloneNode(true) : this.element.nativeElement.cloneNode(true); this._dragGhost.style.transitionDuration = '0.0s'; this._dragGhost.style.position = 'absolute'; this._dragGhost.style.top = this._dragStartY + 'px'; diff --git a/projects/igniteui-angular/src/lib/grids/cell.component.ts b/projects/igniteui-angular/src/lib/grids/cell.component.ts index 8c6b97dd48a..f19b67299aa 100644 --- a/projects/igniteui-angular/src/lib/grids/cell.component.ts +++ b/projects/igniteui-angular/src/lib/grids/cell.component.ts @@ -15,7 +15,7 @@ import { IgxSelectionAPIService } from '../core/selection'; import { IgxTextHighlightDirective } from '../directives/text-highlight/text-highlight.directive'; import { GridBaseAPIService } from './api.service'; import { IgxColumnComponent } from './column.component'; -import { isNavigationKey, valToPxlsUsingRange, KEYS } from '../core/utils'; +import { isNavigationKey, getNodeSizeViaRange, KEYS } from '../core/utils'; import { State } from '../services/index'; import { IgxGridBaseComponent, IGridEditEventArgs } from './grid-base.component'; import { first } from 'rxjs/operators'; @@ -380,6 +380,7 @@ export class IgxGridCellComponent implements OnInit, AfterViewInit { * @memberof IgxGridCellComponent */ @HostBinding('style.min-width') + @HostBinding('style.max-width') @HostBinding('style.flex-basis') get width() { const hasVerticalScroll = !this.grid.verticalScrollContainer.dc.instance.notVirtual; @@ -902,7 +903,7 @@ export class IgxGridCellComponent implements OnInit, AfterViewInit { */ public calculateSizeToFit(range: any): number { return Math.max(...Array.from(this.nativeElement.children) - .map((child) => valToPxlsUsingRange(range, child))); + .map((child) => getNodeSizeViaRange(range, child))); } private isToggleKey(key) { diff --git a/projects/igniteui-angular/src/lib/grids/column.component.ts b/projects/igniteui-angular/src/lib/grids/column.component.ts index 4ed4b794719..1e568415d59 100644 --- a/projects/igniteui-angular/src/lib/grids/column.component.ts +++ b/projects/igniteui-angular/src/lib/grids/column.component.ts @@ -21,15 +21,17 @@ import { IgxCellHeaderTemplateDirective, IgxCellTemplateDirective } from './grid.common'; -import { - IgxBooleanFilteringOperand, IgxNumberFilteringOperand, IgxDateFilteringOperand, - IgxStringFilteringOperand, - IgxGridBaseComponent, - FilteringExpressionsTree -} from '../../public_api'; import { IgxGridHeaderComponent } from './grid-header.component'; -import { valToPxlsUsingRange } from '../core/utils'; import { DefaultSortingStrategy, ISortingStrategy } from '../data-operations/sorting-strategy'; +import { getNodeSizeViaRange, flatten } from '../core/utils'; +import { + IgxBooleanFilteringOperand, + IgxNumberFilteringOperand, + IgxDateFilteringOperand, + IgxStringFilteringOperand } from '../data-operations/filtering-condition'; +import { IgxGridBaseComponent } from './grid-base.component'; +import { FilteringExpressionsTree } from '../data-operations/filtering-expressions-tree'; +import { IgxGridFilteringCellComponent } from './filtering/grid-filtering-cell.component'; /** * **Ignite UI for Angular Column** - @@ -304,6 +306,11 @@ export class IgxColumnComponent implements AfterContentInit { */ @Input() public headerClasses = ''; + /** + *@hidden + */ + @Input() + public headerGroupClasses = ''; /** * Sets a conditional class selector of the column cells. * Accepts an object literal, containing key-value pairs, @@ -1064,9 +1071,19 @@ export class IgxColumnComponent implements AfterContentInit { * @memberof IgxColumnComponent */ get headerCell(): IgxGridHeaderComponent { - if (this.grid.headerList.length > 0) { - return flatten(this.grid.headerList.toArray()).find((h) => h.column === this); - } + return this.grid.headerCellList.find((header) => header.column === this); + } + + /** + * Returns a reference to the filter cell of the column. + * ```typescript + * let column = this.grid.columnList.filter(c => c.field === 'ID')[0]; + * let filterell = column.filterell; + * ``` + * @memberof IgxColumnComponent + */ + get filterCell(): IgxGridFilteringCellComponent { + return this.grid.filterCellList.find((filterCell) => filterCell.column === this); } /** @@ -1109,7 +1126,7 @@ export class IgxColumnComponent implements AfterContentInit { if (this.cells[0].nativeElement.children.length > 0) { this.cells.forEach((cell) => cellsContentWidths.push(cell.calculateSizeToFit(range))); } else { - cellsContentWidths = this.cells.map((cell) => valToPxlsUsingRange(range, cell.nativeElement)); + cellsContentWidths = this.cells.map((cell) => getNodeSizeViaRange(range, cell.nativeElement)); } const index = cellsContentWidths.indexOf(Math.max(...cellsContentWidths)); @@ -1122,16 +1139,15 @@ export class IgxColumnComponent implements AfterContentInit { if (this.headerCell) { let headerCell; - const titleIndex = this.grid.hasMovableColumns ? 1 : 0; - if (this.headerTemplate && this.headerCell.elementRef.nativeElement.children[titleIndex].children.length > 0) { - headerCell = Math.max(...Array.from(this.headerCell.elementRef.nativeElement.children[titleIndex].children) - .map((child) => valToPxlsUsingRange(range, child))); + if (this.headerTemplate && this.headerCell.elementRef.nativeElement.children[0].children.length > 0) { + headerCell = Math.max(...Array.from(this.headerCell.elementRef.nativeElement.children[0].children) + .map((child) => getNodeSizeViaRange(range, child))); } else { - headerCell = valToPxlsUsingRange(range, this.headerCell.elementRef.nativeElement.children[titleIndex]); + headerCell = getNodeSizeViaRange(range, this.headerCell.elementRef.nativeElement.children[0]); } - if (this.sortable || (this.grid.allowFiltering && this.filterable)) { - headerCell += this.headerCell.elementRef.nativeElement.children[titleIndex + 1].getBoundingClientRect().width; + if (this.sortable) { + headerCell += this.headerCell.elementRef.nativeElement.children[1].getBoundingClientRect().width; } const headerStyle = this.grid.document.defaultView.getComputedStyle(this.headerCell.elementRef.nativeElement); @@ -1350,7 +1366,6 @@ export class IgxColumnGroupComponent extends IgxColumnComponent implements After if (typeof val.width === 'string' && val.width.indexOf('%') !== -1) { isChildrenWidthInPercent = true; } - return acc + parseInt(val.width, 10); }, 0)}`; return isChildrenWidthInPercent ? width + '%' : width; @@ -1358,17 +1373,3 @@ export class IgxColumnGroupComponent extends IgxColumnComponent implements After set width(val) { } } - - - -function flatten(arr: any[]) { - let result = []; - - arr.forEach(el => { - result.push(el); - if (el.children) { - result = result.concat(flatten(el.children.toArray())); - } - }); - return result; -} diff --git a/projects/igniteui-angular/src/lib/grids/filtering/grid-filtering-cell.component.html b/projects/igniteui-angular/src/lib/grids/filtering/grid-filtering-cell.component.html index c7bfec3f9d9..aade63cb526 100644 --- a/projects/igniteui-angular/src/lib/grids/filtering/grid-filtering-cell.component.html +++ b/projects/igniteui-angular/src/lib/grids/filtering/grid-filtering-cell.component.html @@ -9,8 +9,9 @@ - + - {{filteringService.getOperatorAsString(item.afterOperator)}} + {{filteringService.getOperatorAsString(item.afterOperator)}}
filter_list diff --git a/projects/igniteui-angular/src/lib/grids/filtering/grid-filtering-cell.component.ts b/projects/igniteui-angular/src/lib/grids/filtering/grid-filtering-cell.component.ts index 2276e0aedff..ffe836665ae 100644 --- a/projects/igniteui-angular/src/lib/grids/filtering/grid-filtering-cell.component.ts +++ b/projects/igniteui-angular/src/lib/grids/filtering/grid-filtering-cell.component.ts @@ -8,14 +8,15 @@ import { AfterViewInit, ElementRef, HostListener, - OnInit + OnInit, + ChangeDetectionStrategy, + DoCheck } from '@angular/core'; import { IgxColumnComponent } from '../column.component'; import { IFilteringExpression } from '../../data-operations/filtering-expression.interface'; -import { FilteringExpressionsTree } from '../../data-operations/filtering-expressions-tree'; import { IBaseChipEventArgs, IgxChipsAreaComponent, IgxChipComponent } from '../../chips'; import { IgxFilteringService, ExpressionUI } from './grid-filtering.service'; -import { KEYS, cloneArray } from '../../core/utils'; +import { KEYS } from '../../core/utils'; import { IgxGridNavigationService } from '../grid-navigation.service'; import { IgxGridGroupByRowComponent } from '../grid'; @@ -23,18 +24,17 @@ import { IgxGridGroupByRowComponent } from '../grid'; * @hidden */ @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, preserveWhitespaces: false, selector: 'igx-grid-filtering-cell', templateUrl: './grid-filtering-cell.component.html' }) -export class IgxGridFilteringCellComponent implements AfterViewInit, OnInit { +export class IgxGridFilteringCellComponent implements AfterViewInit, OnInit, DoCheck { - private rootExpressionsTree: FilteringExpressionsTree; - private expressionsList: ExpressionUI[]; private baseClass = 'igx-grid__filtering-cell-indicator'; private currentTemplate = null; - public visibleExpressionsList: ExpressionUI[]; + public expressionsList: ExpressionUI[]; public moreFiltersCount = 0; @Input() @@ -61,37 +61,9 @@ export class IgxGridFilteringCellComponent implements AfterViewInit, OnInit { @ViewChild('complexChip', { read: IgxChipComponent }) protected complexChip: IgxChipComponent; - @HostBinding('style.min-width') - @HostBinding('style.max-width') - @HostBinding('style.flex-basis') - get width() { - // HACK - think of a better solution - const colWidth = this.column.width; - const isPercentageWidth = colWidth && typeof colWidth === 'string' && colWidth.indexOf('%') !== -1; - - if (isPercentageWidth) { - const firstContentCell = this.column.cells[0]; - if (firstContentCell) { - return firstContentCell.nativeElement.getBoundingClientRect().width + 'px'; - } - } else { - return this.column.width; - } - } - @HostBinding('class.igx-grid__filtering-cell') public cssClass = 'igx-grid__filtering-cell'; - @HostBinding('class.igx-grid__th--pinned-last') - get isLastPinned() { - const pinnedCols = this.filteringService.grid.pinnedColumns; - if (pinnedCols.length === 0) { - return false; - } else { - return pinnedCols.indexOf(this.column) === pinnedCols.length - 1; - } - } - constructor(public cdr: ChangeDetectorRef, public filteringService: IgxFilteringService, public navService: IgxGridNavigationService) { this.filteringService.subscribeToEvents(); } @@ -104,6 +76,10 @@ export class IgxGridFilteringCellComponent implements AfterViewInit, OnInit { this.updateFilterCellArea(); } + public ngDoCheck() { + this.updateFilterCellArea(); + } + @HostListener('keydown.tab', ['$event']) public onTabKeyDown(eventArgs) { const pinnedColumns = this.filteringService.grid.pinnedColumns; @@ -117,6 +93,7 @@ export class IgxGridFilteringCellComponent implements AfterViewInit, OnInit { eventArgs.stopPropagation(); return; } + if (this.column.visibleIndex === this.filteringService.grid.columnList.length - 1) { if (!this.filteringService.grid.filteredData || this.filteringService.grid.filteredData.length > 0) { if (this.filteringService.grid.rowList.filter(row => row instanceof IgxGridGroupByRowComponent).length > 0) { @@ -137,10 +114,9 @@ export class IgxGridFilteringCellComponent implements AfterViewInit, OnInit { @HostListener('keydown.shift.tab', ['$event']) public onShiftTabKeyDown(eventArgs) { if (this.isFirstElementFocused()) { - const prevIndex = this.column.visibleIndex - 1 - this.filteringService.grid.pinnedColumns.length; - if (this.column.visibleIndex > 0 && !this.navService.isColumnLeftFullyVisible(this.column.visibleIndex - 1)) { eventArgs.preventDefault(); + const prevIndex = this.column.visibleIndex - 1 - this.filteringService.grid.pinnedColumns.length; this.ScrollToChip(prevIndex, false); } else if (this.column.visibleIndex === 0) { eventArgs.preventDefault(); @@ -149,6 +125,14 @@ export class IgxGridFilteringCellComponent implements AfterViewInit, OnInit { eventArgs.stopPropagation(); } + /** + * Returns whether a chip with a given index is visible or not. + */ + public isChipVisible(index: number) { + const expression = this.expressionsList[index]; + return !!(expression && expression.isVisible); + } + /** * Updates the filtering cell area. */ @@ -261,13 +245,7 @@ export class IgxGridFilteringCellComponent implements AfterViewInit, OnInit { this.filteringService.removeExpression(this.column.field, indexToRemove); this.updateVisibleFilters(); - this.filter(); - } - - private filter(): void { - this.rootExpressionsTree = this.filteringService.createSimpleFilteringTree(this.column.field); - - this.filteringService.filter(this.column.field, this.rootExpressionsTree); + this.filteringService.filter(this.column.field); } private isMoreIconHidden(): boolean { @@ -275,21 +253,20 @@ export class IgxGridFilteringCellComponent implements AfterViewInit, OnInit { } private updateVisibleFilters() { - this.visibleExpressionsList = cloneArray(this.expressionsList); - - // TODO: revise the usage of this.cdr.detectChanges() here - this.cdr.detectChanges(); + this.expressionsList.forEach((ex) => ex.isVisible = true); if (this.moreIcon) { this.filteringService.columnToMoreIconHidden.set(this.column.field, true); } + this.cdr.detectChanges(); + if (this.chipsArea && this.expressionsList.length > 1) { const areaWidth = this.chipsArea.element.nativeElement.offsetWidth; let viewWidth = 0; const chipsAreaElements = this.chipsArea.element.nativeElement.children; let visibleChipsCount = 0; const moreIconWidth = this.moreIcon.nativeElement.offsetWidth - - parseInt(document.defaultView.getComputedStyle(this.moreIcon.nativeElement)['margin-left'], 10); + parseInt(document.defaultView.getComputedStyle(this.moreIcon.nativeElement)['margin-left'], 10); for (let index = 0; index < chipsAreaElements.length - 1; index++) { if (viewWidth + chipsAreaElements[index].offsetWidth < areaWidth) { @@ -308,10 +285,13 @@ export class IgxGridFilteringCellComponent implements AfterViewInit, OnInit { } this.moreFiltersCount = this.expressionsList.length - visibleChipsCount; this.filteringService.columnToMoreIconHidden.set(this.column.field, false); - this.visibleExpressionsList.splice(visibleChipsCount); break; } } + + for (let i = visibleChipsCount; i < this.expressionsList.length; i++) { + this.expressionsList[i].isVisible = false; + } this.cdr.detectChanges(); } } diff --git a/projects/igniteui-angular/src/lib/grids/filtering/grid-filtering-row.component.ts b/projects/igniteui-angular/src/lib/grids/filtering/grid-filtering-row.component.ts index 336374a9058..c1f1e3c3556 100644 --- a/projects/igniteui-angular/src/lib/grids/filtering/grid-filtering-row.component.ts +++ b/projects/igniteui-angular/src/lib/grids/filtering/grid-filtering-row.component.ts @@ -5,12 +5,12 @@ import { Input, TemplateRef, ViewChild, - OnDestroy, ViewChildren, QueryList, ElementRef, HostBinding, - HostListener + HostListener, + ChangeDetectionStrategy } from '@angular/core'; import { Subject } from 'rxjs'; import { DataType } from '../../data-operations/data-util'; @@ -20,7 +20,6 @@ import { IFilteringOperation } from '../../data-operations/filtering-condition'; import { FilteringLogic, IFilteringExpression } from '../../data-operations/filtering-expression.interface'; import { HorizontalAlignment, VerticalAlignment, OverlaySettings } from '../../services/overlay/utilities'; import { ConnectedPositioningStrategy } from '../../services/overlay/position/connected-positioning-strategy'; -import { FilteringExpressionsTree } from '../../data-operations/filtering-expressions-tree'; import { IChipSelectEventArgs, IBaseChipEventArgs, IgxChipsAreaComponent, IgxChipComponent } from '../../chips'; import { ExpressionUI } from './grid-filtering.service'; import { IgxDropDownItemComponent } from '../../drop-down/drop-down-item.component'; @@ -32,11 +31,12 @@ import { AbsoluteScrollStrategy } from '../../services/overlay/scroll'; * @hidden */ @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, preserveWhitespaces: false, selector: 'igx-grid-filtering-row', templateUrl: './grid-filtering-row.component.html' }) -export class IgxGridFilteringRowComponent implements AfterViewInit, OnDestroy { +export class IgxGridFilteringRowComponent implements AfterViewInit { private _positionSettings = { horizontalStartPoint: HorizontalAlignment.Left, @@ -57,11 +57,8 @@ export class IgxGridFilteringRowComponent implements AfterViewInit, OnDestroy { positionStrategy: new ConnectedPositioningStrategy(this._positionSettings) }; - private rootExpressionsTree: FilteringExpressionsTree; private chipsAreaWidth: number; private chipAreaScrollOffset = 0; - private conditionChanged = new Subject(); - private unaryConditionChanged = new Subject(); private _column = null; public showArrows: boolean; @@ -141,10 +138,7 @@ export class IgxGridFilteringRowComponent implements AfterViewInit, OnDestroy { @HostBinding('class.igx-grid__filtering-row') public cssClass = 'igx-grid__filtering-row'; - constructor(public filteringService: IgxFilteringService, public element: ElementRef, public cdr: ChangeDetectorRef) { - this.unaryConditionChanged.subscribe(() => this.unaryConditionChangedCallback()); - this.conditionChanged.subscribe(() => this.conditionChangedCallback()); - } + constructor(public filteringService: IgxFilteringService, public element: ElementRef, public cdr: ChangeDetectorRef) {} ngAfterViewInit() { this._conditionsOverlaySettings.outlet = this.column.grid.outletDirective; @@ -158,11 +152,6 @@ export class IgxGridFilteringRowComponent implements AfterViewInit, OnDestroy { this.input.nativeElement.focus(); } - ngOnDestroy() { - this.conditionChanged.unsubscribe(); - this.unaryConditionChanged.unsubscribe(); - } - @HostListener('keydown.shift.tab', ['$event']) @HostListener('keydown.tab', ['$event']) public onTabKeydown(event) { @@ -378,8 +367,8 @@ export class IgxGridFilteringRowComponent implements AfterViewInit, OnDestroy { }); } - this.filteringService.updateFilteringCell(this.column.field); - this.filteringService.focusFilterCellChip(this.column.field, true); + this.filteringService.updateFilteringCell(this.column); + this.filteringService.focusFilterCellChip(this.column, true); this.filteringService.isFilterRowVisible = false; this.filteringService.filteredColumn = null; @@ -422,9 +411,11 @@ export class IgxGridFilteringRowComponent implements AfterViewInit, OnDestroy { const value = (eventArgs.newSelection as IgxDropDownItemComponent).value; this.expression.condition = this.getCondition(value); if (this.expression.condition.isUnary) { - this.unaryConditionChanged.next(value); + // update grid's filtering on the next cycle to ensure the drop-down is closed + // if the drop-down is not closed this event handler will be invoked multiple times + requestAnimationFrame(() => this.unaryConditionChangedCallback()); } else { - this.conditionChanged.next(value); + requestAnimationFrame(() => this.conditionChangedCallback()); } if (this.input) { @@ -491,7 +482,10 @@ export class IgxGridFilteringRowComponent implements AfterViewInit, OnDestroy { if (eventArgs.oldSelection) { expression.afterOperator = (eventArgs.newSelection as IgxDropDownItemComponent).value; this.expressionsList[this.expressionsList.indexOf(expression) + 1].beforeOperator = expression.afterOperator; - this.filter(); + + // update grid's filtering on the next cycle to ensure the drop-down is closed + // if the drop-down is not closed this event handler will be invoked multiple times + requestAnimationFrame(() => this.filter()); } } @@ -667,8 +661,6 @@ export class IgxGridFilteringRowComponent implements AfterViewInit, OnDestroy { } private filter() { - this.rootExpressionsTree = this.filteringService.createSimpleFilteringTree(this.column.field); - - this.filteringService.filter(this.column.field, this.rootExpressionsTree); + this.filteringService.filter(this.column.field); } } diff --git a/projects/igniteui-angular/src/lib/grids/filtering/grid-filtering.service.ts b/projects/igniteui-angular/src/lib/grids/filtering/grid-filtering.service.ts index 31c5327ef04..26b93422719 100644 --- a/projects/igniteui-angular/src/lib/grids/filtering/grid-filtering.service.ts +++ b/projects/igniteui-angular/src/lib/grids/filtering/grid-filtering.service.ts @@ -10,6 +10,7 @@ import { takeUntil } from 'rxjs/operators'; import { IForOfState } from '../../directives/for-of/for_of.directive'; import { IgxGridFilterConditionPipe } from '../grid-common.pipes'; import { TitleCasePipe, DatePipe } from '@angular/common'; +import { IgxColumnComponent } from '../grid'; const FILTERING_ICONS_FONT_SET = 'filtering-icons'; @@ -21,6 +22,7 @@ export class ExpressionUI { public beforeOperator: FilteringLogic; public afterOperator: FilteringLogic; public isSelected = false; + public isVisible = true; } /** @@ -41,9 +43,9 @@ export class IgxFilteringService implements OnDestroy { public gridId: string; public isFilterRowVisible = false; - public filteredColumn = null; + public filteredColumn: IgxColumnComponent = null; public selectedExpression: IFilteringExpression = null; - public columnToFocus = null; + public columnToFocus: IgxColumnComponent = null; public shouldFocusNext = false; public columnToMoreIconHidden = new Map(); @@ -66,7 +68,7 @@ export class IgxFilteringService implements OnDestroy { this.areEventsSubscribed = true; this.grid.onColumnResized.pipe(takeUntil(this.destroy$)).subscribe((eventArgs: IColumnResizeEventArgs) => { - this.updateFilteringCell(eventArgs.column.field); + this.updateFilteringCell(eventArgs.column); }); this.grid.parentVirtDir.onChunkLoad.pipe(takeUntil(this.destroy$)).subscribe((eventArgs: IForOfState) => { @@ -77,7 +79,7 @@ export class IgxFilteringService implements OnDestroy { }); } if (this.columnToFocus) { - this.focusFilterCellChip(this.columnToFocus.field, false); + this.focusFilterCellChip(this.columnToFocus, false); this.columnToFocus = null; } }); @@ -93,9 +95,10 @@ export class IgxFilteringService implements OnDestroy { /** * Execute filtering on the grid. */ - public filter(field: string, expressionsTree: FilteringExpressionsTree): void { + public filter(field: string): void { this.isFiltering = true; + const expressionsTree = this.createSimpleFilteringTree(field); this.grid.filter(field, null, expressionsTree); // Wait for the change detection to update filtered data through the pipes and then emit the event. @@ -169,7 +172,7 @@ export class IgxFilteringService implements OnDestroy { this.columnsWithComplexFilter.add(key); } - this.updateFilteringCell(key); + this.updateFilteringCell(column); }); } } @@ -272,8 +275,8 @@ export class IgxFilteringService implements OnDestroy { /** * Updates the content of a filterCell. */ - public updateFilteringCell(columnId: string) { - const filterCell = this.grid.filterCellList.find(cell => cell.column.field === columnId); + public updateFilteringCell(column: IgxColumnComponent) { + const filterCell = column.filterCell; if (filterCell) { filterCell.updateFilterCellArea(); } @@ -282,8 +285,8 @@ export class IgxFilteringService implements OnDestroy { /** * Focus a chip in a filterCell. */ - public focusFilterCellChip(columnId: string, focusFirst: boolean) { - const filterCell = this.grid.filterCellList.find(cell => cell.column.field === columnId); + public focusFilterCellChip(column: IgxColumnComponent, focusFirst: boolean) { + const filterCell = column.filterCell; if (filterCell) { filterCell.focusChip(focusFirst); } diff --git a/projects/igniteui-angular/src/lib/grids/grid-base.component.ts b/projects/igniteui-angular/src/lib/grids/grid-base.component.ts index 67257c29f62..ac37956d5bc 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-base.component.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-base.component.ts @@ -28,7 +28,7 @@ import { import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { IgxSelectionAPIService } from '../core/selection'; -import { cloneArray, isNavigationKey, mergeObjects, CancelableEventArgs } from '../core/utils'; +import { cloneArray, isNavigationKey, mergeObjects, CancelableEventArgs, flatten } from '../core/utils'; import { DataType, DataUtil } from '../data-operations/data-util'; import { FilteringLogic, IFilteringExpression } from '../data-operations/filtering-expression.interface'; import { IGroupByRecord } from '../data-operations/groupby-record.interface'; @@ -61,6 +61,7 @@ import { IDisplayDensityOptions, DisplayDensityToken, DisplayDensityBase } from import { IgxGridRowComponent } from './grid'; import { IgxFilteringService } from './filtering/grid-filtering.service'; import { IgxGridFilteringCellComponent } from './filtering/grid-filtering-cell.component'; +import { IgxGridHeaderGroupComponent } from './grid-header-group.component'; const MINIMUM_COLUMN_WIDTH = 136; @@ -242,7 +243,7 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements this.filteringService.refreshExpressions(); this.clearSummaryCache(); - this.cdr.markForCheck(); + this.markForCheck(); } } @@ -1153,14 +1154,41 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements /** * @hidden */ - @ViewChildren(IgxGridHeaderComponent, { read: IgxGridHeaderComponent }) - public headerList: QueryList; + @ViewChildren(IgxGridHeaderGroupComponent, { read: IgxGridHeaderGroupComponent }) + public headerGroups: QueryList; /** - * @hidden + * A list of all `IgxGridHeaderGroupComponent`. + * ```typescript + * const headerGroupsList = this.grid.headerGroupsList; + * ``` + * @memberof IgxGridBaseComponent + */ + get headerGroupsList(): IgxGridHeaderGroupComponent[] { + return this.headerGroups ? flatten(this.headerGroups.toArray()) : []; + } + + /** + * A list of all `IgxGridHeaderComponent`. + * ```typescript + * const headers = this.grid.headerCellList; + * ``` + * @memberof IgxGridBaseComponent + */ + get headerCellList(): IgxGridHeaderComponent[] { + return this.headerGroupsList.map((headerGroup) => headerGroup.headerCell).filter((headerCell) => headerCell); + } + + /** + * A list of all `IgxGridFilteringCellComponent`. + * ```typescript + * const filterCells = this.grid.filterCellList; + * ``` + * @memberof IgxGridBaseComponent */ - @ViewChildren(IgxGridFilteringCellComponent, { read: IgxGridFilteringCellComponent }) - public filterCellList: QueryList; + get filterCellList(): IgxGridFilteringCellComponent[] { + return this.headerGroupsList.map((headerGroup) => headerGroup.filterCell).filter((filterCell) => filterCell); + } @ViewChildren('row') private _rowList: QueryList; @@ -1881,14 +1909,6 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements * @hidden */ public draggedColumn: IgxColumnComponent; - /** - * @hidden - */ - public isColumnResizing: boolean; - /** - * @hidden - */ - public isColumnMoving: boolean; /** * @hidden @@ -2264,6 +2284,17 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements return this.theadRow.nativeElement.clientHeight + this.tbody.nativeElement.clientHeight; } + /** + * @hidden + */ + get headerCheckboxWidth() { + if (this.headerCheckboxContainer) { + return this.headerCheckboxContainer.nativeElement.clientWidth; + } + + return 0; + } + /** * Returns the `IgxGridComponent`'s rows height. * ```typescript @@ -2733,6 +2764,11 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements if (this.rowList) { this.rowList.forEach((row) => row.cdr.markForCheck()); } + + if (this.filterCellList) { + this.filterCellList.forEach((c) => c.cdr.markForCheck()); + } + this.cdr.detectChanges(); } diff --git a/projects/igniteui-angular/src/lib/grids/grid-column-resizing.service.ts b/projects/igniteui-angular/src/lib/grids/grid-column-resizing.service.ts new file mode 100644 index 00000000000..a5eac5e8ed2 --- /dev/null +++ b/projects/igniteui-angular/src/lib/grids/grid-column-resizing.service.ts @@ -0,0 +1,160 @@ +import { Injectable } from '@angular/core'; +import { isFirefox } from '../core/utils'; +import { IgxColumnComponent } from './column.component'; + +/** @hidden */ +@Injectable() +export class IgxColumnResizingService { + + private pinnedMaxWidth: string; + + /** + *@hidden + */ + public startResizePos: number; + /** + * Indicates that a column is currently being resized. + */ + public isColumnResizing: boolean; + /** + *@hidden + */ + public resizeCursor: string = null; + /** + *@hidden + */ + public showResizer = false; + /** + *@hidden + */ + public resizerHeight: number; + /** + *@hidden + */ + public resizeEndTimeout = isFirefox() ? 200 : 0; + /** + * The column being resized. + */ + public column: IgxColumnComponent; + + + /** + * Returns the minimal possible width to which the column can be resized. + */ + get restrictResizeMin(): number { + const actualMinWidth = parseFloat(this.column.minWidth); + const defaultMinWidth = parseFloat(this.column.defaultMinWidth); + + let minWidth = Number.isNaN(actualMinWidth) || actualMinWidth < defaultMinWidth ? defaultMinWidth : actualMinWidth; + minWidth = minWidth < parseFloat(this.column.width) ? minWidth : parseFloat(this.column.width); + + return minWidth - this.column.headerCell.elementRef.nativeElement.getBoundingClientRect().width; + } + + /** + * Returns the maximal possible width to which the column can be resized. + */ + get restrictResizeMax(): number { + const actualWidth = this.column.headerCell.elementRef.nativeElement.getBoundingClientRect().width; + + if (this.column.pinned) { + const pinnedMaxWidth = this.pinnedMaxWidth = + this.column.grid.calcPinnedContainerMaxWidth - this.column.grid.getPinnedWidth(true) + actualWidth; + + if (this.column.maxWidth && parseFloat(this.column.maxWidth) < pinnedMaxWidth) { + this.pinnedMaxWidth = this.column.maxWidth; + + return parseFloat(this.column.maxWidth) - actualWidth; + } else { + return pinnedMaxWidth - actualWidth; + } + } else { + if (this.column.maxWidth) { + return parseFloat(this.column.maxWidth) - actualWidth; + } else { + return Number.MAX_SAFE_INTEGER; + } + } + } + + /** + * Autosizes the column to the longest currently visible cell value, including the header cell. + * If the column has a predifined maxWidth and the autosized column width will become bigger than it, + * then the column is sized to its maxWidth. + * If the column is pinned and the autosized column width will cause the pinned area to become bigger + * than the maximum allowed pinned area width (80% of the total grid width), autosizing will be deismissed. + */ + public autosizeColumnOnDblClick() { + if (this.column.resizable) { + const currentColWidth = this.column.headerCell.elementRef.nativeElement.getBoundingClientRect().width; + + const size = this.column.getLargestCellWidth(); + + if (this.column.pinned) { + const newPinnedWidth = this.column.grid.getPinnedWidth(true) - currentColWidth + parseFloat(size); + + if (newPinnedWidth <= this.column.grid.calcPinnedContainerMaxWidth) { + this.column.width = size; + } + } else if (this.column.maxWidth && (parseFloat(size) > parseFloat(this.column.maxWidth))) { + this.column.width = parseFloat(this.column.maxWidth) + 'px'; + } else if (parseFloat(size) < parseFloat(this.column.defaultMinWidth)) { + this.column.width = this.column.defaultMinWidth + 'px'; + } else { + this.column.width = size; + } + + this.column.grid.markForCheck(); + this.column.grid.reflow(); + this.column.grid.onColumnResized.emit({ + column: this.column, + prevWidth: currentColWidth.toString(), + newWidth: this.column.width + }); + } + } + + /** + * Resizes the column regaridng to the column minWidth and maxWidth. + */ + public resizeColumn(event: MouseEvent) { + this.isColumnResizing = false; + + this.showResizer = false; + const diff = event.clientX - this.startResizePos; + + if (this.column.resizable) { + let currentColWidth = parseFloat(this.column.width); + + const actualMinWidth = parseFloat(this.column.minWidth); + const defaultMinWidth = parseFloat(this.column.defaultMinWidth); + + let colMinWidth = Number.isNaN(actualMinWidth) || actualMinWidth < defaultMinWidth ? defaultMinWidth : actualMinWidth; + const colMaxWidth = this.column.pinned ? parseFloat(this.pinnedMaxWidth) : parseFloat(this.column.maxWidth); + + const actualWidth = this.column.headerCell.elementRef.nativeElement.getBoundingClientRect().width; + + currentColWidth = Number.isNaN(currentColWidth) || (currentColWidth < actualWidth) ? actualWidth : currentColWidth; + colMinWidth = colMinWidth < currentColWidth ? colMinWidth : currentColWidth; + + if (currentColWidth + diff < colMinWidth) { + this.column.width = colMinWidth + 'px'; + } else if (colMaxWidth && (currentColWidth + diff > colMaxWidth)) { + this.column.width = colMaxWidth + 'px'; + } else { + this.column.width = (currentColWidth + diff) + 'px'; + } + + this.column.grid.markForCheck(); + this.column.grid.reflow(); + + if (currentColWidth !== parseFloat(this.column.width)) { + this.column.grid.onColumnResized.emit({ + column: this.column, + prevWidth: currentColWidth.toString(), + newWidth: this.column.width + }); + } + } + } +} diff --git a/projects/igniteui-angular/src/lib/grids/grid-common.module.ts b/projects/igniteui-angular/src/lib/grids/grid-common.module.ts index c453f53ab72..af3d1392672 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-common.module.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-common.module.ts @@ -55,6 +55,8 @@ import { IgxRowEditTabStopDirective } from './grid.rowEdit.directive'; import { IgxGridNavigationService } from './grid-navigation.service'; +import { IgxGridHeaderGroupComponent } from './grid-header-group.component'; +import { IgxColumnResizingService } from './grid-column-resizing.service'; @NgModule({ declarations: [ @@ -81,8 +83,8 @@ import { IgxGridNavigationService } from './grid-navigation.service'; IgxGridFilteringRowComponent, IgxDatePipeComponent, IgxDecimalPipeComponent, - IgxRowComponent - + IgxRowComponent, + IgxGridHeaderGroupComponent ], entryComponents: [ IgxColumnComponent, @@ -132,6 +134,7 @@ import { IgxGridNavigationService } from './grid-navigation.service'; IgxColumnPinningModule, IgxGridFilteringCellComponent, IgxGridFilteringRowComponent, + IgxGridHeaderGroupComponent ], imports: [ CommonModule, @@ -160,6 +163,7 @@ import { IgxGridNavigationService } from './grid-navigation.service'; IgxSelectionAPIService, IgxColumnMovingService, IgxGridNavigationService, + IgxColumnResizingService, { provide: IgxGridTransaction, useClass: IgxBaseTransactionService } ] }) diff --git a/projects/igniteui-angular/src/lib/grids/grid-header-group.component.html b/projects/igniteui-angular/src/lib/grids/grid-header-group.component.html new file mode 100644 index 00000000000..42058a79ce7 --- /dev/null +++ b/projects/igniteui-angular/src/lib/grids/grid-header-group.component.html @@ -0,0 +1,42 @@ + + +
{{ column.header }}
+
+ + + + +
+ +
+ + + + + + +
+
+
+ +
diff --git a/projects/igniteui-angular/src/lib/grids/grid-header-group.component.ts b/projects/igniteui-angular/src/lib/grids/grid-header-group.component.ts new file mode 100644 index 00000000000..bd9981d6058 --- /dev/null +++ b/projects/igniteui-angular/src/lib/grids/grid-header-group.component.ts @@ -0,0 +1,213 @@ +import { + Component, + HostBinding, + Input, + ViewChild, + QueryList, + ViewChildren, + forwardRef, + ChangeDetectionStrategy, + ChangeDetectorRef, + DoCheck +} from '@angular/core'; +import { IgxColumnComponent } from './column.component'; +import { IgxFilteringService } from './filtering/grid-filtering.service'; +import { GridBaseAPIService } from './api.service'; +import { IgxGridBaseComponent } from './grid-base.component'; +import { IgxColumnResizingService } from './grid-column-resizing.service'; +import { IgxGridHeaderComponent } from './grid-header.component'; +import { IgxGridFilteringCellComponent } from './filtering/grid-filtering-cell.component'; + +const Z_INDEX = 9999; + +/** + * @hidden + */ +@Component({ + changeDetection: ChangeDetectionStrategy.OnPush, + preserveWhitespaces: false, + selector: 'igx-grid-header-group', + templateUrl: './grid-header-group.component.html' +}) +export class IgxGridHeaderGroupComponent implements DoCheck { + + /** + * Gets the column of the header group. + * @memberof IgxGridHeaderGroupComponent + */ + @Input() + public column: IgxColumnComponent; + + /** + * Gets the `id` of the grid in which the header group is stored. + * @memberof IgxGridHeaderGroupComponent + */ + @Input() + public gridID: string; + + /** + * @hidden + */ + @ViewChild(IgxGridHeaderComponent) + public headerCell: IgxGridHeaderComponent; + + /** + * @hidden + */ + @ViewChild(IgxGridFilteringCellComponent) + public filterCell: IgxGridFilteringCellComponent; + + /** + * @hidden + */ + @ViewChildren(forwardRef(() => IgxGridHeaderGroupComponent), { read: IgxGridHeaderGroupComponent }) + public children: QueryList; + + /** + * Gets the width of the header group. + * @memberof IgxGridHeaderGroupComponent + */ + @HostBinding('style.min-width') + @HostBinding('style.flex-basis') + get width() { + return this.column.width; + } + + /** + * Gets the style classes of the header group. + * @memberof IgxGridHeaderGroupComponent + */ + @HostBinding('class') + get styleClasses(): string { + const defaultClasses = [ + 'igx-grid__thead-item', + this.column.headerGroupClasses + ]; + + const classList = { + 'igx-grid__th--pinned': this.isPinned, + 'igx-grid__th--pinned-last': this.isLastPinned, + 'igx-grid__drag-col-header': this.isHeaderDragged, + 'igx-grid__th--filtering': this.isFiltered + }; + + Object.entries(classList).forEach(([className, value]) => { + if (value) { + defaultClasses.push(className); + } + }); + return defaultClasses.join(' '); + } + + /** + * @hidden + */ + @HostBinding('style.z-index') + get zIndex() { + if (!this.column.pinned) { + return null; + } + return Z_INDEX - this.grid.pinnedColumns.indexOf(this.column); + } + + /** + * Gets the grid of the header group. + * @memberof IgxGridHeaderGroupComponent + */ + get grid(): any { + return this.gridAPI.get(this.gridID); + } + + /** + * Gets whether the header group belongs to a column that is filtered. + * @memberof IgxGridHeaderGroupComponent + */ + get isFiltered(): boolean { + return this.filteringService.filteredColumn === this.column; + } + + /** + * Gets whether the header group is stored in the last column in the pinned area. + * @memberof IgxGridHeaderGroupComponent + */ + get isLastPinned(): boolean { + const pinnedCols = this.grid.pinnedColumns; + + if (pinnedCols.length === 0) { + return false; + } + + return pinnedCols.indexOf(this.column) === pinnedCols.length - 1; + } + + /** + * Gets whether the header group is stored in a pinned column. + * @memberof IgxGridHeaderGroupComponent + */ + get isPinned(): boolean { + return this.column.pinned; + } + + /** + * Gets whether the header group belongs to a column that is moved. + * @memberof IgxGridHeaderGroupComponent + */ + get isHeaderDragged(): boolean { + return this.grid.draggedColumn === this.column; + } + + /** + * @hidden + */ + get hasLastPinnedChildColumn(): boolean { + const pinnedCols = this.grid.pinnedColumns; + if (this.column.allChildren) { + return this.column.allChildren.some((child) => { + return pinnedCols.length > 0 && pinnedCols.indexOf(child) === pinnedCols.length - 1; + }); + } + } + + public ngDoCheck() { + this.cdr.markForCheck(); + } + + constructor(private cdr: ChangeDetectorRef, + public gridAPI: GridBaseAPIService, + public colResizingService: IgxColumnResizingService, + public filteringService: IgxFilteringService) { } + + /** + * @hidden + */ + public onResizeAreaMouseOver() { + if (this.column.resizable) { + this.colResizingService.resizeCursor = 'col-resize'; + } + } + + /** + * @hidden + */ + public onResizeAreaMouseDown(event) { + if (event.button === 0 && this.column.resizable) { + this.colResizingService.column = this.column; + this.colResizingService.showResizer = true; + this.colResizingService.isColumnResizing = true; + this.colResizingService.resizerHeight = this.column.grid.calcResizerHeight; + this.colResizingService.startResizePos = event.clientX; + } else { + this.colResizingService.resizeCursor = null; + } + } + + /** + * @hidden + */ + public autosizeColumnOnDblClick(event) { + if (event.button === 0 && this.column.resizable) { + this.colResizingService.column = this.column; + this.colResizingService.autosizeColumnOnDblClick(); + } + } +} diff --git a/projects/igniteui-angular/src/lib/grids/grid-header.component.html b/projects/igniteui-angular/src/lib/grids/grid-header.component.html index b1d1d032c98..67d857a69a9 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-header.component.html +++ b/projects/igniteui-angular/src/lib/grids/grid-header.component.html @@ -2,49 +2,11 @@ {{ column.header || column.field }} - - -
{{ column.header }}
-
- -
- - -
-
-
- -
- - - - - - - - -
- {{sortingIcon}} - -
- - - -
-
- -
- - - -
+ + + + +
+ {{sortingIcon}} +
diff --git a/projects/igniteui-angular/src/lib/grids/grid-header.component.ts b/projects/igniteui-angular/src/lib/grids/grid-header.component.ts index 216225c4d59..718532aecf8 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-header.component.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-header.component.ts @@ -1,5 +1,4 @@ import { - AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, @@ -9,22 +8,15 @@ import { HostListener, Input, NgZone, - OnInit, - ViewChild, - QueryList, - ViewChildren, - OnDestroy + OnInit } from '@angular/core'; import { DataType } from '../data-operations/data-util'; import { SortingDirection } from '../data-operations/sorting-expression.interface'; -import { RestrictDrag } from '../directives/dragdrop/dragdrop.directive'; import { GridBaseAPIService } from './api.service'; import { IgxColumnComponent } from './column.component'; -import { IgxColumnMovingService } from './grid.common'; -import { isFirefox } from '../core/utils'; import { IgxGridBaseComponent } from './grid-base.component'; import { IgxFilteringService } from './filtering/grid-filtering.service'; -import { IgxGridComponent } from './grid'; +import { IgxColumnResizingService } from './grid-column-resizing.service'; /** * @hidden @@ -35,7 +27,7 @@ import { IgxGridComponent } from './grid'; selector: 'igx-grid-header', templateUrl: './grid-header.component.html' }) -export class IgxGridHeaderComponent implements OnInit, DoCheck, AfterViewInit, OnDestroy { +export class IgxGridHeaderComponent implements OnInit, DoCheck { @Input() public column: IgxColumnComponent; @@ -55,10 +47,7 @@ export class IgxGridHeaderComponent implements OnInit, DoCheck, AfterViewInit, O 'asc': this.ascending, 'desc': this.descending, 'igx-grid__th--number': this.column.dataType === DataType.Number, - 'igx-grid__th--sorted': this.sorted, - 'igx-grid__drag-col-header': this.dragged, - 'igx-grid__th--pinned-last': this.isLastPinned, - 'igx-grid__th--filtering': this.filteringService.filteredColumn === this.column + 'igx-grid__th--sorted': this.sorted }; Object.entries(classList).forEach(([klass, value]) => { @@ -69,25 +58,6 @@ export class IgxGridHeaderComponent implements OnInit, DoCheck, AfterViewInit, O return defaultClasses.join(' '); } - - @HostBinding('style.min-width') - @HostBinding('style.max-width') - @HostBinding('style.flex-basis') - get width() { - // HACK - think of a better solution - const colWidth = this.column.width; - const isPercentageWidth = colWidth && typeof colWidth === 'string' && colWidth.indexOf('%') !== -1; - - if (isPercentageWidth) { - const firstContentCell = this.column.cells[0]; - if (firstContentCell) { - return firstContentCell.nativeElement.getBoundingClientRect().width + 'px'; - } - } else { - return this.column.width; - } - } - @HostBinding('style.height.px') get height() { if (this.grid.hasColumnGroups) { @@ -121,14 +91,6 @@ export class IgxGridHeaderComponent implements OnInit, DoCheck, AfterViewInit, O return this.column === this.column.grid.draggedColumn; } - @HostBinding('style.z-index') - get zIndex() { - if (!this.column.pinned) { - return null; - } - return 9999 - this.grid.pinnedColumns.indexOf(this.column); - } - @HostBinding('attr.role') public hostRole = 'columnheader'; @@ -140,29 +102,14 @@ export class IgxGridHeaderComponent implements OnInit, DoCheck, AfterViewInit, O return `${this.gridID}_${this.column.field}`; } - @ViewChild('resizeArea') - public resizeArea: ElementRef; - - @ViewChildren(IgxGridHeaderComponent, { read: IgxGridHeaderComponent }) - public children: QueryList; - - public resizeCursor = null; - public showResizer = false; - public resizerHeight; - public dragDirection: RestrictDrag = RestrictDrag.HORIZONTALLY; - public resizeEndTimeout = isFirefox() ? 200 : 0; - protected sortDirection = SortingDirection.None; - private _startResizePos; - private _pinnedMaxWidth; - constructor( public gridAPI: GridBaseAPIService, + public colResizingService: IgxColumnResizingService, public cdr: ChangeDetectorRef, public elementRef: ElementRef, public zone: NgZone, - private cms: IgxColumnMovingService, public filteringService: IgxFilteringService ) { } @@ -176,29 +123,9 @@ export class IgxGridHeaderComponent implements OnInit, DoCheck, AfterViewInit, O this.cdr.markForCheck(); } - ngAfterViewInit() { - if (!this.column.columnGroup) { - this.zone.runOutsideAngular(() => { - this.resizeArea.nativeElement.addEventListener('mouseover', this.onResizeAreaMouseOver.bind(this)); - this.resizeArea.nativeElement.addEventListener('mousedown', this.onResizeAreaMouseDown.bind(this)); - this.resizeArea.nativeElement.addEventListener('dblclick', this.onResizeAreaDblClick.bind(this)); - }); - } - } - - ngOnDestroy() { - if (!this.column.columnGroup) { - this.zone.runOutsideAngular(() => { - this.resizeArea.nativeElement.removeEventListener('mouseover', this.onResizeAreaMouseOver); - this.resizeArea.nativeElement.removeEventListener('mousedown', this.onResizeAreaMouseDown); - this.resizeArea.nativeElement.removeEventListener('dblclick', this.onResizeAreaDblClick); - }); - } - } - @HostListener('click', ['$event']) public onClick(event) { - if (!this.column.grid.isColumnResizing) { + if (!this.colResizingService.isColumnResizing) { event.stopPropagation(); if (this.grid.filteringService.isFilterRowVisible) { if (this.column.filterable && !this.column.columnGroup && @@ -224,140 +151,12 @@ export class IgxGridHeaderComponent implements OnInit, DoCheck, AfterViewInit, O } } - get restrictResizeMin(): number { - const actualMinWidth = parseFloat(this.column.minWidth); - const defaultMinWidth = parseFloat(this.column.defaultMinWidth); - - let minWidth = Number.isNaN(actualMinWidth) || actualMinWidth < defaultMinWidth ? defaultMinWidth : actualMinWidth; - minWidth = minWidth < parseFloat(this.column.width) ? minWidth : parseFloat(this.column.width); - - return minWidth - this.elementRef.nativeElement.getBoundingClientRect().width; - } - - get restrictResizeMax(): number { - const actualWidth = this.elementRef.nativeElement.getBoundingClientRect().width; - - if (this.column.pinned) { - const pinnedMaxWidth = this._pinnedMaxWidth = - this.grid.calcPinnedContainerMaxWidth - this.grid.getPinnedWidth(true) + actualWidth; - - if (this.column.maxWidth && parseFloat(this.column.maxWidth) < pinnedMaxWidth) { - this._pinnedMaxWidth = this.column.maxWidth; - - return parseFloat(this.column.maxWidth) - actualWidth; - } else { - return pinnedMaxWidth - actualWidth; - } - } else { - if (this.column.maxWidth) { - return parseFloat(this.column.maxWidth) - actualWidth; - } else { - return Number.MAX_SAFE_INTEGER; - } - } - } - get grid(): any { return this.gridAPI.get(this.gridID); } - get isPinned() { - return this.column.pinned; - } - - get isLastPinned() { - const pinnedCols = this.grid.pinnedColumns; - if (pinnedCols.length === 0) { - return false; - } else { - return pinnedCols.indexOf(this.column) === pinnedCols.length - 1; - } - } - protected getSortDirection() { const expr = this.gridAPI.get(this.gridID).sortingExpressions.find((x) => x.fieldName === this.column.field); this.sortDirection = expr ? expr.dir : SortingDirection.None; } - - private onResizeAreaMouseOver() { - if (this.column.resizable) { - this.resizeCursor = 'col-resize'; - this.cdr.detectChanges(); - } - } - - private onResizeAreaMouseDown(event) { - if (event.button === 0 && this.column.resizable) { - this.showResizer = true; - this.column.grid.isColumnResizing = true; - this.resizerHeight = this.grid.calcResizerHeight; - this._startResizePos = event.clientX; - } else { - this.resizeCursor = null; - } - this.cdr.detectChanges(); - } - - private onResizeAreaDblClick() { - if (this.column.resizable) { - const currentColWidth = this.elementRef.nativeElement.getBoundingClientRect().width; - - const size = this.column.getLargestCellWidth(); - - if (this.column.pinned) { - const newPinnedWidth = this.grid.getPinnedWidth(true) - currentColWidth + parseFloat(size); - - if (newPinnedWidth <= this.grid.calcPinnedContainerMaxWidth) { - this.column.width = size; - } - } else if (this.column.maxWidth && (parseFloat(size) > parseFloat(this.column.maxWidth))) { - this.column.width = parseFloat(this.column.maxWidth) + 'px'; - } else if (parseFloat(size) < parseFloat(this.column.defaultMinWidth)) { - this.column.width = this.column.defaultMinWidth + 'px'; - } else { - this.column.width = size; - } - - this.grid.markForCheck(); - this.grid.reflow(); - this.grid.onColumnResized.emit({ column: this.column, prevWidth: currentColWidth.toString(), newWidth: this.column.width }); - } - } - - public onResize(event) { - this.column.grid.isColumnResizing = false; - - this.showResizer = false; - const diff = event.clientX - this._startResizePos; - - if (this.column.resizable) { - let currentColWidth = parseFloat(this.column.width); - - const actualMinWidth = parseFloat(this.column.minWidth); - const defaultMinWidth = parseFloat(this.column.defaultMinWidth); - - let colMinWidth = Number.isNaN(actualMinWidth) || actualMinWidth < defaultMinWidth ? defaultMinWidth : actualMinWidth; - const colMaxWidth = this.column.pinned ? parseFloat(this._pinnedMaxWidth) : parseFloat(this.column.maxWidth); - - const actualWidth = this.elementRef.nativeElement.getBoundingClientRect().width; - - currentColWidth = Number.isNaN(currentColWidth) || (currentColWidth < actualWidth) ? actualWidth : currentColWidth; - colMinWidth = colMinWidth < currentColWidth ? colMinWidth : currentColWidth; - - if (currentColWidth + diff < colMinWidth) { - this.column.width = colMinWidth + 'px'; - } else if (colMaxWidth && (currentColWidth + diff > colMaxWidth)) { - this.column.width = colMaxWidth + 'px'; - } else { - this.column.width = (currentColWidth + diff) + 'px'; - } - - this.grid.markForCheck(); - this.grid.reflow(); - - if (currentColWidth !== parseFloat(this.column.width)) { - this.grid.onColumnResized.emit({ column: this.column, prevWidth: currentColWidth.toString(), newWidth: this.column.width }); - } - } - } } diff --git a/projects/igniteui-angular/src/lib/grids/grid-navigation.service.ts b/projects/igniteui-angular/src/lib/grids/grid-navigation.service.ts index 07641cbcd14..f41f30099ad 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-navigation.service.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-navigation.service.ts @@ -419,7 +419,8 @@ export class IgxGridNavigationService { this.grid.rowList.find(row => row instanceof IgxGridRowComponent).cells.first._clearCellSelection(); const visColLength = this.grid.unpinnedColumns.length; if (this.isColumnFullyVisible(visColLength - 1)) { - this.grid.filteringService.focusFilterCellChip(this.grid.filterCellList.last.column.field, false); + const lastFilterCellIndex = this.grid.filterCellList.length - 1; + this.grid.filteringService.focusFilterCellChip(this.grid.filterCellList[lastFilterCellIndex].column, false); } else { this.grid.filteringService.columnToFocus = this.grid.unpinnedColumns[visColLength - 1]; this.grid.filteringService.shouldFocusNext = false; diff --git a/projects/igniteui-angular/src/lib/grids/grid.common.ts b/projects/igniteui-angular/src/lib/grids/grid.common.ts index d94af25461c..6e86a987365 100644 --- a/projects/igniteui-angular/src/lib/grids/grid.common.ts +++ b/projects/igniteui-angular/src/lib/grids/grid.common.ts @@ -123,6 +123,7 @@ export class IgxColumnResizerDirective implements OnInit, OnDestroy { event.preventDefault(); } } + /** * @hidden */ @@ -176,6 +177,8 @@ export class IgxColumnMovingService { private _column: IgxColumnComponent; public cancelDrop: boolean; + public isColumnMoving: boolean; + public selection: { column: IgxColumnComponent, rowID: any @@ -256,7 +259,6 @@ export class IgxColumnMovingDragDirective extends IgxDragDirective { } public onPointerDown(event) { - if (!this.draggable || event.target.getAttribute('draggable') === 'false') { return; } @@ -270,7 +272,7 @@ export class IgxColumnMovingDragDirective extends IgxDragDirective { super.onPointerDown(event); - this.column.grid.isColumnMoving = true; + this.cms.isColumnMoving = true; this.column.grid.cdr.detectChanges(); const currSelection = this.column.grid.selection.first_item(this.column.gridID + '-cell'); @@ -296,7 +298,7 @@ export class IgxColumnMovingDragDirective extends IgxDragDirective { this.column.grid.cdr.detectChanges(); } - if (this.column.grid.isColumnMoving) { + if (this.cms.isColumnMoving) { const args = { source: this.column, cancel: false @@ -314,14 +316,16 @@ export class IgxColumnMovingDragDirective extends IgxDragDirective { this.zone.run(() => { super.onPointerUp(event); - this.column.grid.isColumnMoving = false; + this.cms.isColumnMoving = false; this.column.grid.draggedColumn = null; this.column.grid.cdr.detectChanges(); }); } protected createDragGhost(event) { - super.createDragGhost(event); + const index = this.column.grid.hasMovableColumns ? 1 : 0; + + super.createDragGhost(event, this.element.nativeElement.children[index]); let pageX, pageY; if (this.pointerEventsEnabled || !this.touchEventsEnabled) { @@ -347,19 +351,15 @@ export class IgxColumnMovingDragDirective extends IgxDragDirective { if (!this.column.columnGroup) { this.renderer.addClass(icon, this._dragGhostImgIconClass); - this._dragGhost.removeChild(this._dragGhost.children[2]); - this._dragGhost.insertBefore(icon, this._dragGhost.children[1]); + this._dragGhost.insertBefore(icon, this._dragGhost.firstElementChild); this.left = this._dragStartX = pageX - ((this._dragGhost.getBoundingClientRect().width / 3) * 2); this.top = this._dragStartY = pageY - ((this._dragGhost.getBoundingClientRect().height / 3) * 2); } else { - this._dragGhost.removeChild(this._dragGhost.children[2]); - this._dragGhost.removeChild(this._dragGhost.firstElementChild); - this._dragGhost.removeChild(this._dragGhost.lastElementChild); - this._dragGhost.insertBefore(icon, this._dragGhost.firstElementChild); + this._dragGhost.insertBefore(icon, this._dragGhost.childNodes[0]); this.renderer.addClass(icon, this._dragGhostImgIconGroupClass); - this._dragGhost.children[1].style.paddingLeft = '0px'; + this._dragGhost.children[0].style.paddingLeft = '0px'; this.left = this._dragStartX = pageX - ((this._dragGhost.getBoundingClientRect().width / 3) * 2); this.top = this._dragStartY = pageY - ((this._dragGhost.getBoundingClientRect().height / 3) * 2); @@ -389,7 +389,7 @@ export class IgxColumnMovingDropDirective extends IgxDropDirective implements On } get isDropTarget(): boolean { - return this._column && this._column.grid.hasMovableColumns; + return this._column && this._column.grid.hasMovableColumns && this.cms.column.movable; } get horizontalScroll(): any { @@ -425,7 +425,8 @@ export class IgxColumnMovingDropDirective extends IgxDropDirective implements On this.renderer.removeClass(this._dropIndicator, this._dropIndicatorClass); } - const pos = this.elementRef.nativeElement.getBoundingClientRect().left + parseFloat(this.column.width) / 2; + const clientRect = this.elementRef.nativeElement.getBoundingClientRect(); + const pos = clientRect.left + clientRect.width / 2; if (event.detail.pageX < pos) { this._dropPos = DropPosition.BeforeDropTarget; @@ -530,11 +531,9 @@ export class IgxColumnMovingDropDirective extends IgxDropDirective implements On this.column.grid.moveColumn(this.cms.column, this.column, this._dropPos); if (this.cms.selection && this.cms.selection.column) { - const colID = this.column.grid.columnList.toArray().indexOf(this.cms.selection.column); - this.column.grid.selection.set(this.column.gridID + '-cell', new Set([{ rowID: this.cms.selection.rowID, - columnID: colID + columnID: this.column.grid.columnList.toArray().indexOf(this.cms.selection.column) }])); const cell = this.column.grid.getCellByKey(this.cms.selection.rowID, this.cms.selection.column.field); @@ -542,8 +541,6 @@ export class IgxColumnMovingDropDirective extends IgxDropDirective implements On if (cell) { cell.nativeElement.focus(); } - - this.cms.selection = null; } this.column.grid.draggedColumn = null; diff --git a/projects/igniteui-angular/src/lib/grids/grid/column-group.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/column-group.spec.ts index 78a0b400c75..1164687bb37 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/column-group.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/column-group.spec.ts @@ -68,7 +68,8 @@ describe('IgxGrid - multi-column headers', () => { addressGroup.hidden = true; tick(); - expect(document.querySelectorAll('igx-grid-header').length).toEqual(6); + expect(document.querySelectorAll('igx-grid-header').length).toEqual(4); + expect(document.querySelectorAll('igx-grid-header-group').length).toEqual(6); })); it('column hiding - child level', fakeAsync(() => { @@ -81,7 +82,7 @@ describe('IgxGrid - multi-column headers', () => { addressGroup.children.first.hidden = true; tick(); - expect(document.querySelectorAll('igx-grid-header').length).toEqual(5); + expect(document.querySelectorAll('igx-grid-header-group').length).toEqual(5); expect(addressGroup.children.first.hidden).toBe(true); expect(addressGroup.children.first.children.toArray().every(c => c.hidden === true)).toEqual(true); })); @@ -102,7 +103,7 @@ describe('IgxGrid - multi-column headers', () => { // Hide column in goup grid.getColumnByName('CompanyName').hidden = true; tick(); - expect(document.querySelectorAll('igx-grid-header').length).toEqual(16); + expect(document.querySelectorAll('igx-grid-header-group').length).toEqual(16); expect(fixture.debugElement.queryAll(By.css(GRID_COL_THEAD_CLASS)).length).toEqual(9); grid.getColumnByName('Address').hidden = true; @@ -586,7 +587,7 @@ describe('IgxGrid - multi-column headers', () => { testColumnGroupHeaderRendering(secondGroup, secondGroupChildrenCount * secondSubGroupChildrenCount * columnWidthPx, gridHeadersDepth * grid.defaultRowHeight, componentInstance.secondGroupTitle, - 'secondSubGroup', secondGroupChildrenCount); + 'secondSubGroup', 0); const secondSubGroups = secondGroup.queryAll(By.css('.secondSubGroup')); testColumnGroupHeaderRendering(secondSubGroups[0], @@ -1850,21 +1851,21 @@ export class StegosaurusGridComponent implements AfterViewInit { @Component({ template: ` - + - - + + - + - + @@ -1907,7 +1908,7 @@ export class BlueWhaleGridComponent { @Component({ template: ` - + ` @@ -1925,13 +1926,13 @@ export class EmptyColGridComponent { @Component({ template: ` - + - + - + @@ -1960,13 +1961,13 @@ export class OneColPerGroupGridComponent { @Component({ template: ` - - + + - + @@ -2054,8 +2055,9 @@ function getColGroup(grid: IgxGridComponent, headerName: string): IgxColumnGroup // tests column and column group header rendering function testColumnGroupHeaderRendering(column: DebugElement, width: number, height: number, title: string, descendentColumnCssClass?: string, descendentColumnCount?: number) { - expect(column.nativeElement.parentElement.offsetHeight).toBe(height); - expect(column.nativeElement.parentElement.offsetWidth).toBe(width); + + expect(column.nativeElement.offsetHeight).toBe(height); + expect(column.nativeElement.offsetWidth).toBe(width); const colHeaderTitle = column.children .filter(c => c.nativeElement.classList.contains(GRID_COL_GROUP_THEAD_TITLE_CLASS))[0]; @@ -2103,7 +2105,7 @@ function testColumnsVisibleIndexes(columns: IgxColumnComponent[]) { } function testGroupsAndColumns(groups: number, columns: number) { - expect(document.querySelectorAll('igx-grid-header').length).toEqual(groups); + expect(document.querySelectorAll('igx-grid-header-group').length).toEqual(groups); expect(document.querySelectorAll(GRID_COL_THEAD_CLASS).length).toEqual(columns); } @@ -2176,7 +2178,7 @@ class NestedColGroupsTests { const masterColGroup = fixture.debugElement.query(By.css('.masterColGroup')); const masterColGroupWidth = firstSlaveColGroupWidth + secondSlaveColGroupWidth; const masterSlaveColGroupDepth = 3; - const masterColGroupChildrenCount = 2; + const masterColGroupChildrenCount = 0; testColumnGroupHeaderRendering(masterColGroup, masterColGroupWidth, masterSlaveColGroupDepth * grid.defaultRowHeight, ci.masterColGroupTitle, diff --git a/projects/igniteui-angular/src/lib/grids/grid/column-moving.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/column-moving.spec.ts index b2c6fb0d715..6f3be21d2cf 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/column-moving.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/column-moving.spec.ts @@ -24,7 +24,7 @@ describe('IgxGrid - Column Moving', () => { configureTestSuite(); const CELL_CSS_CLASS = '.igx-grid__td'; const COLUMN_HEADER_CLASS = '.igx-grid__th'; - const COLUMN_GROUP_HEADER_CLASS = '.igx-grid__th--fw'; + const COLUMN_GROUP_HEADER_CLASS = '.igx-grid__thead-title'; let fixture, grid: IgxGridComponent; @@ -141,8 +141,7 @@ describe('IgxGrid - Column Moving', () => { expect(columnsList[2].field).toEqual('LastName'); })); - xit('Should not break filtering, sorting and resizing when column moving is enabled.', (async() => { - pending('This scenario need to be reworked with new Filtering row'); + it('Should not break sorting and resizing when column moving is enabled.', (async() => { fixture.componentInstance.isFilterable = true; fixture.componentInstance.isResizable = true; fixture.componentInstance.isSortable = true; @@ -171,13 +170,12 @@ describe('IgxGrid - Column Moving', () => { // step 2 - verify resizing is not broken - const resizeHandle = headers[0].nativeElement.children[3]; - - UIInteractions.simulateMouseEvent('mousedown', resizeHandle, 200, 0); + const resizeHandle = headers[0].parent.nativeElement.children[2]; + UIInteractions.simulateMouseEvent('mousedown', resizeHandle, 200, 80); await wait(); fixture.detectChanges(); - const resizer = headers[0].nativeElement.children[3].children[0]; + const resizer = headers[0].parent.nativeElement.children[2].children[0]; expect(resizer).toBeDefined(); UIInteractions.simulateMouseEvent('mousemove', resizer, 300, 5); await wait(); @@ -194,18 +192,6 @@ describe('IgxGrid - Column Moving', () => { fixture.detectChanges(); expect(grid.getCellByColumn(0, 'ID').value).toEqual(6); - - - // step 4 - verify filtering is not broken - const filterUIContainer = fixture.debugElement.query(By.css('igx-grid-filter')); - const filterIcon = filterUIContainer.query(By.css('igx-icon')); - - filterIcon.nativeElement.click(); - await wait(); - fixture.detectChanges(); - - const dialog = filterUIContainer.query(By.directive(IgxToggleDirective)); - expect(dialog.nativeElement.classList).toContain('igx-toggle'); })); it('Should not break vertical or horizontal scrolling after columns are reordered.', (async() => { @@ -245,44 +231,6 @@ describe('IgxGrid - Column Moving', () => { expect(grid.columnList.toArray()[2].cells[3].value).toBeTruthy('BRown'); })); - xit('Should close filter dialog, if opened, when column moving starts.', (async() => { - pending('This scenario need to be reworked with new Filtering row'); - fixture.componentInstance.isFilterable = true; - fixture.detectChanges(); - - const headers: DebugElement[] = fixture.debugElement.queryAll(By.css(COLUMN_HEADER_CLASS)); - - headers[0].triggerEventHandler('click', new Event('click')); - fixture.detectChanges(); - - const filterUIContainer = fixture.debugElement.query(By.css('igx-grid-filter')); - const filterIcon = filterUIContainer.query(By.css('igx-icon')); - - // step 1 - open the filtering dialog - filterIcon.nativeElement.click(); - await wait(); - fixture.detectChanges(); - - let dialog = filterUIContainer.query(By.directive(IgxToggleDirective)); - expect(dialog.nativeElement.classList.contains('igx-toggle')).toBeTruthy(); - - // step 2 - move a column - const header = headers[0].nativeElement; - UIInteractions.simulatePointerEvent('pointerdown', header, 100, 65); - await wait(); - UIInteractions.simulatePointerEvent('pointermove', header, 106, 71); - await wait(); - UIInteractions.simulatePointerEvent('pointermove', header, 300, 71); - await wait(); - UIInteractions.simulatePointerEvent('pointerup', header, 300, 71); - await wait(); - fixture.detectChanges(); - - // step 3 - verify the filtering dialog is closed - dialog = filterUIContainer.query(By.directive(IgxToggleDirective)); - expect(dialog.nativeElement.classList.contains('igx-toggle--hidden')).toBeTruthy(); - })); - it('Should fire onColumnMovingStart, onColumnMoving and onColumnMovingEnd with correct values of event arguments.', (async() => { const headers: DebugElement[] = fixture.debugElement.queryAll(By.css(COLUMN_HEADER_CLASS)); @@ -509,6 +457,7 @@ describe('IgxGrid - Column Moving', () => { cell = fixture.debugElement.queryAll(By.css(CELL_CSS_CLASS))[1]; UIInteractions.triggerKeyDownEvtUponElem('arrowright', cell.nativeElement, true); await wait(50); + fixture.detectChanges(); expect(grid.getCellByColumn(0, 'LastName').selected).toBeTruthy(); })); @@ -542,6 +491,7 @@ describe('IgxGrid - Column Moving', () => { cell = fixture.debugElement.queryAll(By.css(CELL_CSS_CLASS))[0]; UIInteractions.triggerKeyDownEvtUponElem('arrowright', cell.nativeElement, true); await wait(50); + fixture.detectChanges(); expect(grid.getCellByColumn(0, 'LastName').selected).toBeTruthy(); })); @@ -1002,7 +952,7 @@ describe('IgxGrid - Column Moving', () => { it('MCH - should reorder only columns on the same level (top level simple column).', (async() => { // step 1 - try reordering simple column level 0 and simple column level 1 - const header = fixture.debugElement.queryAll(By.css(COLUMN_GROUP_HEADER_CLASS))[0].nativeElement; + const header = fixture.debugElement.queryAll(By.css(COLUMN_HEADER_CLASS))[0].nativeElement; UIInteractions.simulatePointerEvent('pointerdown', header, 50, 75); await wait(); UIInteractions.simulatePointerEvent('pointermove', header, 50, 81); @@ -1051,7 +1001,7 @@ describe('IgxGrid - Column Moving', () => { it('MCH - should reorder only columns on the same level (top level group column).', (async() => { // step 1 - try reordering group column level 0 and simple column level 1 - let header = fixture.debugElement.queryAll(By.css(COLUMN_GROUP_HEADER_CLASS))[1].nativeElement; + let header = fixture.debugElement.queryAll(By.css(COLUMN_GROUP_HEADER_CLASS))[0].nativeElement; UIInteractions.simulatePointerEvent('pointerdown', header, 250, 25); await wait(); UIInteractions.simulatePointerEvent('pointermove', header, 250, 31); @@ -1073,9 +1023,9 @@ describe('IgxGrid - Column Moving', () => { await wait(); UIInteractions.simulatePointerEvent('pointermove', header, 250, 31); await wait(50); - UIInteractions.simulatePointerEvent('pointermove', header, 560, 81); - await wait(); - UIInteractions.simulatePointerEvent('pointerup', header, 560, 81); + UIInteractions.simulatePointerEvent('pointermove', header, 570, 81); + await wait(50); + UIInteractions.simulatePointerEvent('pointerup', header, 570, 81); await wait(); fixture.detectChanges(); @@ -1085,14 +1035,14 @@ describe('IgxGrid - Column Moving', () => { expect(columnsList[2].field).toEqual('CompanyName'); // step 3 - try reordering group column level 0 and group column level 0 - header = fixture.debugElement.queryAll(By.css(COLUMN_GROUP_HEADER_CLASS))[7].nativeElement; - UIInteractions.simulatePointerEvent('pointerdown', header, 800, 25); + header = fixture.debugElement.queryAll(By.css(COLUMN_GROUP_HEADER_CLASS))[2].nativeElement; + UIInteractions.simulatePointerEvent('pointerdown', header, 700, 25); await wait(); - UIInteractions.simulatePointerEvent('pointermove', header, 800, 31); + UIInteractions.simulatePointerEvent('pointermove', header, 700, 31); await wait(50); - UIInteractions.simulatePointerEvent('pointermove', header, 350, 31); + UIInteractions.simulatePointerEvent('pointermove', header, 200, 31); await wait(); - UIInteractions.simulatePointerEvent('pointerup', header, 350, 31); + UIInteractions.simulatePointerEvent('pointerup', header, 200, 31); await wait(); fixture.detectChanges(); @@ -1106,7 +1056,7 @@ describe('IgxGrid - Column Moving', () => { it('MCH - should reorder only columns on the same level (sub level simple column).', (async() => { // step 1 - try reordering simple column level 1 and simple column level 0 - const header = fixture.debugElement.queryAll(By.css(COLUMN_GROUP_HEADER_CLASS))[2].nativeElement; + const header = fixture.debugElement.queryAll(By.css(COLUMN_HEADER_CLASS))[1].nativeElement; UIInteractions.simulatePointerEvent('pointerdown', header, 150, 100); await wait(); UIInteractions.simulatePointerEvent('pointermove', header, 150, 106); @@ -1174,7 +1124,8 @@ describe('IgxGrid - Column Moving', () => { it('MCH - should reorder only columns on the same level (sub level group column).', (async() => { // step 1 - try reordering group column level 1 and simple column level 0 - const header = fixture.debugElement.queryAll(By.css(COLUMN_GROUP_HEADER_CLASS))[3].nativeElement; + const header = fixture.debugElement.queryAll(By.css(COLUMN_GROUP_HEADER_CLASS))[1].nativeElement; + UIInteractions.simulatePointerEvent('pointerdown', header, 300, 75); await wait(); UIInteractions.simulatePointerEvent('pointermove', header, 300, 81); @@ -1226,7 +1177,7 @@ describe('IgxGrid - Column Moving', () => { it('MCH - should reorder only columns on the same level, with same parent.', (async() => { // step 1 - try reordering simple column level 1 and simple column level 1 (different parent) - let header = fixture.debugElement.queryAll(By.css(COLUMN_GROUP_HEADER_CLASS))[2].nativeElement; + let header = fixture.debugElement.queryAll(By.css(COLUMN_HEADER_CLASS))[1].nativeElement; UIInteractions.simulatePointerEvent('pointerdown', header, 150, 75); await wait(); UIInteractions.simulatePointerEvent('pointermove', header, 150, 81); @@ -1242,7 +1193,7 @@ describe('IgxGrid - Column Moving', () => { expect(columnsList[5].field).toEqual('Country'); // step 2 - try reordering simple column level 2 and simple column level 2 (same parent) - header = fixture.debugElement.queryAll(By.css(COLUMN_GROUP_HEADER_CLASS))[5].nativeElement; + header = fixture.debugElement.queryAll(By.css(COLUMN_HEADER_CLASS))[3].nativeElement; UIInteractions.simulatePointerEvent('pointerdown', header, 400, 125); await wait(); UIInteractions.simulatePointerEvent('pointermove', header, 400, 131); @@ -1258,14 +1209,14 @@ describe('IgxGrid - Column Moving', () => { expect(columnsList[3].field).toEqual('ContactName'); // step 3 - try reordering simple column level 0 and simple column level 0 (no parent) - header = fixture.debugElement.queryAll(By.css(COLUMN_GROUP_HEADER_CLASS))[0].nativeElement; + header = fixture.debugElement.queryAll(By.css(COLUMN_HEADER_CLASS))[0].nativeElement; UIInteractions.simulatePointerEvent('pointerdown', header, 50, 75); await wait(); UIInteractions.simulatePointerEvent('pointermove', header, 50, 81); await wait(50); - UIInteractions.simulatePointerEvent('pointermove', header, 560, 81); + UIInteractions.simulatePointerEvent('pointermove', header, 580, 81); await wait(); - UIInteractions.simulatePointerEvent('pointerup', header, 560, 81); + UIInteractions.simulatePointerEvent('pointerup', header, 580, 81); await wait(); fixture.detectChanges(); @@ -1284,14 +1235,14 @@ describe('IgxGrid - Column Moving', () => { fixture.detectChanges(); // step 2 - reorder the parent column and verify selection is preserved - const header = fixture.debugElement.queryAll(By.css(COLUMN_GROUP_HEADER_CLASS))[1].nativeElement; + const header = fixture.debugElement.queryAll(By.css(COLUMN_GROUP_HEADER_CLASS))[0].nativeElement; UIInteractions.simulatePointerEvent('pointerdown', header, 300, 25); await wait(); UIInteractions.simulatePointerEvent('pointermove', header, 300, 31); await wait(50); - UIInteractions.simulatePointerEvent('pointermove', header, 560, 50); + UIInteractions.simulatePointerEvent('pointermove', header, 580, 50); await wait(); - UIInteractions.simulatePointerEvent('pointerup', header, 560, 50); + UIInteractions.simulatePointerEvent('pointerup', header, 580, 50); await wait(); fixture.detectChanges(); @@ -1312,7 +1263,7 @@ describe('IgxGrid - Column Moving', () => { fixture.detectChanges(); // step 2 - try pinning a sub level simple column - let header = fixture.debugElement.queryAll(By.css(COLUMN_GROUP_HEADER_CLASS))[2].nativeElement; + let header = fixture.debugElement.queryAll(By.css(COLUMN_HEADER_CLASS))[1].nativeElement; UIInteractions.simulatePointerEvent('pointerdown', header, 150, 75); await wait(); UIInteractions.simulatePointerEvent('pointermove', header, 150, 81); @@ -1327,7 +1278,7 @@ describe('IgxGrid - Column Moving', () => { expect(columnsList[1].field).toEqual('CompanyName'); // step 3 - try pinning a top level group column - header = fixture.debugElement.queryAll(By.css(COLUMN_GROUP_HEADER_CLASS))[1].nativeElement; + header = fixture.debugElement.queryAll(By.css(COLUMN_GROUP_HEADER_CLASS))[0].nativeElement; UIInteractions.simulatePointerEvent('pointerdown', header, 150, 25); await wait(); UIInteractions.simulatePointerEvent('pointermove', header, 150, 31); diff --git a/projects/igniteui-angular/src/lib/grids/grid/column-resizing.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/column-resizing.spec.ts index 21755caab31..2d4d7020863 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/column-resizing.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/column-resizing.spec.ts @@ -1,5 +1,5 @@ import { Component, DebugElement, OnInit, ViewChild } from '@angular/core'; -import { async, fakeAsync, TestBed, tick } from '@angular/core/testing'; +import { async, fakeAsync, TestBed, tick, flush } from '@angular/core/testing'; import { FormsModule } from '@angular/forms'; import { By } from '@angular/platform-browser'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; @@ -18,6 +18,7 @@ import { configureTestSuite } from '../../test-utils/configure-suite'; describe('IgxGrid - Deferred Column Resizing', () => { configureTestSuite(); const COLUMN_HEADER_CLASS = '.igx-grid__th'; + const COLUMN_HEADER_GROUP_CLASS = '.igx-grid__thead-item'; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -50,22 +51,17 @@ describe('IgxGrid - Deferred Column Resizing', () => { expect(grid.columns[0].resizable).toBeTruthy(); expect(grid.columns[2].resizable).toBeFalsy(); - const headerResArea = headers[0].nativeElement.children[2]; - UIInteractions.simulateMouseEvent('mouseover', headerResArea, 100, 5); - UIInteractions.simulateMouseEvent('mousedown', headerResArea, 100, 5); - UIInteractions.simulateMouseEvent('mousedup', headerResArea, 100, 5); - tick(100); - fixture.detectChanges(); - UIInteractions.simulateMouseEvent('mousedown', headerResArea, 100, 5); - tick(100); + const headerResArea = headers[0].parent.children[1].nativeElement; + UIInteractions.simulateMouseEvent('mousedown', headerResArea, 100, 15); + tick(); fixture.detectChanges(); - let resizer = headers[0].nativeElement.children[2].children[0]; + let resizer = headers[0].parent.children[1].children[0].nativeElement; expect(resizer).toBeDefined(); - UIInteractions.simulateMouseEvent('mousemove', resizer, 250, 5); - tick(100); + UIInteractions.simulateMouseEvent('mousemove', resizer, 250, 15); + tick(); - UIInteractions.simulateMouseEvent('mouseup', resizer, 250, 5); + UIInteractions.simulateMouseEvent('mouseup', resizer, 250, 15); tick(); fixture.detectChanges(); @@ -75,7 +71,7 @@ describe('IgxGrid - Deferred Column Resizing', () => { tick(); fixture.detectChanges(); - resizer = headers[0].nativeElement.children[2].children[0]; + resizer = headers[0].parent.children[1].children[0].nativeElement; expect(resizer).toBeDefined(); UIInteractions.simulateMouseEvent('mousemove', resizer, 40, 5); tick(); @@ -105,12 +101,12 @@ describe('IgxGrid - Deferred Column Resizing', () => { expect(grid.columns[0].width).toEqual('100px'); - const headerResArea = headers[0].nativeElement.children[2]; + const headerResArea = headers[0].parent.children[1].nativeElement; UIInteractions.simulateMouseEvent('mousedown', headerResArea, 100, 0); tick(); fixture.detectChanges(); - const resizer = headers[0].nativeElement.children[2].children[0]; + const resizer = headers[0].parent.children[1].children[0].nativeElement; expect(resizer).toBeDefined(); UIInteractions.simulateMouseEvent('mousemove', resizer, 700, 5); tick(); @@ -134,18 +130,18 @@ describe('IgxGrid - Deferred Column Resizing', () => { expect(grid.columns[1].maxWidth).toEqual('250px'); expect(grid.columns[1].resizable).toBeTruthy(); - const headerResArea = headers[1].nativeElement.children[2]; + const headerResArea = headers[1].parent.children[1].nativeElement; UIInteractions.simulateMouseEvent('mousedown', headerResArea, 200, 0); tick(); fixture.detectChanges(); - let resizer = headers[1].nativeElement.children[2].children[0]; + let resizer = headers[1].parent.children[1].children[0].nativeElement; expect(resizer).toBeDefined(); UIInteractions.simulateMouseEvent('mousemove', resizer, 370, 5); tick(); UIInteractions.simulateMouseEvent('mouseup', resizer, 370, 5); - tick(100); + tick(); fixture.detectChanges(); expect(grid.columns[1].width).toEqual('250px'); @@ -154,7 +150,7 @@ describe('IgxGrid - Deferred Column Resizing', () => { tick(); fixture.detectChanges(); - resizer = headers[1].nativeElement.children[2].children[0]; + resizer = headers[1].parent.children[1].children[0].nativeElement; UIInteractions.simulateMouseEvent('mousemove', resizer, 100, 5); tick(); @@ -176,12 +172,12 @@ describe('IgxGrid - Deferred Column Resizing', () => { expect(grid.columns[2].sortable).toBeTruthy(); expect(grid.columns[2].cells[0].value).toEqual(254); - const headerResArea = headers[2].nativeElement.children[2]; + const headerResArea = headers[2].parent.children[1].nativeElement; UIInteractions.simulateMouseEvent('mousedown', headerResArea, 450, 0); tick(); fixture.detectChanges(); - const resizer = headers[2].nativeElement.children[1].children[0]; + const resizer = headers[2].parent.children[1].children[0].nativeElement; expect(resizer).toBeDefined(); UIInteractions.simulateMouseEvent('mousemove', resizer, 550, 5); tick(); @@ -211,12 +207,12 @@ describe('IgxGrid - Deferred Column Resizing', () => { expect(grid.columns[0].width).toEqual('100px'); expect(grid.columns[1].width).toEqual('100px'); - const headerResArea = headers[0].nativeElement.children[2]; + const headerResArea = headers[0].parent.children[1].nativeElement; UIInteractions.simulateMouseEvent('mousedown', headerResArea, 100, 0); tick(); fixture.detectChanges(); - let resizer = headers[0].nativeElement.children[2].children[0]; + let resizer = headers[0].parent.children[1].children[0].nativeElement; expect(resizer).toBeDefined(); UIInteractions.simulateMouseEvent('mousemove', resizer, 450, 5); tick(); @@ -232,7 +228,7 @@ describe('IgxGrid - Deferred Column Resizing', () => { tick(); fixture.detectChanges(); - resizer = headers[0].nativeElement.children[2].children[0]; + resizer = headers[0].parent.children[1].children[0].nativeElement; UIInteractions.simulateMouseEvent('mousemove', resizer, 100, 5); tick(); @@ -252,12 +248,12 @@ describe('IgxGrid - Deferred Column Resizing', () => { expect(parseInt(grid.columns[0].width, 10)).not.toBeNaN(); - let headerResArea = headers[0].nativeElement.children[2]; + let headerResArea = headers[0].parent.children[1].nativeElement; UIInteractions.simulateMouseEvent('mousedown', headerResArea, 126, 5); tick(); fixture.detectChanges(); - let resizer = headers[0].nativeElement.children[2].children[0]; + let resizer = headers[0].parent.children[1].children[0].nativeElement; expect(resizer).toBeDefined(); UIInteractions.simulateMouseEvent('mousemove', resizer, 250, 5); tick(); @@ -272,7 +268,7 @@ describe('IgxGrid - Deferred Column Resizing', () => { tick(); fixture.detectChanges(); - resizer = headers[0].nativeElement.children[2].children[0]; + resizer = headers[0].parent.children[1].children[0].nativeElement; UIInteractions.simulateMouseEvent('mousemove', resizer, 50, 5); tick(); @@ -282,14 +278,14 @@ describe('IgxGrid - Deferred Column Resizing', () => { expect(grid.columns[0].width).toEqual('70px'); - headerResArea = headers[1].nativeElement.children[2]; + headerResArea = headers[1].parent.children[1].nativeElement; UIInteractions.simulateMouseEvent('mousedown', headerResArea, 197, 5); tick(); fixture.detectChanges(); expect(parseInt(grid.columns[1].width, 10)).not.toBeNaN(); - resizer = headers[1].nativeElement.children[2].children[0]; + resizer = headers[1].parent.children[1].children[0].nativeElement; expect(resizer).toBeDefined(); UIInteractions.simulateMouseEvent('mousemove', resizer, 300, 5); tick(); @@ -304,7 +300,7 @@ describe('IgxGrid - Deferred Column Resizing', () => { tick(); fixture.detectChanges(); - resizer = headers[1].nativeElement.children[2].children[0]; + resizer = headers[1].parent.children[1].children[0].nativeElement; UIInteractions.simulateMouseEvent('mousemove', resizer, 50, 5); tick(); @@ -328,12 +324,12 @@ describe('IgxGrid - Deferred Column Resizing', () => { expect(grid.columns[1].width).toEqual('100px'); - const headerResArea = headers[1].nativeElement.children[2]; + const headerResArea = headers[1].parent.children[1].nativeElement; UIInteractions.simulateMouseEvent('mousedown', headerResArea, 200, 0); tick(); fixture.detectChanges(); - const resizer = headers[1].nativeElement.children[2].children[0]; + const resizer = headers[1].parent.children[1].children[0].nativeElement; expect(resizer).toBeDefined(); UIInteractions.simulateMouseEvent('mousemove', resizer, 350, 5); tick(); @@ -350,43 +346,44 @@ describe('IgxGrid - Deferred Column Resizing', () => { fixture.detectChanges(); const grid = fixture.componentInstance.grid; - const headers: DebugElement[] = fixture.debugElement.queryAll(By.css(COLUMN_HEADER_CLASS)); + const headers: DebugElement[] = fixture.debugElement.queryAll(By.css(COLUMN_HEADER_GROUP_CLASS)); expect(grid.columns[0].width).toEqual('150px'); expect(grid.columns[1].width).toEqual('150px'); expect(grid.columns[2].width).toEqual('150px'); - let resizeArea = headers[0].componentInstance.resizeArea.nativeElement; - UIInteractions.simulateMouseEvent('dblclick', resizeArea, 148, 5); + let resizeArea = headers[0].children[1].nativeElement; + UIInteractions.simulateMouseEvent('dblclick', resizeArea, 148, 15); tick(); fixture.detectChanges(); expect(grid.columns[0].width).toEqual('78px'); - resizeArea = headers[1].componentInstance.resizeArea.nativeElement; + resizeArea = headers[1].children[1].nativeElement; + UIInteractions.simulateMouseEvent('mouseover', resizeArea, 248, 5); UIInteractions.simulateMouseEvent('dblclick', resizeArea, 248, 5); tick(); fixture.detectChanges(); expect(grid.columns[1].width).toEqual('195px'); - resizeArea = headers[2].componentInstance.resizeArea.nativeElement; + resizeArea = headers[2].children[1].nativeElement; UIInteractions.simulateMouseEvent('dblclick', resizeArea, 305, 5); tick(); fixture.detectChanges(); expect(grid.columns[2].width).toEqual('78px'); - resizeArea = headers[3].componentInstance.resizeArea.nativeElement; + resizeArea = headers[3].children[1].nativeElement; UIInteractions.simulateMouseEvent('dblclick', resizeArea, 400, 5); tick(); fixture.detectChanges(); expect(grid.columns[3].width).toEqual('73px'); - resizeArea = headers[5].componentInstance.resizeArea.nativeElement; + resizeArea = headers[5].children[1].nativeElement; UIInteractions.simulateMouseEvent('dblclick', resizeArea, 486, 5); - tick(); + tick(100); fixture.detectChanges(); expect(grid.columns[5].width).toEqual('89px'); @@ -397,13 +394,13 @@ describe('IgxGrid - Deferred Column Resizing', () => { fixture.detectChanges(); const grid = fixture.componentInstance.grid; - const headers: DebugElement[] = fixture.debugElement.queryAll(By.css(COLUMN_HEADER_CLASS)); + const headers: DebugElement[] = fixture.debugElement.queryAll(By.css(COLUMN_HEADER_GROUP_CLASS)); - expect(grid.columns[4].cells[0].nativeElement.getBoundingClientRect().width).toEqual(48); + expect(grid.columns[4].cells[0].nativeElement.getBoundingClientRect().width).toEqual(50); expect(grid.columns[4].maxWidth).toEqual('100px'); - const resizeArea = headers[4].componentInstance.resizeArea.nativeElement; - UIInteractions.simulateMouseEvent('dblclick', resizeArea, 498, 5); + const resizeArea = headers[4].children[1].nativeElement; + UIInteractions.simulateMouseEvent('dblclick', resizeArea, 448, 15); tick(); fixture.detectChanges(); @@ -415,11 +412,11 @@ describe('IgxGrid - Deferred Column Resizing', () => { fixture.detectChanges(); const grid = fixture.componentInstance.grid; - const headers: DebugElement[] = fixture.debugElement.queryAll(By.css(COLUMN_HEADER_CLASS)); + const headers: DebugElement[] = fixture.debugElement.queryAll(By.css(COLUMN_HEADER_GROUP_CLASS)); expect(grid.columns[5].width).toEqual('150px'); - const resizeArea = headers[5].componentInstance.resizeArea.nativeElement; + const resizeArea = headers[5].children[1].nativeElement; UIInteractions.simulateMouseEvent('dblclick', resizeArea, 898, 5); tick(); fixture.detectChanges(); @@ -432,11 +429,11 @@ describe('IgxGrid - Deferred Column Resizing', () => { fixture.detectChanges(); const grid = fixture.componentInstance.grid; - const headers: DebugElement[] = fixture.debugElement.queryAll(By.css(COLUMN_HEADER_CLASS)); + const headers: DebugElement[] = fixture.debugElement.queryAll(By.css(COLUMN_HEADER_GROUP_CLASS)); expect(grid.columns[2].width).toEqual('100px'); - const resizeArea = headers[2].componentInstance.resizeArea.nativeElement; + const resizeArea = headers[2].children[1].nativeElement; UIInteractions.simulateMouseEvent('dblclick', resizeArea, 298, 5); tick(); fixture.detectChanges(); @@ -449,13 +446,13 @@ describe('IgxGrid - Deferred Column Resizing', () => { fixture.detectChanges(); const grid = fixture.componentInstance.grid; - const headers: DebugElement[] = fixture.debugElement.queryAll(By.css(COLUMN_HEADER_CLASS)); + const headers: DebugElement[] = fixture.debugElement.queryAll(By.css(COLUMN_HEADER_GROUP_CLASS)); expect(grid.columns[0].width).toEqual('100px'); expect(grid.columns[1].width).toEqual('100px'); expect(grid.columns[2].width).toEqual('100px'); - const resizeArea = headers[1].componentInstance.resizeArea.nativeElement; + const resizeArea = headers[1].children[1].nativeElement; UIInteractions.simulateMouseEvent('dblclick', resizeArea, 198, 5); tick(); fixture.detectChanges(); @@ -464,12 +461,12 @@ describe('IgxGrid - Deferred Column Resizing', () => { expect(grid.columns[1].width).toEqual('100px'); expect(grid.columns[2].width).toEqual('100px'); - const headerResArea = headers[0].nativeElement.children[2]; + const headerResArea = headers[0].children[1].nativeElement; UIInteractions.simulateMouseEvent('mousedown', headerResArea, 100, 0); tick(); fixture.detectChanges(); - const resizer = headers[0].nativeElement.children[2].children[0]; + const resizer = headers[0].children[1].children[0].nativeElement; expect(resizer).toBeDefined(); UIInteractions.simulateMouseEvent('mousemove', resizer, 450, 5); tick(); @@ -488,17 +485,17 @@ describe('IgxGrid - Deferred Column Resizing', () => { fixture.detectChanges(); const grid = fixture.componentInstance.grid; - const headers: DebugElement[] = fixture.debugElement.queryAll(By.css(COLUMN_HEADER_CLASS)); + const headers: DebugElement[] = fixture.debugElement.queryAll(By.css(COLUMN_HEADER_GROUP_CLASS)); expect(grid.columns[0].width).toEqual('150px'); expect(fixture.componentInstance.count).toEqual(0); - const headerResArea = headers[0].nativeElement.children[2]; + const headerResArea = headers[0].children[1].nativeElement; UIInteractions.simulateMouseEvent('mousedown', headerResArea, 150, 5); tick(); fixture.detectChanges(); - const resizer = headers[0].nativeElement.children[2].children[0]; + const resizer = headers[0].children[1].children[0].nativeElement; expect(resizer).toBeDefined(); UIInteractions.simulateMouseEvent('mousemove', resizer, 300, 5); tick(); @@ -515,7 +512,7 @@ describe('IgxGrid - Deferred Column Resizing', () => { expect(grid.columns[1].width).toEqual('150px'); - const resizeArea = headers[1].componentInstance.resizeArea.nativeElement; + const resizeArea = headers[1].children[1].nativeElement; UIInteractions.simulateMouseEvent('dblclick', resizeArea, 198, 5); tick(); fixture.detectChanges(); @@ -531,7 +528,7 @@ describe('IgxGrid - Deferred Column Resizing', () => { const fixture = TestBed.createComponent(ResizableColumnsComponent); fixture.detectChanges(); const grid = fixture.componentInstance.grid; - const headers: DebugElement[] = fixture.debugElement.queryAll(By.css(COLUMN_HEADER_CLASS)); + const headers: DebugElement[] = fixture.debugElement.queryAll(By.css(COLUMN_HEADER_GROUP_CLASS)); const displayContainer: HTMLElement = fixture.componentInstance.grid.tbody.nativeElement.querySelector('igx-display-container'); let rowsRendered = displayContainer.querySelectorAll('igx-display-container'); let colsRendered = rowsRendered[0].children; @@ -540,12 +537,12 @@ describe('IgxGrid - Deferred Column Resizing', () => { expect(colsRendered.length).toEqual(4); // Resize first column - const headerResArea = headers[0].nativeElement.children[2]; + const headerResArea = headers[0].children[1].nativeElement; UIInteractions.simulateMouseEvent('mousedown', headerResArea, 100, 0); tick(); fixture.detectChanges(); - const resizer = headers[0].nativeElement.children[2].children[0]; + const resizer = headers[0].children[1].children[0].nativeElement; expect(resizer).toBeDefined(); UIInteractions.simulateMouseEvent('mousemove', resizer, 700, 5); tick(); @@ -577,7 +574,7 @@ describe('IgxGrid - Deferred Column Resizing', () => { fixture.detectChanges(); const grid = fixture.componentInstance.grid; - const headers: DebugElement[] = fixture.debugElement.queryAll(By.css(COLUMN_HEADER_CLASS)); + const headers: DebugElement[] = fixture.debugElement.queryAll(By.css(COLUMN_HEADER_GROUP_CLASS)); const expectedHeight = fixture.debugElement.query(By.css('igx-grid')).nativeElement.getBoundingClientRect().height - grid.nativeElement.querySelector('.igx-grid__thead').getBoundingClientRect().height - grid.nativeElement.querySelector('.igx-grid__tfoot').getBoundingClientRect().height; @@ -586,12 +583,12 @@ describe('IgxGrid - Deferred Column Resizing', () => { expect(grid.columns[0].width).toEqual('100px'); // Resize first column - const headerResArea = headers[0].nativeElement.children[2]; + const headerResArea = headers[0].children[1].nativeElement; UIInteractions.simulateMouseEvent('mousedown', headerResArea, 100, 0); tick(); fixture.detectChanges(); - const resizer = headers[0].nativeElement.children[2].children[0]; + const resizer = headers[0].children[1].children[0].nativeElement; expect(resizer).toBeDefined(); UIInteractions.simulateMouseEvent('mousemove', resizer, 250, 5); tick(); @@ -751,7 +748,7 @@ export class PinnedColumnsComponent { [formatter]="returnVal"> - +
diff --git a/projects/igniteui-angular/src/lib/grids/grid/column.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/column.spec.ts index 0af94dce994..42c22b7d921 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/column.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/column.spec.ts @@ -13,6 +13,7 @@ describe('IgxGrid - Column properties', () => { configureTestSuite(); const COLUMN_HEADER_CLASS = '.igx-grid__th'; + const COLUMN_HEADER_GROUP_CLASS = '.igx-grid__thead-item'; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -170,10 +171,11 @@ describe('IgxGrid - Column properties', () => { fix.componentInstance.grid.columnWidth = '200px'; fix.detectChanges(); const cols = fix.componentInstance.grid.columnList; + cols.forEach((item) => { expect(item.width).toEqual('200px'); }); - const headers = fix.debugElement.queryAll(By.css(COLUMN_HEADER_CLASS)); + const headers = fix.debugElement.queryAll(By.css(COLUMN_HEADER_GROUP_CLASS)); expect(headers[0].nativeElement.style['min-width']).toEqual('200px'); }); diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-ui.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-ui.spec.ts index 50867d14403..04f8abb58ac 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-ui.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-ui.spec.ts @@ -1,7 +1,7 @@ import { Component, ViewChild, DebugElement } from '@angular/core'; -import { async, discardPeriodicTasks, fakeAsync, TestBed, tick } from '@angular/core/testing'; +import { async, discardPeriodicTasks, fakeAsync, TestBed, tick, flush } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations'; import { Calendar } from '../../calendar/calendar'; import { IgxInputDirective } from '../../directives/input/input.directive'; import { IgxGridComponent } from './grid.component'; @@ -21,6 +21,7 @@ import { IgxBadgeComponent } from '../../badge/badge.component'; import { IgxCheckboxComponent } from '../../checkbox/checkbox.component'; import { SortingDirection } from '../../data-operations/sorting-expression.interface'; import { DefaultSortingStrategy } from '../../data-operations/sorting-strategy'; +import { IgxGridHeaderGroupComponent } from '../grid-header-group.component'; const FILTER_UI_ROW = 'igx-grid-filtering-row'; @@ -32,7 +33,7 @@ describe('IgxGrid - Filtering actions', () => { IgxGridFilteringComponent ], imports: [ - BrowserAnimationsModule, + NoopAnimationsModule, IgxGridModule.forRoot()] }) .compileComponents(); @@ -63,8 +64,8 @@ describe('IgxGrid - Filtering actions', () => { // open dropdown filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); - tick(100); const ddList = fix.debugElement.query(By.css('div.igx-drop-down__list.igx-toggle')); const ddItems = ddList.nativeElement.children; @@ -74,9 +75,8 @@ describe('IgxGrid - Filtering actions', () => { verifyFilterUIPosition(filterUIRow, grid); ddItems[2].click(); - // select.nativeElement.dispatchEvent(new Event('change')); - fix.detectChanges(); tick(); + fix.detectChanges(); expect(grid.rowList.length).toEqual(8); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); @@ -85,12 +85,12 @@ describe('IgxGrid - Filtering actions', () => { // open dropdown filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); - tick(100); // ends with ddItems[3].click(); - fix.detectChanges(); tick(); + fix.detectChanges(); expect(grid.rowList.length).toEqual(8); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); @@ -99,12 +99,12 @@ describe('IgxGrid - Filtering actions', () => { // open dropdown filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); - tick(100); // does not contain ddItems[1].click(); - fix.detectChanges(); tick(); + fix.detectChanges(); expect(grid.rowList.length).toEqual(8); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); @@ -113,12 +113,12 @@ describe('IgxGrid - Filtering actions', () => { // open dropdown filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); - tick(100); // equals ddItems[0].click(); - fix.detectChanges(); tick(); + fix.detectChanges(); expect(grid.rowList.length).toEqual(8); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); @@ -127,12 +127,12 @@ describe('IgxGrid - Filtering actions', () => { // open dropdown filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); - tick(100); // does not equal ddItems[5].click(); - fix.detectChanges(); tick(); + fix.detectChanges(); expect(grid.rowList.length).toEqual(8); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); @@ -141,12 +141,12 @@ describe('IgxGrid - Filtering actions', () => { // open dropdown filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); - tick(100); // empty ddItems[6].click(); + tick(100); fix.detectChanges(); - tick(); expect(grid.rowList.length).toEqual(4); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); @@ -157,12 +157,12 @@ describe('IgxGrid - Filtering actions', () => { // open dropdown filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); - tick(100); // not empty ddItems[7].click(); + tick(100); fix.detectChanges(); - tick(); expect(grid.rowList.length).toEqual(4); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); @@ -173,13 +173,13 @@ describe('IgxGrid - Filtering actions', () => { // open dropdown filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); - tick(100); // iterate over unary conditions // null ddItems[8].click(); + tick(100); fix.detectChanges(); - tick(); expect(grid.rowList.length).toEqual(3); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); @@ -190,12 +190,12 @@ describe('IgxGrid - Filtering actions', () => { // open dropdown filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); - tick(100); // not null ddItems[9].click(); + tick(100); fix.detectChanges(); - tick(); expect(grid.rowList.length).toEqual(5); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); @@ -204,13 +204,13 @@ describe('IgxGrid - Filtering actions', () => { // open dropdown filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); - tick(100); // changing from unary to not unary condition when input is empty - filtering should keep its state // contains ddItems[0].click(); + tick(100); fix.detectChanges(); - tick(); input = filterUIRow.query(By.directive(IgxInputDirective)); expect(grid.rowList.length).toEqual(5); @@ -241,21 +241,17 @@ describe('IgxGrid - Filtering actions', () => { // open dropdown filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); - tick(100); const ddList = fix.debugElement.query(By.css('div.igx-drop-down__list.igx-toggle')); const ddItems = ddList.nativeElement.children; - filterIcon.nativeElement.click(); - fix.detectChanges(); - tick(100); - // iterate over not unary conditions and fill the input // contains sendInput(input, 'Ignite', fix); - fix.detectChanges(); tick(); + fix.detectChanges(); expect(grid.rowList.length).toEqual(2); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); @@ -264,12 +260,12 @@ describe('IgxGrid - Filtering actions', () => { // starts with ddItems[2].click(); + tick(100); fix.detectChanges(); - tick(); sendInput(input, 'Net', fix); - fix.detectChanges(); tick(); + fix.detectChanges(); verifyFilterUIPosition(filterUIRow, grid); expect(grid.rowList.length).toEqual(1); @@ -281,16 +277,16 @@ describe('IgxGrid - Filtering actions', () => { // open dropdown filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); - tick(100); // ends with ddItems[3].click(); + tick(100); fix.detectChanges(); - tick(); sendInput(input, 'script', fix); - fix.detectChanges(); tick(); + fix.detectChanges(); expect(grid.rowList.length).toEqual(2); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); @@ -299,12 +295,12 @@ describe('IgxGrid - Filtering actions', () => { // open dropdown filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); - tick(100); // does not contain ddItems[1].click(); + tick(100); fix.detectChanges(); - tick(); expect(grid.rowList.length).toEqual(6); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); @@ -313,8 +309,8 @@ describe('IgxGrid - Filtering actions', () => { // use reset button reset.nativeElement.click(); - fix.detectChanges(); tick(); + fix.detectChanges(); expect(grid.rowList.length).toEqual(8); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); @@ -323,16 +319,16 @@ describe('IgxGrid - Filtering actions', () => { // open dropdown filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); - tick(100); // equals ddItems[4].click(); + tick(100); fix.detectChanges(); - tick(); sendInput(input, 'NetAdvantage', fix); - fix.detectChanges(); tick(); + fix.detectChanges(); expect(grid.rowList.length).toEqual(1); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); @@ -341,16 +337,16 @@ describe('IgxGrid - Filtering actions', () => { // open dropdown filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); - tick(100); // equals ddItems[4].click(); + tick(100); fix.detectChanges(); - tick(); sendInput(input, ' ', fix); - fix.detectChanges(); tick(); + fix.detectChanges(); expect(grid.rowList.length).toEqual(0); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); @@ -361,16 +357,16 @@ describe('IgxGrid - Filtering actions', () => { // open dropdown filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); - tick(100); // does not equal ddItems[5].click(); + tick(100); fix.detectChanges(); - tick(); sendInput(input, 'NetAdvantage', fix); - fix.detectChanges(); tick(); + fix.detectChanges(); expect(grid.rowList.length).toEqual(7); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); @@ -400,8 +396,8 @@ describe('IgxGrid - Filtering actions', () => { expect(reset.nativeElement.classList.contains('igx-button--disabled')).toBeTruthy(); filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); - tick(100); const ddList = fix.debugElement.query(By.css('div.igx-drop-down__list.igx-toggle')); const ddItems = ddList.nativeElement.children; @@ -411,8 +407,8 @@ describe('IgxGrid - Filtering actions', () => { // iterate over not unary conditions and fill the input // equals sendInput(input, 0, fix); - fix.detectChanges(); tick(); + fix.detectChanges(); expect(grid.rowList.length).toEqual(1); expect(grid.getCellByColumn(0, 'Downloads').value).toEqual(0); @@ -423,24 +419,32 @@ describe('IgxGrid - Filtering actions', () => { // clear input value GridFunctions.removeFilterChipByIndex(0, filterUIRow); - fix.detectChanges(); tick(); + fix.detectChanges(); // iterate over not unary conditions when input is empty + // open dropdown + filterIcon.nativeElement.click(); + tick(); + fix.detectChanges(); // does not equal ddItems[1].click(); + tick(100); fix.detectChanges(); - tick(); expect(grid.rowList.length).toEqual(8); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); expect(reset.nativeElement.classList.contains('igx-button--disabled')).toBeTruthy(); expect(input.nativeElement.offsetHeight).toBeGreaterThan(0); + // open dropdown + filterIcon.nativeElement.click(); + tick(); + fix.detectChanges(); // greater than ddItems[2].click(); + tick(100); fix.detectChanges(); - tick(); expect(grid.rowList.length).toEqual(8); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); @@ -448,40 +452,56 @@ describe('IgxGrid - Filtering actions', () => { expect(input.nativeElement.offsetHeight).toBeGreaterThan(0); // iterate over unary conditions - // null + // open dropdown + filterIcon.nativeElement.click(); + tick(); + fix.detectChanges(); + // empty ddItems[6].click(); + tick(100); fix.detectChanges(); - tick(); expect(grid.rowList.length).toEqual(1); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); expect(reset.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); expect(input.nativeElement.offsetHeight).toBeGreaterThan(0); - // not null + // open dropdown + filterIcon.nativeElement.click(); + tick(); + fix.detectChanges(); + // not empty ddItems[7].click(); + tick(100); fix.detectChanges(); - tick(); expect(grid.rowList.length).toEqual(7); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); expect(reset.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); expect(input.nativeElement.offsetHeight).toBeGreaterThan(0); - // empty + // open dropdown + filterIcon.nativeElement.click(); + tick(); + fix.detectChanges(); + // null ddItems[8].click(); + tick(100); fix.detectChanges(); - tick(); expect(grid.rowList.length).toEqual(1); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); expect(reset.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); expect(input.nativeElement.offsetHeight).toBeGreaterThan(0); - // not empty + // open dropdown + filterIcon.nativeElement.click(); + tick(); + fix.detectChanges(); + // not null ddItems[9].click(); + tick(100); fix.detectChanges(); - tick(); expect(grid.rowList.length).toEqual(7); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); @@ -489,10 +509,14 @@ describe('IgxGrid - Filtering actions', () => { expect(input.nativeElement.offsetHeight).toBeGreaterThan(0); // changing from unary to not unary condition when input is empty - filtering should keep its state + // open dropdown + filterIcon.nativeElement.click(); + tick(); + fix.detectChanges(); // equals - filter should keep its state and not be reset ddItems[0].click(); + tick(100); fix.detectChanges(); - tick(); input = filterUIRow.query(By.directive(IgxInputDirective)); expect(grid.rowList.length).toEqual(7); @@ -504,8 +528,8 @@ describe('IgxGrid - Filtering actions', () => { // iterate over not unary conditions and fill the input // equals sendInput(input, 100, fix); - fix.detectChanges(); tick(); + fix.detectChanges(); clear = filterUIRow.query(By.css('igx-suffix')); expect(grid.rowList.length).toEqual(1); @@ -515,24 +539,32 @@ describe('IgxGrid - Filtering actions', () => { expect(clear.nativeElement.offsetHeight).toBeGreaterThan(0); expect(input.nativeElement.offsetHeight).toBeGreaterThan(0); + // open dropdown + filterIcon.nativeElement.click(); + tick(); + fix.detectChanges(); // does not equal ddItems[1].click(); + tick(100); fix.detectChanges(); - tick(); expect(grid.rowList.length).toEqual(7); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); expect(reset.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); expect(input.nativeElement.offsetHeight).toBeGreaterThan(0); + // open dropdown + filterIcon.nativeElement.click(); + tick(); + fix.detectChanges(); // greater than ddItems[2].click(); + tick(100); fix.detectChanges(); - tick(); sendInput(input, 300, fix); - fix.detectChanges(); tick(); + fix.detectChanges(); expect(grid.rowList.length).toEqual(2); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); @@ -541,8 +573,8 @@ describe('IgxGrid - Filtering actions', () => { // use reset button reset.nativeElement.click(); - fix.detectChanges(); tick(); + fix.detectChanges(); expect(grid.rowList.length).toEqual(8); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); @@ -552,16 +584,16 @@ describe('IgxGrid - Filtering actions', () => { // open dropdown filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); - tick(100); // less than ddItems[3].click(); + tick(100); fix.detectChanges(); - tick(); sendInput(input, 100, fix); - fix.detectChanges(); tick(); + fix.detectChanges(); expect(grid.rowList.length).toEqual(3); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); @@ -571,8 +603,8 @@ describe('IgxGrid - Filtering actions', () => { GridFunctions.removeFilterChipByIndex(0, filterUIRow); clear.nativeElement.click(); - fix.detectChanges(); tick(); + fix.detectChanges(); expect(grid.rowList.length).toEqual(8); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); @@ -581,24 +613,32 @@ describe('IgxGrid - Filtering actions', () => { // revert to the default after expect(filterIcon.componentInstance.iconName).toMatch('equals'); + // open dropdown + filterIcon.nativeElement.click(); + tick(); + fix.detectChanges(); // greater than or equal to ddItems[4].click(); + tick(100); fix.detectChanges(); - tick(); sendInput(input, 254, fix); - fix.detectChanges(); tick(); + fix.detectChanges(); expect(grid.rowList.length).toEqual(3); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); expect(reset.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); expect(input.nativeElement.offsetHeight).toBeGreaterThan(0); + // open dropdown + filterIcon.nativeElement.click(); + tick(); + fix.detectChanges(); // less than or equal to ddItems[5].click(); + tick(100); fix.detectChanges(); - tick(); expect(grid.rowList.length).toEqual(6); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); @@ -624,8 +664,8 @@ describe('IgxGrid - Filtering actions', () => { expect(grid.rowList.length).toEqual(8); filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); - tick(100); const ddList = fix.debugElement.query(By.css('div.igx-drop-down__list.igx-toggle')); const ddItems = ddList.nativeElement.children; @@ -634,8 +674,8 @@ describe('IgxGrid - Filtering actions', () => { // false condition ddItems[2].click(); + tick(100); fix.detectChanges(); - tick(); expect(grid.rowList.length).toEqual(2); expect(grid.getCellByColumn(0, 'Released').value).toBeFalsy(); @@ -643,10 +683,13 @@ describe('IgxGrid - Filtering actions', () => { expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); expect(reset.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); + filterIcon.nativeElement.click(); + tick(); + fix.detectChanges(); // true condition ddItems[1].click(); + tick(100); fix.detectChanges(); - tick(); expect(grid.rowList.length).toEqual(3); expect(grid.getCellByColumn(0, 'Released').value).toBe(true); @@ -655,19 +698,25 @@ describe('IgxGrid - Filtering actions', () => { expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); expect(reset.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); + filterIcon.nativeElement.click(); + tick(); + fix.detectChanges(); // (all) condition ddItems[0].click(); + tick(100); fix.detectChanges(); - tick(); expect(grid.rowList.length).toEqual(8); expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); expect(reset.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); + filterIcon.nativeElement.click(); + tick(); + fix.detectChanges(); // empty condition ddItems[3].click(); + tick(100); fix.detectChanges(); - tick(); expect(grid.rowList.length).toEqual(3); expect(grid.getCellByColumn(0, 'Released').value).toEqual(null); @@ -676,10 +725,13 @@ describe('IgxGrid - Filtering actions', () => { expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); expect(reset.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); + filterIcon.nativeElement.click(); + tick(); + fix.detectChanges(); // not empty condition ddItems[4].click(); + tick(100); fix.detectChanges(); - tick(); expect(grid.rowList.length).toEqual(5); expect(grid.getCellByColumn(0, 'Released').value).toBe(false); @@ -690,10 +742,13 @@ describe('IgxGrid - Filtering actions', () => { expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); expect(reset.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); + filterIcon.nativeElement.click(); + tick(); + fix.detectChanges(); // null condition ddItems[5].click(); + tick(100); fix.detectChanges(); - tick(); expect(grid.rowList.length).toEqual(2); expect(grid.getCellByColumn(0, 'Released').value).toEqual(null); @@ -701,10 +756,13 @@ describe('IgxGrid - Filtering actions', () => { expect(close.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); expect(reset.nativeElement.classList.contains('igx-button--disabled')).toBeFalsy(); + filterIcon.nativeElement.click(); + tick(); + fix.detectChanges(); // not null condition ddItems[6].click(); + tick(100); fix.detectChanges(); - tick(); expect(grid.rowList.length).toEqual(6); expect(grid.getCellByColumn(0, 'Released').value).toBe(false); @@ -718,61 +776,66 @@ describe('IgxGrid - Filtering actions', () => { })); // UI tests date column - it('UI - should correctly filter date column by \'today\' filtering conditions', () => { + it('UI - should correctly filter date column by \'today\' filtering conditions', fakeAsync(() => { const fix = TestBed.createComponent(IgxGridFilteringComponent); fix.detectChanges(); const grid = fix.componentInstance.grid; const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); filteringCells[4].query(By.css('igx-chip')).nativeElement.click(); + tick(); fix.detectChanges(); const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); const filterIcon = filterUIRow.query(By.css('igx-icon')); filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); const ddList = fix.debugElement.query(By.css('div.igx-drop-down__list.igx-toggle')); - fix.detectChanges(); verifyFilterUIPosition(filterUIRow, grid); GridFunctions.selectFilteringCondition('Today', ddList); + tick(100); fix.detectChanges(); // only one record is populated with 'today' date, this is why rows must be 1 expect(grid.rowList.length).toEqual(1); - }); + })); - it('UI - should correctly filter date column by \'yesterday\' filtering conditions', () => { + it('UI - should correctly filter date column by \'yesterday\' filtering conditions', fakeAsync(() => { const fix = TestBed.createComponent(IgxGridFilteringComponent); fix.detectChanges(); const grid = fix.componentInstance.grid; const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); filteringCells[4].query(By.css('igx-chip')).nativeElement.click(); + tick(); fix.detectChanges(); const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); const filterIcon = filterUIRow.query(By.css('igx-icon')); filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); const ddList = fix.debugElement.query(By.css('div.igx-drop-down__list.igx-toggle')); - fix.detectChanges(); verifyFilterUIPosition(filterUIRow, grid); GridFunctions.selectFilteringCondition('Yesterday', ddList); + tick(100); fix.detectChanges(); // only one record is populated with (today - 1 day) date, this is why rows must be 1 expect(grid.rowList.length).toEqual(1); - }); + })); - it('UI - should correctly filter date column by \'this month\' filtering conditions', () => { + it('UI - should correctly filter date column by \'this month\' filtering conditions', fakeAsync(() => { const fix = TestBed.createComponent(IgxGridFilteringComponent); fix.detectChanges(); const grid = fix.componentInstance.grid; const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); filteringCells[4].query(By.css('igx-chip')).nativeElement.click(); + tick(); fix.detectChanges(); const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); const filterIcon = filterUIRow.query(By.css('igx-icon')); @@ -782,25 +845,26 @@ describe('IgxGrid - Filtering actions', () => { // Fill expected results based on the current date fillExpectedResults(grid, cal, today); - filterIcon.triggerEventHandler('mousedown', null); - fix.detectChanges(); filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); const ddList = fix.debugElement.query(By.css('div.igx-drop-down__list.igx-toggle')); verifyFilterUIPosition(filterIcon, grid); GridFunctions.selectFilteringCondition('This Month', ddList); + tick(100); fix.detectChanges(); expect(grid.rowList.length).toEqual(expectedResults[5]); - }); + })); - it('UI - should correctly filter date column by \'next month\' filtering conditions', () => { + it('UI - should correctly filter date column by \'next month\' filtering conditions', fakeAsync(() => { const fix = TestBed.createComponent(IgxGridFilteringComponent); fix.detectChanges(); const grid = fix.componentInstance.grid; const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); filteringCells[4].query(By.css('igx-chip')).nativeElement.click(); + tick(); fix.detectChanges(); const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); const filterIcon = filterUIRow.query(By.css('igx-icon')); @@ -810,26 +874,27 @@ describe('IgxGrid - Filtering actions', () => { // Fill expected results based on the current date fillExpectedResults(grid, cal, today); - filterIcon.triggerEventHandler('mousedown', null); - fix.detectChanges(); filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); verifyFilterUIPosition(filterIcon, grid); + const ddList = fix.debugElement.query(By.css('div.igx-drop-down__list.igx-toggle')); GridFunctions.selectFilteringCondition('Next Month', ddList); - + tick(100); fix.detectChanges(); expect(grid.rowList.length).toEqual(expectedResults[1]); - }); + })); - it('UI - should correctly filter date column by \'last month\' filtering conditions', () => { + it('UI - should correctly filter date column by \'last month\' filtering conditions', fakeAsync(() => { const fix = TestBed.createComponent(IgxGridFilteringComponent); fix.detectChanges(); const grid = fix.componentInstance.grid; const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); filteringCells[4].query(By.css('igx-chip')).nativeElement.click(); + tick(); fix.detectChanges(); const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); const filterIcon = filterUIRow.query(By.css('igx-icon')); @@ -839,118 +904,126 @@ describe('IgxGrid - Filtering actions', () => { // Fill expected results based on the current date fillExpectedResults(grid, cal, today); - filterIcon.triggerEventHandler('mousedown', null); - fix.detectChanges(); filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); verifyFilterUIPosition(filterIcon, grid); + const ddList = fix.debugElement.query(By.css('div.igx-drop-down__list.igx-toggle')); GridFunctions.selectFilteringCondition('Last Month', ddList); - + tick(100); fix.detectChanges(); expect(grid.rowList.length).toEqual(expectedResults[0]); - }); + })); - it('UI - should correctly filter date column by \'empty\' filtering conditions', () => { + it('UI - should correctly filter date column by \'empty\' filtering conditions', fakeAsync(() => { const fix = TestBed.createComponent(IgxGridFilteringComponent); fix.detectChanges(); const grid = fix.componentInstance.grid; const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); filteringCells[4].query(By.css('igx-chip')).nativeElement.click(); + tick(); fix.detectChanges(); const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); const filterIcon = filterUIRow.query(By.css('igx-icon')); - filterIcon.triggerEventHandler('mousedown', null); - fix.detectChanges(); filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); verifyFilterUIPosition(filterIcon, grid); + const ddList = fix.debugElement.query(By.css('div.igx-drop-down__list.igx-toggle')); GridFunctions.selectFilteringCondition('Empty', ddList); + tick(100); fix.detectChanges(); - expect(grid.rowList.length).toEqual(2); - }); + })); - it('UI - should correctly filter date column by \'notEmpty\' filtering conditions', () => { + it('UI - should correctly filter date column by \'notEmpty\' filtering conditions', fakeAsync(() => { const fix = TestBed.createComponent(IgxGridFilteringComponent); fix.detectChanges(); const grid = fix.componentInstance.grid; const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); filteringCells[4].query(By.css('igx-chip')).nativeElement.click(); + tick(); fix.detectChanges(); const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); const filterIcon = filterUIRow.query(By.css('igx-icon')); - filterIcon.triggerEventHandler('mousedown', null); - fix.detectChanges(); filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); verifyFilterUIPosition(filterIcon, grid); + const ddList = fix.debugElement.query(By.css('div.igx-drop-down__list.igx-toggle')); GridFunctions.selectFilteringCondition('Not Empty', ddList); + tick(100); fix.detectChanges(); expect(grid.rowList.length).toEqual(6); - }); + })); - it('UI - should correctly filter date column by \'null\' filtering conditions', () => { + it('UI - should correctly filter date column by \'null\' filtering conditions', fakeAsync(() => { const fix = TestBed.createComponent(IgxGridFilteringComponent); fix.detectChanges(); const grid = fix.componentInstance.grid; const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); filteringCells[4].query(By.css('igx-chip')).nativeElement.click(); + tick(); fix.detectChanges(); const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); const filterIcon = filterUIRow.query(By.css('igx-icon')); - filterIcon.triggerEventHandler('mousedown', null); - fix.detectChanges(); filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); verifyFilterUIPosition(filterIcon, grid); + const ddList = fix.debugElement.query(By.css('div.igx-drop-down__list.igx-toggle')); GridFunctions.selectFilteringCondition('Null', ddList); + tick(100); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); - }); + })); - it('UI - should correctly filter date column by \'notNull\' filtering conditions', () => { + it('UI - should correctly filter date column by \'notNull\' filtering conditions', fakeAsync(() => { const fix = TestBed.createComponent(IgxGridFilteringComponent); fix.detectChanges(); const grid = fix.componentInstance.grid; const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); filteringCells[4].query(By.css('igx-chip')).nativeElement.click(); + tick(); fix.detectChanges(); const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); const filterIcon = filterUIRow.query(By.css('igx-icon')); - filterIcon.triggerEventHandler('mousedown', null); - fix.detectChanges(); filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); verifyFilterUIPosition(filterIcon, grid); + const ddList = fix.debugElement.query(By.css('div.igx-drop-down__list.igx-toggle')); GridFunctions.selectFilteringCondition('Not Null', ddList); + tick(100); fix.detectChanges(); expect(grid.rowList.length).toEqual(7); - }); + })); - it('UI - should correctly filter date column by \'thisYear\' filtering conditions', () => { + it('UI - should correctly filter date column by \'thisYear\' filtering conditions', fakeAsync(() => { const fix = TestBed.createComponent(IgxGridFilteringComponent); fix.detectChanges(); const grid = fix.componentInstance.grid; const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); filteringCells[4].query(By.css('igx-chip')).nativeElement.click(); + tick(); fix.detectChanges(); const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); const filterIcon = filterUIRow.query(By.css('igx-icon')); @@ -960,25 +1033,26 @@ describe('IgxGrid - Filtering actions', () => { // Fill expected results based on the current date fillExpectedResults(grid, cal, today); - filterIcon.triggerEventHandler('mousedown', null); - fix.detectChanges(); filterIcon.nativeElement.click(); fix.detectChanges(); verifyFilterUIPosition(filterIcon, grid); + const ddList = fix.debugElement.query(By.css('div.igx-drop-down__list.igx-toggle')); GridFunctions.selectFilteringCondition('This Year', ddList); + tick(100); fix.detectChanges(); expect(grid.rowList.length).toEqual(expectedResults[2]); - }); + })); - it('UI - should correctly filter date column by \'lastYear\' filtering conditions', () => { + it('UI - should correctly filter date column by \'lastYear\' filtering conditions', fakeAsync(() => { const fix = TestBed.createComponent(IgxGridFilteringComponent); fix.detectChanges(); const grid = fix.componentInstance.grid; const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); filteringCells[4].query(By.css('igx-chip')).nativeElement.click(); + tick(); fix.detectChanges(); const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); const filterIcon = filterUIRow.query(By.css('igx-icon')); @@ -988,25 +1062,27 @@ describe('IgxGrid - Filtering actions', () => { // Fill expected results based on the current date fillExpectedResults(grid, cal, today); - filterIcon.triggerEventHandler('mousedown', null); - fix.detectChanges(); filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); verifyFilterUIPosition(filterIcon, grid); + const ddList = fix.debugElement.query(By.css('div.igx-drop-down__list.igx-toggle')); GridFunctions.selectFilteringCondition('Last Year', ddList); + tick(100); fix.detectChanges(); expect(grid.rowList.length).toEqual(expectedResults[4]); - }); + })); - it('UI - should correctly filter date column by \'nextYear\' filtering conditions', () => { + it('UI - should correctly filter date column by \'nextYear\' filtering conditions', fakeAsync(() => { const fix = TestBed.createComponent(IgxGridFilteringComponent); fix.detectChanges(); const grid = fix.componentInstance.grid; const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); filteringCells[4].query(By.css('igx-chip')).nativeElement.click(); + tick(); fix.detectChanges(); const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); const filterIcon = filterUIRow.query(By.css('igx-icon')); @@ -1016,17 +1092,18 @@ describe('IgxGrid - Filtering actions', () => { // Fill expected results based on the current date fillExpectedResults(grid, cal, today); - filterIcon.triggerEventHandler('mousedown', null); - fix.detectChanges(); filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); verifyFilterUIPosition(filterIcon, grid); + const ddList = fix.debugElement.query(By.css('div.igx-drop-down__list.igx-toggle')); GridFunctions.selectFilteringCondition('Next Year', ddList); + tick(100); fix.detectChanges(); expect(grid.rowList.length).toEqual(expectedResults[3]); - }); + })); it('UI - should correctly filter date column by \'equals\' filtering conditions', fakeAsync(() => { const fix = TestBed.createComponent(IgxGridFilteringComponent); @@ -1036,32 +1113,31 @@ describe('IgxGrid - Filtering actions', () => { const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); filteringCells[4].query(By.css('igx-chip')).nativeElement.click(); fix.detectChanges(); + const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); const filterIcon = filterUIRow.query(By.css('igx-icon')); const input = filterUIRow.query(By.directive(IgxInputDirective)); - filterIcon.triggerEventHandler('mousedown', null); - fix.detectChanges(); filterIcon.nativeElement.click(); fix.detectChanges(); - tick(100); verifyFilterUIPosition(filterIcon, grid); const ddList = fix.debugElement.query(By.css('div.igx-drop-down__list.igx-toggle')); GridFunctions.selectFilteringCondition('Equals', ddList); + input.nativeElement.click(); - fix.detectChanges(); tick(); + fix.detectChanges(); const calendar = fix.debugElement.query(By.css('igx-calendar')); const currentDay = calendar.query(By.css('span.igx-calendar__date--current')); currentDay.nativeElement.click(); + flush(); fix.detectChanges(); - tick(); input.nativeElement.dispatchEvent(new Event('change')); - fix.detectChanges(); tick(); + fix.detectChanges(); expect(grid.rowList.length).toEqual(1); })); @@ -1074,37 +1150,37 @@ describe('IgxGrid - Filtering actions', () => { const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); filteringCells[4].query(By.css('igx-chip')).nativeElement.click(); fix.detectChanges(); + const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); const filterIcon = filterUIRow.query(By.css('igx-icon')); const input = filterUIRow.query(By.directive(IgxInputDirective)); - filterIcon.triggerEventHandler('mousedown', null); - fix.detectChanges(); filterIcon.nativeElement.click(); - tick(100); + tick(); + fix.detectChanges(); verifyFilterUIPosition(filterIcon, grid); - fix.detectChanges(); const ddList = fix.debugElement.query(By.css('div.igx-drop-down__list.igx-toggle')); GridFunctions.selectFilteringCondition('Does Not Equal', ddList); + input.nativeElement.click(); - fix.detectChanges(); tick(); + fix.detectChanges(); const calendar = fix.debugElement.query(By.css('igx-calendar')); const currentDay = calendar.query(By.css('span.igx-calendar__date--current')); currentDay.nativeElement.click(); + flush(); fix.detectChanges(); - tick(); input.nativeElement.dispatchEvent(new Event('change')); - fix.detectChanges(); tick(); + fix.detectChanges(); expect(grid.rowList.length).toEqual(7); })); - it('UI - should correctly filter date column by \'after\' filtering conditions', fakeAsync(() => { + it('UI - should correctly filter date column by \'after\' filtering conditions', async() => { const fix = TestBed.createComponent(IgxGridFilteringComponent); fix.detectChanges(); @@ -1112,35 +1188,44 @@ describe('IgxGrid - Filtering actions', () => { const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); filteringCells[4].query(By.css('igx-chip')).nativeElement.click(); fix.detectChanges(); + const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); const filterIcon = filterUIRow.query(By.css('igx-icon')); const input = filterUIRow.query(By.directive(IgxInputDirective)); - filterIcon.triggerEventHandler('mousedown', null); - fix.detectChanges(); filterIcon.nativeElement.click(); fix.detectChanges(); - tick(100); + await wait(); verifyFilterUIPosition(filterIcon, grid); + const ddList = fix.debugElement.query(By.css('div.igx-drop-down__list.igx-toggle')); - GridFunctions.selectFilteringCondition('After', ddList); + const ddItems = ddList.nativeElement.children; + let i; + for (i = 0; i < ddItems.length; i++) { + if (ddItems[i].textContent === 'After') { + ddItems[i].click(); + await wait(100); + return; + } + } + input.nativeElement.click(); fix.detectChanges(); - tick(); + await wait(100); const calendar = fix.debugElement.query(By.css('igx-calendar')); const currentDay = calendar.query(By.css('span.igx-calendar__date--current')); currentDay.nativeElement.click(); fix.detectChanges(); - tick(); + await wait(); input.nativeElement.dispatchEvent(new Event('change')); fix.detectChanges(); - tick(); + await wait(); expect(grid.rowList.length).toEqual(3); - })); + }); it('UI - should correctly filter date column by \'before\' filtering conditions', fakeAsync(() => { const fix = TestBed.createComponent(IgxGridFilteringComponent); @@ -1150,32 +1235,32 @@ describe('IgxGrid - Filtering actions', () => { const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); filteringCells[4].query(By.css('igx-chip')).nativeElement.click(); fix.detectChanges(); + const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); const filterIcon = filterUIRow.query(By.css('igx-icon')); const input = filterUIRow.query(By.directive(IgxInputDirective)); - filterIcon.triggerEventHandler('mousedown', null); - fix.detectChanges(); filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); - tick(100); verifyFilterUIPosition(filterIcon, grid); const ddList = fix.debugElement.query(By.css('div.igx-drop-down__list.igx-toggle')); GridFunctions.selectFilteringCondition('Before', ddList); + input.nativeElement.click(); - fix.detectChanges(); tick(); + fix.detectChanges(); const calendar = fix.debugElement.query(By.css('igx-calendar')); const currentDay = calendar.query(By.css('span.igx-calendar__date--current')); currentDay.nativeElement.click(); + flush(); fix.detectChanges(); - tick(); input.nativeElement.dispatchEvent(new Event('change')); - fix.detectChanges(); tick(); + fix.detectChanges(); expect(grid.rowList.length).toEqual(2); })); @@ -1185,31 +1270,30 @@ describe('IgxGrid - Filtering actions', () => { fix.detectChanges(); const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); filteringCells[4].query(By.css('igx-chip')).nativeElement.click(); + tick(); fix.detectChanges(); const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); const filterIcon = filterUIRow.query(By.css('igx-icon')); const input = filterUIRow.query(By.directive(IgxInputDirective)); - filterIcon.triggerEventHandler('mousedown', null); - fix.detectChanges(); filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); - tick(100); input.nativeElement.click(); - fix.detectChanges(); tick(); + fix.detectChanges(); let calendar = fix.debugElement.query(By.css('igx-calendar')); const monthView = calendar.queryAll(By.css('.date__el'))[0]; monthView.nativeElement.click(); - fix.detectChanges(); tick(); + fix.detectChanges(); const firstMonth = calendar.queryAll(By.css('.igx-calendar__month'))[0]; firstMonth.nativeElement.click(); - fix.detectChanges(); tick(); + fix.detectChanges(); calendar = fix.debugElement.query(By.css('igx-calendar')); const month = calendar.queryAll(By.css('.date__el'))[0]; @@ -1222,31 +1306,30 @@ describe('IgxGrid - Filtering actions', () => { fix.detectChanges(); const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); filteringCells[4].query(By.css('igx-chip')).nativeElement.click(); + tick(); fix.detectChanges(); const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); const filterIcon = filterUIRow.query(By.css('igx-icon')); const input = filterUIRow.query(By.directive(IgxInputDirective)); - filterIcon.triggerEventHandler('mousedown', null); - fix.detectChanges(); filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); - tick(100); input.nativeElement.click(); - fix.detectChanges(); tick(); + fix.detectChanges(); let calendar = fix.debugElement.query(By.css('igx-calendar')); const monthView = calendar.queryAll(By.css('.date__el'))[1]; monthView.nativeElement.click(); - fix.detectChanges(); tick(); + fix.detectChanges(); const firstMonth = calendar.queryAll(By.css('.igx-calendar__year'))[0]; firstMonth.nativeElement.click(); - fix.detectChanges(); tick(); + fix.detectChanges(); calendar = fix.debugElement.query(By.css('igx-calendar')); const month = calendar.queryAll(By.css('.date__el'))[1]; @@ -1265,6 +1348,7 @@ describe('IgxGrid - Filtering actions', () => { const grid = fix.componentInstance.grid; const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); filteringCells[5].query(By.css('igx-chip')).nativeElement.click(); + tick(); fix.detectChanges(); const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); const filterIcon = filterUIRow.query(By.css('igx-icon')); @@ -1276,18 +1360,18 @@ describe('IgxGrid - Filtering actions', () => { expect(grid.rowList.length).toEqual(8); filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); - tick(100); sendInput(input, 'a', fix); - fix.detectChanges(); tick(); + fix.detectChanges(); const ddList = fix.debugElement.query(By.css('div.igx-drop-down__list.igx-toggle')); // false condition GridFunctions.selectFilteringCondition('False', ddList); + tick(100); fix.detectChanges(); - tick(); expect(grid.rowList.length).toEqual(1); expect(grid.getCellByColumn(0, 'AnotherField').value).toMatch('custom'); @@ -1304,6 +1388,7 @@ describe('IgxGrid - Filtering actions', () => { const columnName = 'ProductName'; grid.filter(columnName, filterVal, IgxStringFilteringOperand.instance().condition('contains')); + tick(100); fix.detectChanges(); const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); @@ -1312,15 +1397,17 @@ describe('IgxGrid - Filtering actions', () => { spyOn(grid.onFilteringDone, 'emit'); idCellChips[0].nativeElement.click(); + tick(); fix.detectChanges(); + const filterUiRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); const reset = filterUiRow.queryAll(By.css('button'))[0]; const input = filterUiRow.query(By.directive(IgxInputDirective)); sendInput(input, filterVal, fix); reset.nativeElement.dispatchEvent(new MouseEvent('click')); - fix.detectChanges(); tick(100); + fix.detectChanges(); expect(grid.onFilteringDone.emit).toHaveBeenCalledWith(null); })); @@ -1330,12 +1417,13 @@ describe('IgxGrid - Filtering actions', () => { fix.detectChanges(); const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); filteringCells[1].query(By.css('igx-chip')).nativeElement.click(); + tick(); fix.detectChanges(); const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); const filterIcon = filterUIRow.query(By.css('igx-icon')); UIInteractions.clickElement(filterIcon); - tick(50); + tick(); fix.detectChanges(); // apply two filters for And/Or button @@ -1344,7 +1432,7 @@ describe('IgxGrid - Filtering actions', () => { const andButton = fix.debugElement.queryAll(By.css('#operand')); - tick(50); + tick(100); fix.detectChanges(); expect(andButton.length).toEqual(1); @@ -1359,6 +1447,7 @@ describe('IgxGrid - Filtering actions', () => { const grid = fix.componentInstance.grid; const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); filteringCells[1].query(By.css('igx-chip')).nativeElement.click(); + tick(); fix.detectChanges(); const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); const filterIcon = filterUIRow.query(By.css('igx-icon')); @@ -1366,21 +1455,18 @@ describe('IgxGrid - Filtering actions', () => { expect(grid.rowList.length).toEqual(8); filterIcon.nativeElement.click(); + tick(); fix.detectChanges(); - tick(100); verifyFilterUIPosition(filterUIRow, grid); GridFunctions.filterBy('Contains', 'I', fix); + tick(100); fix.detectChanges(); - tick(); - - fix.detectChanges(); - tick(); GridFunctions.filterBy('Contains', 'g', fix); + tick(100); fix.detectChanges(); - tick(); expect(grid.rowList.length).toEqual(2); let andButton = fix.debugElement.queryAll(By.css('#operand')); @@ -1389,8 +1475,8 @@ describe('IgxGrid - Filtering actions', () => { // remove the second chip const secondChip = filterUIRow.queryAll(By.css('igx-chip'))[1]; secondChip.query(By.css('div.igx-chip__remove')).nativeElement.click(); - fix.detectChanges(); tick(); + fix.detectChanges(); expect(grid.rowList.length).toEqual(3); andButton = fix.debugElement.queryAll(By.css('#operand')); @@ -1405,10 +1491,12 @@ describe('IgxGrid - Filtering actions', () => { const columnName = 'ProductName'; const filterValue = 'search'; grid.filter(columnName, filterValue, IgxStringFilteringOperand.instance().condition('contains')); + tick(100); fix.detectChanges(); const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); filteringCells[1].query(By.css('igx-chip')).nativeElement.click(); + tick(); fix.detectChanges(); const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); const input = filterUIRow.query(By.directive(IgxInputDirective)); @@ -1421,8 +1509,8 @@ describe('IgxGrid - Filtering actions', () => { clearSuffix.nativeElement.dispatchEvent(new MouseEvent('click')); GridFunctions.simulateKeyboardEvent(input, 'keydown', 'Enter'); - fix.detectChanges(); tick(100); + fix.detectChanges(); const columnFilteringExpressionsTree = grid.filteringExpressionsTree.find(columnName); expect(grid.onFilteringDone.emit).toHaveBeenCalledWith(columnFilteringExpressionsTree); @@ -1437,6 +1525,7 @@ describe('IgxGrid - Filtering actions', () => { const headerOfTypeNumber = gridheaders.find(gh => gh.nativeElement.classList.contains('igx-grid__th--number')); const filterCellsForTypeNumber = headerOfTypeNumber.parent.query(By.css('igx-grid-filtering-cell')); filterCellsForTypeNumber.query(By.css('igx-chip')).nativeElement.click(); + tick(); fix.detectChanges(); const filterUiRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); @@ -1444,21 +1533,19 @@ describe('IgxGrid - Filtering actions', () => { const input = filterUiRow.query(By.directive(IgxInputDirective)); filterIcon.nativeElement.click(); - fix.detectChanges(); tick(); fix.detectChanges(); sendInput(input, 0, fix); - fix.detectChanges(); tick(); fix.detectChanges(); grid.nativeElement.click(); - fix.detectChanges(); tick(); fix.detectChanges(); filterUiRow.queryAll(By.css('button'))[1].nativeElement.click(); + tick(); fix.detectChanges(); expect(filterCellsForTypeNumber.queryAll(By.css('.igx-filtering-chips')).length).toBe(1); })); @@ -1479,20 +1566,23 @@ describe('IgxGrid - Filtering actions', () => { filteringExpressionsTree.filteringOperands.push(expression); grid.filteringExpressionsTree = filteringExpressionsTree; + tick(100); fix.detectChanges(); expect(grid.rowList.length).toEqual(2); const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); filteringCells[1].query(By.css('igx-chip')).nativeElement.click(); + tick(); fix.detectChanges(); + const filterUIContainer = fix.debugElement.queryAll(By.css(FILTER_UI_ROW))[0]; const filterIcon = filterUIContainer.query(By.css('igx-icon')); const input = filterUIContainer.query(By.directive(IgxInputDirective)); filterIcon.nativeElement.click(); - fix.detectChanges(); tick(100); + fix.detectChanges(); verifyFilterUIPosition(filterUIContainer, grid); @@ -1512,40 +1602,31 @@ describe('IgxGrid - Filtering Row UI actions', () => { IgxGridFilteringMCHComponent ], imports: [ - BrowserAnimationsModule, + NoopAnimationsModule, IgxGridModule.forRoot()] - }) - .compileComponents(); + }).compileComponents(); })); afterEach(() => { UIInteractions.clearOverlay(); }); - // TODO - add new tests based on the test plan in the spec. - it('should render Filter chip for filterable columns and render empty cell for a column when filterable is set to false', fakeAsync(() => { const fix = TestBed.createComponent(IgxGridFilteringComponent); fix.detectChanges(); - tick(100); + const grid = fix.componentInstance.grid; grid.width = '1500px'; fix.detectChanges(); + const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); const filteringChips = fix.debugElement.queryAll(By.css('.igx-filtering-chips')); expect(filteringCells.length).toBe(6); expect(filteringChips.length).toBe(5); - let idCellChips = filteringCells[0].queryAll(By.css('.igx-filtering-chips')); + const idCellChips = filteringCells[0].queryAll(By.css('.igx-filtering-chips')); expect(idCellChips.length).toBe(0); - - grid.getColumnByName('ID').filterable = true; - fix.detectChanges(); - tick(100); - - idCellChips = filteringCells[0].queryAll(By.css('.igx-filtering-chips')); - expect(idCellChips.length).toBe(1); })); it('should render correct input and dropdown in filter row for different column types', fakeAsync(() => { @@ -1560,7 +1641,6 @@ describe('IgxGrid - Filtering Row UI actions', () => { // open for string stringCellChip.nativeElement.click(); fix.detectChanges(); - tick(200); checkUIForType('string', fix.debugElement); @@ -1568,40 +1648,44 @@ describe('IgxGrid - Filtering Row UI actions', () => { let filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); let close = filterUIRow.queryAll(By.css('button'))[1]; close.nativeElement.click(); + tick(100); fix.detectChanges(); - tick(200); // open for number numberCellChip.nativeElement.click(); fix.detectChanges(); - tick(200); checkUIForType('number', fix.debugElement); // close filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); close = filterUIRow.queryAll(By.css('button'))[1]; close.nativeElement.click(); + tick(100); fix.detectChanges(); - tick(200); // open for date dateCellChip.nativeElement.click(); fix.detectChanges(); - tick(200); checkUIForType('date', fix.debugElement); // close filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); close = filterUIRow.queryAll(By.css('button'))[1]; close.nativeElement.click(); + tick(100); fix.detectChanges(); - tick(200); // open for bool boolCellChip.nativeElement.click(); fix.detectChanges(); - tick(200); checkUIForType('bool', fix.debugElement); + + // close + filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); + close = filterUIRow.queryAll(By.css('button'))[1]; + close.nativeElement.click(); + tick(100); + fix.detectChanges(); })); it('should apply multiple conditions to grid immediately while the filter row is still open', fakeAsync(() => { @@ -1614,9 +1698,9 @@ describe('IgxGrid - Filtering Row UI actions', () => { const boolCellChip = filteringCells[3].query(By.css('igx-chip')); const dateCellChip = filteringCells[4].query(By.css('igx-chip')); const grid = fix.componentInstance.grid; + // open for string stringCellChip.nativeElement.click(); - tick(); fix.detectChanges(); GridFunctions.filterBy('Starts With', 'I', fix); @@ -1630,7 +1714,6 @@ describe('IgxGrid - Filtering Row UI actions', () => { // open for number numberCellChip.nativeElement.click(); - tick(); fix.detectChanges(); GridFunctions.filterBy('Less Than', '100', fix); @@ -1641,15 +1724,15 @@ describe('IgxGrid - Filtering Row UI actions', () => { // Reset and Close GridFunctions.resetFilterRow(fix); GridFunctions.closeFilterRow(fix); + // open for bool boolCellChip.nativeElement.click(); - tick(); fix.detectChanges(); GridFunctions.filterBy('False', '', fix); expect(grid.rowList.length).toEqual(2); GridFunctions.filterBy('Empty', '', fix); - expect(grid.rowList.length).toEqual(0); + expect(grid.rowList.length).toEqual(3); // Reset and Close GridFunctions.resetFilterRow(fix); @@ -1658,6 +1741,7 @@ describe('IgxGrid - Filtering Row UI actions', () => { // open for date dateCellChip.nativeElement.click(); fix.detectChanges(); + GridFunctions.filterBy('Today', '', fix); expect(grid.rowList.length).toEqual(1); GridFunctions.filterBy('Null', '', fix); @@ -1677,7 +1761,6 @@ describe('IgxGrid - Filtering Row UI actions', () => { for (let i = 0; i < 10; i++) { GridFunctions.filterBy('Starts With', 'I', fix); - tick(200); } const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); const startArrow = filterUIRow.query(By.css('.igx-grid__filtering-row-scroll-start')); @@ -1690,13 +1773,15 @@ describe('IgxGrid - Filtering Row UI actions', () => { it('should update UI when chip is removed from header cell.', fakeAsync(() => { const fix = TestBed.createComponent(IgxGridFilteringComponent); fix.detectChanges(); + let filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); let stringCellChip = filteringCells[1].query(By.css('igx-chip')); const grid = fix.componentInstance.grid; + // filter string col stringCellChip.nativeElement.click(); - tick(); fix.detectChanges(); + GridFunctions.filterBy('Starts With', 'I', fix); expect(grid.rowList.length).toEqual(2); @@ -1708,7 +1793,6 @@ describe('IgxGrid - Filtering Row UI actions', () => { // remove chip const removeButton = stringCellChip.query(By.css('div.igx-chip__remove')); removeButton.nativeElement.click(); - tick(); fix.detectChanges(); expect(grid.rowList.length).toEqual(8); @@ -1717,20 +1801,22 @@ describe('IgxGrid - Filtering Row UI actions', () => { it('should update UI when chip is removed from filter row.', fakeAsync(() => { const fix = TestBed.createComponent(IgxGridFilteringComponent); fix.detectChanges(); + const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); const stringCellChip = filteringCells[1].query(By.css('igx-chip')); const grid = fix.componentInstance.grid; + // filter string col stringCellChip.nativeElement.click(); - tick(); fix.detectChanges(); + GridFunctions.filterBy('Starts With', 'I', fix); expect(grid.rowList.length).toEqual(2); // remove from row const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); GridFunctions.removeFilterChipByIndex(0, filterUIRow); - tick(); + tick(100); fix.detectChanges(); expect(grid.rowList.length).toEqual(8); @@ -1740,22 +1826,26 @@ describe('IgxGrid - Filtering Row UI actions', () => { fakeAsync(() => { const fix = TestBed.createComponent(IgxGridFilteringComponent); fix.detectChanges(); + let filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); const stringCellChip = filteringCells[1].query(By.css('igx-chip')); const grid = fix.componentInstance.grid; + // filter string col stringCellChip.nativeElement.click(); - tick(); fix.detectChanges(); + GridFunctions.filterBy('Starts With', 'I', fix); - // remote text from input + + // remove text from input const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); const input = filterUIRow.query(By.directive(IgxInputDirective)); input.nativeElement.value = null; + const exprList = filterUIRow.componentInstance.expressionsList; exprList[0].expression.searchVal = null; - tick(); fix.detectChanges(); + GridFunctions.closeFilterRow(fix); // check no condition is applied @@ -1808,28 +1898,24 @@ describe('IgxGrid - Filtering Row UI actions', () => { fix.detectChanges(); checkUIForType('string', fix.debugElement); - tick(200); // Click on number column. numberHeader.nativeElement.click(); fix.detectChanges(); checkUIForType('number', fix.debugElement); - tick(200); // Click on boolean column boolHeader.nativeElement.click(); fix.detectChanges(); checkUIForType('bool', fix.debugElement); - tick(200); // Click on date column dateHeader.nativeElement.click(); fix.detectChanges(); checkUIForType('date', fix.debugElement); - tick(200); })); it('Should correctly render read-only input when selecting read-only condition and should create a chip.', fakeAsync(() => { @@ -1916,7 +2002,6 @@ describe('IgxGrid - Filtering Row UI actions', () => { expect(filterChip.componentInstance.selected).toBeTruthy(); GridFunctions.filterBy('Starts With', 'S', fix); - tick(200); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); @@ -1975,6 +2060,7 @@ describe('IgxGrid - Filtering Row UI actions', () => { grid.width = '1600px'; grid.columnWidth = '400px'; fix.detectChanges(); + const filteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.And, 'ProductName'); const expression = { fieldName: 'ProductName', @@ -1990,7 +2076,6 @@ describe('IgxGrid - Filtering Row UI actions', () => { filteringExpressionsTree.filteringOperands.push(expression1); grid.filter('ProductName', null, filteringExpressionsTree); grid.filter('Released', true, IgxBooleanFilteringOperand.instance().condition('false')); - tick(); fix.detectChanges(); expect(grid.rowList.length).toEqual(0); @@ -2021,14 +2106,16 @@ describe('IgxGrid - Filtering Row UI actions', () => { fix.detectChanges(); let filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); + const stringCellChip = filteringCells[1].query(By.css('igx-chip')); // filter string col stringCellChip.nativeElement.click(); - tick(); fix.detectChanges(); + GridFunctions.filterBy('Starts With', 'IgniteUI', fix); GridFunctions.filterBy('Contains', 'for', fix); GridFunctions.closeFilterRow(fix); + // check 1 chip and view more icon is displayed. const chips = filteringCells[1].queryAll(By.css('igx-chip')); expect(chips.length).toEqual(1); @@ -2054,7 +2141,6 @@ describe('IgxGrid - Filtering Row UI actions', () => { ]; gridFilteringExpressionsTree.filteringOperands.push(columnsFilteringTree); grid.filteringExpressionsTree = gridFilteringExpressionsTree; - tick(); fix.detectChanges(); const colChips = GridFunctions.getFilterChipsForColumn('ProductName', fix); @@ -2082,9 +2168,9 @@ describe('IgxGrid - Filtering Row UI actions', () => { const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); const stringCellChip = filteringCells[1].query(By.css('igx-chip')); + // filter string col stringCellChip.nativeElement.click(); - tick(); fix.detectChanges(); const filteringRow = fix.debugElement.query(By.directive(IgxGridFilteringRowComponent)); @@ -2107,7 +2193,7 @@ describe('IgxGrid - Filtering Row UI actions', () => { expect(cellElem.offsetParent.offsetHeight + cellElem.offsetHeight).toBeCloseTo(thead.clientHeight, 10); idCellChip.nativeElement.click(); - tick(); + // tick(); fix.detectChanges(); // check if it is positioned at the bottom of the thead. @@ -2118,7 +2204,10 @@ describe('IgxGrid - Filtering Row UI actions', () => { it('should position filter row and chips correctly when grid has column groups and one is hidden.', fakeAsync(() => { const fix = TestBed.createComponent(IgxGridFilteringMCHComponent); + fix.detectChanges(); + const grid = fix.componentInstance.grid; + const filteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.And, 'ProductName'); const expression = { fieldName: 'ProductName', @@ -2127,7 +2216,6 @@ describe('IgxGrid - Filtering Row UI actions', () => { }; filteringExpressionsTree.filteringOperands.push(expression); grid.filteringExpressionsTree = filteringExpressionsTree; - tick(); fix.detectChanges(); let filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); expect(filteringCells.length).toEqual(6); @@ -2135,12 +2223,12 @@ describe('IgxGrid - Filtering Row UI actions', () => { const groupCol = grid.getColumnByName('General'); groupCol.hidden = true; fix.detectChanges(); + filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); expect(filteringCells.length).toEqual(1); const chip = filteringCells[0].query(By.css('igx-chip')); chip.nativeElement.click(); - tick(); fix.detectChanges(); // check if it is positioned at the bottom of the thead. @@ -2152,7 +2240,6 @@ describe('IgxGrid - Filtering Row UI actions', () => { GridFunctions.closeFilterRow(fix); groupCol.hidden = false; - tick(); fix.detectChanges(); filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); @@ -2165,14 +2252,17 @@ describe('IgxGrid - Filtering Row UI actions', () => { // Filtering + Moving it('should move chip under the correct column when column is moved and filter row should open for correct column.', fakeAsync(() => { const fix = TestBed.createComponent(IgxGridFilteringComponent); - const grid = fix.componentInstance.grid; fix.detectChanges(); + const grid = fix.componentInstance.grid; + let filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); let stringCellChip = filteringCells[1].query(By.css('igx-chip')); + // filter string col stringCellChip.nativeElement.click(); fix.detectChanges(); + GridFunctions.filterBy('Contains', 'Angular', fix); GridFunctions.closeFilterRow(fix); @@ -2208,22 +2298,27 @@ describe('IgxGrid - Filtering Row UI actions', () => { // Filtering + Hiding it('should not display filter cell for hidden columns and chips should show under correct column.', fakeAsync(() => { const fix = TestBed.createComponent(IgxGridFilteringComponent); - const grid = fix.componentInstance.grid; fix.detectChanges(); + const grid = fix.componentInstance.grid; + let filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); let stringCellChip = filteringCells[1].query(By.css('igx-chip')); + // filter string col stringCellChip.nativeElement.click(); fix.detectChanges(); + GridFunctions.filterBy('Contains', 'Angular', fix); GridFunctions.closeFilterRow(fix); + filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); expect(filteringCells.length).toEqual(6); + // hide column grid.getColumnByName('ID').hidden = true; - tick(); fix.detectChanges(); + filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); expect(filteringCells.length).toEqual(5); stringCellChip = filteringCells[0].query(By.css('igx-chip')); @@ -2235,6 +2330,7 @@ describe('IgxGrid - Filtering Row UI actions', () => { grid.getColumnByName('ProductName').hidden = true; fix.detectChanges(); + filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); expect(filteringCells.length).toEqual(4); @@ -2248,14 +2344,17 @@ describe('IgxGrid - Filtering Row UI actions', () => { // Filtering + Grouping it('should display the header expand/collapse icon for groupby above the filter row.', fakeAsync(() => { const fix = TestBed.createComponent(IgxGridFilteringComponent); - const grid = fix.componentInstance.grid; fix.detectChanges(); + + const grid = fix.componentInstance.grid; + grid.getColumnByName('ProductName').groupable = true; grid.groupBy({fieldName: 'ProductName', dir: SortingDirection.Asc, ignoreCase: false, strategy: DefaultSortingStrategy.instance()}); fix.detectChanges(); const filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); const stringCellChip = filteringCells[1].query(By.css('igx-chip')); + // filter string col stringCellChip.nativeElement.click(); fix.detectChanges(); @@ -2270,15 +2369,20 @@ describe('IgxGrid - Filtering Row UI actions', () => { // Filtering + Pinning it('should position chips correctly after pinning column.', fakeAsync(() => { const fix = TestBed.createComponent(IgxGridFilteringComponent); - const grid = fix.componentInstance.grid; fix.detectChanges(); + + const grid = fix.componentInstance.grid; + let filteringCells = fix.debugElement.queryAll(By.css('igx-grid-filtering-cell')); let stringCellChip = filteringCells[1].query(By.css('igx-chip')); + // filter string col stringCellChip.nativeElement.click(); fix.detectChanges(); + GridFunctions.filterBy('Contains', 'Angular', fix); GridFunctions.closeFilterRow(fix); + grid.getColumnByName('ProductName').pinned = true; fix.detectChanges(); @@ -2294,6 +2398,7 @@ describe('IgxGrid - Filtering Row UI actions', () => { const fix = TestBed.createComponent(IgxGridFilteringComponent); const grid = fix.componentInstance.grid; grid.columnWidth = '250px'; + fix.detectChanges(); // Add initial filtering conditions const gridFilteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.And); @@ -2304,11 +2409,6 @@ describe('IgxGrid - Filtering Row UI actions', () => { ]; gridFilteringExpressionsTree.filteringOperands.push(columnsFilteringTree); grid.filteringExpressionsTree = gridFilteringExpressionsTree; - tick(); - fix.detectChanges(); - - // Enable resizing - grid.columns.forEach(col => col.resizable = true); fix.detectChanges(); let colChips = GridFunctions.getFilterChipsForColumn('ProductName', fix); @@ -2319,14 +2419,18 @@ describe('IgxGrid - Filtering Row UI actions', () => { expect(colOperands.length).toEqual(1); expect(colIndicator.length).toEqual(0); + // Enable resizing + fix.componentInstance.resizable = true; + fix.detectChanges(); + // Make 'ProductName' column smaller - const headers: DebugElement[] = fix.debugElement.queryAll(By.directive(IgxGridHeaderComponent)); - const headerResArea = headers[1].nativeElement.children[2]; + const headers: DebugElement[] = fix.debugElement.queryAll(By.directive(IgxGridHeaderGroupComponent)); + const headerResArea = headers[1].children[2].nativeElement; UIInteractions.simulateMouseEvent('mousedown', headerResArea, 200, 0); tick(); fix.detectChanges(); - const resizer = headers[1].nativeElement.children[2].children[0]; + const resizer = headers[1].children[2].children[0].nativeElement; expect(resizer).toBeDefined(); UIInteractions.simulateMouseEvent('mousemove', resizer, 100, 5); tick(); @@ -2365,8 +2469,8 @@ describe('IgxGrid - Filtering Row UI actions', () => { stringCellChip.click(); fix.detectChanges(); - const headers: DebugElement[] = fix.debugElement.queryAll(By.directive(IgxGridHeaderComponent)); - const headerResArea = headers[1].nativeElement.children[2]; + const headers: DebugElement[] = fix.debugElement.queryAll(By.directive(IgxGridHeaderGroupComponent)); + const headerResArea = headers[1].children[2].nativeElement; let filteringRow = fix.debugElement.query(By.directive(IgxGridFilteringRowComponent)); expect(filteringRow).toBeTruthy(); @@ -2376,7 +2480,7 @@ describe('IgxGrid - Filtering Row UI actions', () => { tick(); fix.detectChanges(); - const resizer = headers[1].nativeElement.children[2].children[0]; + const resizer = headers[1].children[2].children[0].nativeElement; expect(resizer).toBeDefined(); UIInteractions.simulateMouseEvent('mousemove', resizer, 100, 5); tick(); @@ -2425,13 +2529,13 @@ describe('IgxGrid - Filtering Row UI actions', () => { expect(indicatorBadge.nativeElement.innerText.trim()).toEqual('2'); // Make 'Downloads' column bigger - const headers: DebugElement[] = fix.debugElement.queryAll(By.directive(IgxGridHeaderComponent)); - const headerResArea = headers[2].nativeElement.children[2]; + const headers: DebugElement[] = fix.debugElement.queryAll(By.directive(IgxGridHeaderGroupComponent)); + const headerResArea = headers[2].children[2].nativeElement; UIInteractions.simulateMouseEvent('mousedown', headerResArea, 100, 0); tick(); fix.detectChanges(); - const resizer = headers[2].nativeElement.children[2].children[0]; + const resizer = headers[2].children[2].children[0].nativeElement; expect(resizer).toBeDefined(); UIInteractions.simulateMouseEvent('mousemove', resizer, 300, 5); tick(); @@ -2495,15 +2599,15 @@ export class CustomFilter extends IgxFilteringOperand { @Component({ template: ` - - - - + + + + + dataType="date" [resizable]="resizable"> + dataType="string" [filters]="customFilter" [resizable]="resizable"> ` }) @@ -2512,6 +2616,7 @@ export class IgxGridFilteringComponent { public timeGenerator: Calendar = new Calendar(); public today: Date = new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate(), 0, 0, 0); public customFilter = CustomFilter; + public resizable = false; public data = [ { diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid.component.html b/projects/igniteui-angular/src/lib/grids/grid/grid.component.html index aba84aec6df..6a3ae954eaf 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid.component.html +++ b/projects/igniteui-angular/src/lib/grids/grid/grid.component.html @@ -40,7 +40,7 @@
- +
@@ -54,22 +54,12 @@ -
- - -
+
-
- - -
+
diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid.component.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid.component.spec.ts index 70540b52f20..8b9fb8df079 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid.component.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid.component.spec.ts @@ -32,6 +32,7 @@ const DEBOUNCETIME = 30; describe('IgxGrid Component Tests', () => { const MIN_COL_WIDTH = '136px'; const COLUMN_HEADER_CLASS = '.igx-grid__th'; + const COLUMN_HEADER_GROUP_CLASS = '.igx-grid__thead-item'; const CELL_CLASS = '.igx-grid__td'; const ROW_CLASS = '.igx-grid__tr'; const ROW_EDITING_OUTLET_CLASS = '.igx-grid__row-editing-outlet'; @@ -2345,13 +2346,13 @@ describe('IgxGrid Component Tests', () => { column.resizable = true; fix.detectChanges(); - const headers: DebugElement[] = fix.debugElement.queryAll(By.css(COLUMN_HEADER_CLASS)); - const headerResArea = headers[2].nativeElement.children[2]; + const headers: DebugElement[] = fix.debugElement.queryAll(By.css(COLUMN_HEADER_GROUP_CLASS)); + const headerResArea = headers[2].children[1].nativeElement; UIInteractions.simulateMouseEvent('mousedown', headerResArea, 500, 0); tick(); fix.detectChanges(); - const resizer = headers[2].nativeElement.children[2].children[0]; + const resizer = headers[2].children[1].children[0].nativeElement; expect(resizer).toBeDefined(); UIInteractions.simulateMouseEvent('mousemove', resizer, 550, 0); tick(); diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid.component.ts b/projects/igniteui-angular/src/lib/grids/grid/grid.component.ts index 1b9d51a3c25..436535c06b0 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid.component.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid.component.ts @@ -24,6 +24,7 @@ import { IgxColumnComponent } from '../column.component'; import { takeUntil } from 'rxjs/operators'; import { IgxFilteringService } from '../filtering/grid-filtering.service'; import { IGroupingExpression } from '../../data-operations/grouping-expression.interface'; +import { IgxColumnResizingService } from '../grid-column-resizing.service'; let NEXT_ID = 0; @@ -58,7 +59,7 @@ export interface IGroupingDoneEventArgs { providers: [IgxGridNavigationService, { provide: GridBaseAPIService, useClass: IgxGridAPIService }, { provide: IgxGridBaseComponent, useExisting: forwardRef(() => IgxGridComponent) }, - IgxFilteringService + IgxFilteringService, IgxColumnResizingService ], selector: 'igx-grid', templateUrl: './grid.component.html' diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid.groupby.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid.groupby.spec.ts index 46f002903af..45136802b05 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid.groupby.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid.groupby.spec.ts @@ -22,6 +22,7 @@ import { MultiColumnHeadersWithGroupingComponent } from '../../test-utils/grid-s describe('IgxGrid - GroupBy', () => { configureTestSuite(); const COLUMN_HEADER_CLASS = '.igx-grid__th'; + const COLUMN_HEADER_GROUP_CLASS = '.igx-grid__thead-item'; const CELL_CSS_CLASS = '.igx-grid__td'; const SORTING_ICON_ASC_CONTENT = 'arrow_upward'; const SORTING_ICON_DESC_CONTENT = 'arrow_downward'; @@ -1480,8 +1481,8 @@ describe('IgxGrid - GroupBy', () => { expect(grRow.element.nativeElement.clientWidth).toEqual(1200); } - const headers = fix.debugElement.queryAll(By.css(COLUMN_HEADER_CLASS)); - const headerResArea = headers[0].nativeElement.children[2]; + const headers = fix.debugElement.queryAll(By.css(COLUMN_HEADER_GROUP_CLASS)); + const headerResArea = headers[0].children[1].nativeElement; UIInteractions.simulateMouseEvent('mouseover', headerResArea, 200, 5); UIInteractions.simulateMouseEvent('mousedown', headerResArea, 200, 5); UIInteractions.simulateMouseEvent('mouseup', headerResArea, 200, 5); @@ -1491,7 +1492,7 @@ describe('IgxGrid - GroupBy', () => { tick(100); fix.detectChanges(); - const resizer = headers[0].nativeElement.children[2].children[0]; + const resizer = headers[0].children[1].children[0].nativeElement; expect(resizer).toBeDefined(); UIInteractions.simulateMouseEvent('mousemove', resizer, 550, 5); tick(100); diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid.pinning.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid.pinning.spec.ts index 81ab5b4c49f..f3f0d5bf48f 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid.pinning.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid.pinning.spec.ts @@ -14,6 +14,7 @@ import { wait, UIInteractions } from '../../test-utils/ui-interactions.spec'; import { IgxStringFilteringOperand } from '../../data-operations/filtering-condition'; import { DefaultSortingStrategy } from '../../data-operations/sorting-strategy'; import { configureTestSuite } from '../../test-utils/configure-suite'; +import { IgxGridHeaderGroupComponent } from '../grid-header-group.component'; describe('IgxGrid - Column Pinning ', () => { configureTestSuite(); @@ -579,7 +580,7 @@ describe('IgxGrid - Column Pinning ', () => { fix.detectChanges(); const grid = fix.componentInstance.instance; - let headers = fix.debugElement.queryAll(By.directive(IgxGridHeaderComponent)); + let headers = fix.debugElement.queryAll(By.directive(IgxGridHeaderGroupComponent)); // First two headers are pinned expect(headers[0].componentInstance.zIndex).toEqual(9999); @@ -590,7 +591,7 @@ describe('IgxGrid - Column Pinning ', () => { fix.detectChanges(); // First three headers are pinned - headers = fix.debugElement.queryAll(By.directive(IgxGridHeaderComponent)); + headers = fix.debugElement.queryAll(By.directive(IgxGridHeaderGroupComponent)); expect(headers[2].componentInstance.zIndex).toEqual(9997); })); diff --git a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-cell.component.ts b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-cell.component.ts index 56983517c7b..18a4ebac380 100644 --- a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-cell.component.ts +++ b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-cell.component.ts @@ -3,7 +3,7 @@ import { IgxGridCellComponent } from '../cell.component'; import { IgxTreeGridAPIService } from './tree-grid-api.service'; import { GridBaseAPIService } from '../api.service'; import { IgxSelectionAPIService } from '../../core/selection'; -import { valToPxlsUsingRange } from '../../core/utils'; +import { getNodeSizeViaRange } from '../../core/utils'; import { DOCUMENT } from '@angular/common'; import { IgxGridBaseComponent } from '../grid'; @@ -86,7 +86,7 @@ export class IgxTreeGridCellComponent extends IgxGridCellComponent { leftPadding = parseFloat(indentationStyle.paddingLeft); } const largestWidth = Math.max(...Array.from(this.nativeElement.children) - .map((child) => valToPxlsUsingRange(range, child))); + .map((child) => getNodeSizeViaRange(range, child))); return largestWidth + indicatorWidth + indicatorMargin + leftPadding; } } diff --git a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-indentation.spec.ts b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-indentation.spec.ts index e954d89bbe7..d72b9b32609 100644 --- a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-indentation.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-indentation.spec.ts @@ -131,7 +131,7 @@ describe('IgxTreeGrid - Indentation', () => { fix.detectChanges(); const header = TreeGridFunctions.getHeaderCell(fix, 'ID'); - const resizer = header.query(By.css('.igx-grid__th-resize-handle')).nativeElement; + const resizer = header.parent.query(By.css('.igx-grid__th-resize-handle')).nativeElement; // Verify before resizing width expect((header.nativeElement).getBoundingClientRect().width).toBe(225); @@ -284,7 +284,7 @@ describe('IgxTreeGrid - Indentation', () => { fix.detectChanges(); const header = TreeGridFunctions.getHeaderCell(fix, 'ID'); - const resizer = header.query(By.css('.igx-grid__th-resize-handle')).nativeElement; + const resizer = header.parent.query(By.css('.igx-grid__th-resize-handle')).nativeElement; // Verify before resizing width expect((header.nativeElement).getBoundingClientRect().width).toBe(180); diff --git a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-integration.spec.ts b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-integration.spec.ts index b1c3cc1b26e..803d0cef869 100644 --- a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-integration.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-integration.spec.ts @@ -160,7 +160,7 @@ describe('IgxTreeGrid - Integration', () => { }); it('(UI) should autosize tree-column', () => { - const headerCell = TreeGridFunctions.getHeaderCell(fix, 'ID'); + const headerCell = TreeGridFunctions.getHeaderCell(fix, 'ID').parent; const column = treeGrid.columnList.filter(c => c.field === 'ID')[0]; column.resizable = true; @@ -271,7 +271,7 @@ describe('IgxTreeGrid - Integration', () => { }); it('(UI) should autosize tree-column', () => { - const headerCell = TreeGridFunctions.getHeaderCell(fix, 'ID'); + const headerCell = TreeGridFunctions.getHeaderCell(fix, 'ID').parent; const column = treeGrid.columnList.filter(c => c.field === 'ID')[0]; column.resizable = true; diff --git a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.html b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.html index 34569aa7232..fc113af79b7 100644 --- a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.html +++ b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.html @@ -22,7 +22,7 @@
- +
@@ -31,22 +31,12 @@ -
- - -
+
-
- - -
+
@@ -56,10 +46,10 @@
- - + @@ -119,7 +109,7 @@
-
+
diff --git a/projects/igniteui-angular/src/lib/test-utils/grid-functions.spec.ts b/projects/igniteui-angular/src/lib/test-utils/grid-functions.spec.ts index 3bd838a3c61..37860563637 100644 --- a/projects/igniteui-angular/src/lib/test-utils/grid-functions.spec.ts +++ b/projects/igniteui-angular/src/lib/test-utils/grid-functions.spec.ts @@ -6,7 +6,7 @@ import { Calendar, IgxCheckboxComponent } from '../../public_api'; import { DebugElement } from '@angular/core'; import { By } from '@angular/platform-browser'; -import { ComponentFixture } from '@angular/core/testing'; +import { ComponentFixture, tick } from '@angular/core/testing'; import { IgxInputDirective } from '../input-group'; import { IgxGridHeaderComponent } from '../grids/grid-header.component'; import { IgxChipComponent } from '../chips'; @@ -408,6 +408,7 @@ export class GridFunctions { for ( i = 0; i < ddItems.length; i++) { if (ddItems[i].textContent === cond) { ddItems[i].click(); + tick(100); return; } } @@ -417,11 +418,12 @@ export class GridFunctions { const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); // open dropdown this.openFilterDD(fix.debugElement); + fix.detectChanges(); const ddList = fix.debugElement.query(By.css('div.igx-drop-down__list.igx-toggle')); this.selectFilteringCondition(condition, ddList); - const input = filterUIRow.query(By.directive(IgxInputDirective)); + const input = filterUIRow.query(By.directive(IgxInputDirective)); input.nativeElement.value = value; input.nativeElement.dispatchEvent(new Event('input')); fix.detectChanges(); @@ -436,6 +438,7 @@ export class GridFunctions { const editingBtns = filterUIRow.query(By.css('.igx-grid__filtering-row-editing-buttons')); const reset = editingBtns.queryAll(By.css('button'))[0]; reset.nativeElement.click(); + tick(100); fix.detectChanges(); } @@ -444,6 +447,7 @@ export class GridFunctions { const editingBtns = filterUIRow.query(By.css('.igx-grid__filtering-row-editing-buttons')); const close = editingBtns.queryAll(By.css('button'))[1]; close.nativeElement.click(); + tick(100); fix.detectChanges(); } diff --git a/projects/igniteui-angular/src/lib/test-utils/tree-grid-functions.spec.ts b/projects/igniteui-angular/src/lib/test-utils/tree-grid-functions.spec.ts index 42aeb047a82..e9245df8c42 100644 --- a/projects/igniteui-angular/src/lib/test-utils/tree-grid-functions.spec.ts +++ b/projects/igniteui-angular/src/lib/test-utils/tree-grid-functions.spec.ts @@ -152,7 +152,8 @@ export class TreeGridFunctions { * Verifies that the specified column is the tree column, that contains the tree cells. */ public static verifyTreeColumn(fix, expectedTreeColumnKey, expectedColumnsCount) { - const headerCell = TreeGridFunctions.getHeaderCell(fix, expectedTreeColumnKey); + const headerCell = TreeGridFunctions.getHeaderCell(fix, expectedTreeColumnKey).parent; + const treeCells = TreeGridFunctions.getTreeCells(fix); const rows = TreeGridFunctions.getAllRows(fix); diff --git a/src/app/app.component.ts b/src/app/app.component.ts index ceabe9129be..6187ef164c1 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -148,6 +148,11 @@ export class AppComponent implements OnInit { icon: 'view_column', name: 'Grid Performance' }, + { + link: '/gridPercentage', + icon: 'view_column', + name: 'Grid Percentage' + }, { link: '/gridRemoteVirtualization', icon: 'view_column', diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 83ad99ef0bf..03e8c838052 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -74,6 +74,7 @@ import { GridRowEditSampleComponent } from './grid-row-edit/grid-row-edit-sample import { GridWithTransactionsComponent } from './grid-row-edit/grid-with-transactions.component'; import { TreeGridSampleComponent } from './tree-grid/tree-grid.sample'; import { TreeGridFlatDataSampleComponent } from './tree-grid-flat-data/tree-grid-flat-data.sample'; +import { GridColumnPercentageWidthsSampleComponent } from './grid-percentage-columns/grid-percantge-widths.sample'; const components = [ AppComponent, @@ -136,7 +137,8 @@ const components = [ ShadowsSampleComponent, TypographySampleComponent, RadioSampleComponent, - TooltipSampleComponent + TooltipSampleComponent, + GridColumnPercentageWidthsSampleComponent ]; @NgModule({ diff --git a/src/app/app.routing.ts b/src/app/app.routing.ts index df53f775f7d..289d4d62d0c 100644 --- a/src/app/app.routing.ts +++ b/src/app/app.routing.ts @@ -44,6 +44,7 @@ import { GridCellStylingSampleComponent } from './gird-cell-styling/grid-cell-st import { GridRowEditSampleComponent } from './grid-row-edit/grid-row-edit-sample.component'; import { TreeGridSampleComponent } from './tree-grid/tree-grid.sample'; import { TreeGridFlatDataSampleComponent } from './tree-grid-flat-data/tree-grid-flat-data.sample'; +import { GridColumnPercentageWidthsSampleComponent } from './grid-percentage-columns/grid-percantge-widths.sample'; const appRoutes = [ { @@ -231,6 +232,10 @@ const appRoutes = [ { path: 'tooltip', component: TooltipSampleComponent + }, + { + path: 'gridPercentage', + component: GridColumnPercentageWidthsSampleComponent } ]; diff --git a/src/app/grid-column-groups/grid-column-groups.sample.html b/src/app/grid-column-groups/grid-column-groups.sample.html index 02ef5c55a71..06dc63c6630 100644 --- a/src/app/grid-column-groups/grid-column-groups.sample.html +++ b/src/app/grid-column-groups/grid-column-groups.sample.html @@ -61,7 +61,6 @@ - Pin first group Hide first group diff --git a/src/app/grid-column-moving/grid-column-moving.sample.html b/src/app/grid-column-moving/grid-column-moving.sample.html index 2bba6311a56..2b1ce8971cc 100644 --- a/src/app/grid-column-moving/grid-column-moving.sample.html +++ b/src/app/grid-column-moving/grid-column-moving.sample.html @@ -15,8 +15,7 @@ [rowSelectable]="true" [paging]="false" [width]="'900px'" - [height]="'500px'" - > + [height]="'500px'"> + + Grid with column widths in % + +
+
+ + + + + + + + {{val | date:'dd/MM/yyyy'}} + + + + + + + + + + +
+
+ + + +
+ + + + + + + + {{+val | currency}} + + + + + + + Continued + Discontinued + + + +
+
diff --git a/src/app/grid-percentage-columns/grid-percantge-widths.sample.ts b/src/app/grid-percentage-columns/grid-percantge-widths.sample.ts new file mode 100644 index 00000000000..25f407c603f --- /dev/null +++ b/src/app/grid-percentage-columns/grid-percantge-widths.sample.ts @@ -0,0 +1,453 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { IgxGridComponent, IgxStringFilteringOperand } from 'igniteui-angular'; + @Component({ + providers: [], + selector: 'ap-grid-percantge-widths.sample', + templateUrl: 'grid-percantge-widths.sample.html' +}) + export class GridColumnPercentageWidthsSampleComponent implements OnInit { + public data: Array; + public data1: Array; + + @ViewChild("grid1", { read: IgxGridComponent }) + public grid1: IgxGridComponent; + + public ngOnInit(): void { + this.data1 = [{ + ProductID: 1, + ProductName: "Chai", + SupplierID: 1, + CategoryID: 1, + QuantityPerUnit: "10 boxes x 20 bags", + UnitPrice: 18.0000, + UnitsInStock: 39, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date("2012-02-12") + }, { + ProductID: 2, + ProductName: "Chang", + SupplierID: 1, + CategoryID: 1, + QuantityPerUnit: "24 - 12 oz bottles", + UnitPrice: 19.0000, + UnitsInStock: 17, + UnitsOnOrder: 40, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date("2003-03-17") + }, { + ProductID: 3, + ProductName: "Aniseed Syrup", + SupplierID: 1, + CategoryID: 2, + QuantityPerUnit: "12 - 550 ml bottles", + UnitPrice: 10.0000, + UnitsInStock: 13, + UnitsOnOrder: 70, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date("2006-03-17") + }, { + ProductID: 4, + ProductName: "Chef Antons Cajun Seasoning", + SupplierID: 2, + CategoryID: 2, + QuantityPerUnit: "48 - 6 oz jars", + UnitPrice: 22.0000, + UnitsInStock: 53, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date("2016-03-17") + }, { + ProductID: 5, + ProductName: "Chef Antons Gumbo Mix", + SupplierID: 2, + CategoryID: 2, + QuantityPerUnit: "36 boxes", + UnitPrice: 21.3500, + UnitsInStock: 0, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date("2011-11-11") + }, { + ProductID: 6, + ProductName: "Grandmas Boysenberry Spread", + SupplierID: 3, + CategoryID: 2, + QuantityPerUnit: "12 - 8 oz jars", + UnitPrice: 25.0000, + UnitsInStock: 0, + UnitsOnOrder: 0, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date("2017-12-17") + }, { + ProductID: 7, + ProductName: "Uncle Bobs Organic Dried Pears", + SupplierID: 3, + CategoryID: 7, + QuantityPerUnit: "12 - 1 lb pkgs.", + UnitPrice: 30.0000, + UnitsInStock: 150, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date("2016-07-17") + }, { + ProductID: 8, + ProductName: "Northwoods Cranberry Sauce", + SupplierID: 3, + CategoryID: 2, + QuantityPerUnit: "12 - 12 oz jars", + UnitPrice: 40.0000, + UnitsInStock: 6, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date("2018-01-17") + }, { + ProductID: 9, + ProductName: "Mishi Kobe Niku", + SupplierID: 4, + CategoryID: 6, + QuantityPerUnit: "18 - 500 g pkgs.", + UnitPrice: 97.0000, + UnitsInStock: 29, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date("2010-02-17") + }, { + ProductID: 10, + ProductName: "Ikura", + SupplierID: 4, + CategoryID: 8, + QuantityPerUnit: "12 - 200 ml jars", + UnitPrice: 31.0000, + UnitsInStock: 31, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date("2008-05-17") + }, { + ProductID: 11, + ProductName: "Queso Cabrales", + SupplierID: 5, + CategoryID: 4, + QuantityPerUnit: "1 kg pkg.", + UnitPrice: 21.0000, + UnitsInStock: 22, + UnitsOnOrder: 30, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date("2009-01-17") + }, { + ProductID: 12, + ProductName: "Queso Manchego La Pastora", + SupplierID: 5, + CategoryID: 4, + QuantityPerUnit: "10 - 500 g pkgs.", + UnitPrice: 38.0000, + UnitsInStock: 86, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date("2015-11-17") + }, { + ProductID: 13, + ProductName: "Konbu", + SupplierID: 6, + CategoryID: 8, + QuantityPerUnit: "2 kg box", + UnitPrice: 6.0000, + UnitsInStock: 24, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date("2015-03-17") + }, { + ProductID: 14, + ProductName: "Tofu", + SupplierID: 6, + CategoryID: 7, + QuantityPerUnit: "40 - 100 g pkgs.", + UnitPrice: 23.2500, + UnitsInStock: 35, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date("2017-06-17") + }, { + ProductID: 15, + ProductName: "Genen Shouyu", + SupplierID: 6, + CategoryID: 2, + QuantityPerUnit: "24 - 250 ml bottles", + UnitPrice: 15.5000, + UnitsInStock: 39, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date("2014-03-17") + }, { + ProductID: 16, + ProductName: "Pavlova", + SupplierID: 7, + CategoryID: 3, + QuantityPerUnit: "32 - 500 g boxes", + UnitPrice: 17.4500, + UnitsInStock: 29, + UnitsOnOrder: 0, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date("2018-03-28") + }, { + ProductID: 17, + ProductName: "Alice Mutton", + SupplierID: 7, + CategoryID: 6, + QuantityPerUnit: "20 - 1 kg tins", + UnitPrice: 39.0000, + UnitsInStock: 0, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date("2015-08-17") + }, { + ProductID: 18, + ProductName: "Carnarvon Tigers", + SupplierID: 7, + CategoryID: 8, + QuantityPerUnit: "16 kg pkg.", + UnitPrice: 62.5000, + UnitsInStock: 42, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date("2005-09-27") + }, { + ProductID: 19, + ProductName: "Teatime Chocolate Biscuits", + SupplierID: 8, + CategoryID: 3, + QuantityPerUnit: "", + UnitPrice: 9.2000, + UnitsInStock: 25, + UnitsOnOrder: 0, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date("2001-03-17") + }, { + ProductID: 20, + ProductName: "Sir Rodneys Marmalade", + SupplierID: 8, + CategoryID: 3, + QuantityPerUnit: undefined, + UnitPrice: undefined, + UnitsInStock: 40, + UnitsOnOrder: 0, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date("2005-03-17") + }]; + + this.data = [{ + ProductID: 1, + ProductName: "Chai", + QuantityPerUnit: "10 boxes x 20 bags", + UnitPrice: 18.0000, + UnitsInStock: 39, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date("2012-02-12") + }, { + ProductID: 2, + ProductName: "Chang", + QuantityPerUnit: "24 - 12 oz bottles", + UnitPrice: 19.0000, + UnitsInStock: 17, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date("2003-03-17") + }, { + ProductID: 3, + ProductName: "Aniseed Syrup", + QuantityPerUnit: "12 - 550 ml bottles", + UnitPrice: 10.0000, + UnitsInStock: 13, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date("2006-03-17") + }, { + ProductID: 4, + ProductName: "Chef Antons Cajun Seasoning", + QuantityPerUnit: "48 - 6 oz jars", + UnitPrice: 22.0000, + UnitsInStock: 53, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date("2016-03-17") + }, { + ProductID: 5, + ProductName: "Chef Antons Gumbo Mix", + QuantityPerUnit: "36 boxes", + UnitPrice: 21.3500, + UnitsInStock: 0, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date("2011-11-11") + }, { + ProductID: 6, + ProductName: "Grandmas Boysenberry Spread", + QuantityPerUnit: "12 - 8 oz jars", + UnitPrice: 25.0000, + UnitsInStock: 0, + ReorderLevel: 25, + Discontinued: false, + OrderDate: new Date("2017-12-17") + }, { + ProductID: 7, + ProductName: "Uncle Bobs Organic Dried Pears", + QuantityPerUnit: "12 - 1 lb pkgs.", + UnitPrice: 30.0000, + UnitsInStock: 150, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date("2016-07-17") + }, { + ProductID: 8, + ProductName: "Northwoods Cranberry Sauce", + QuantityPerUnit: "12 - 12 oz jars", + UnitPrice: 40.0000, + UnitsInStock: 6, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date("2018-01-17") + }, { + ProductID: 9, + ProductName: "Mishi Kobe Niku", + QuantityPerUnit: "18 - 500 g pkgs.", + UnitPrice: 97.0000, + UnitsInStock: 29, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date("2010-02-17") + }, { + ProductID: 10, + ProductName: "Ikura", + QuantityPerUnit: "12 - 200 ml jars", + UnitPrice: 31.0000, + UnitsInStock: 31, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date("2008-05-17") + }, { + ProductID: 11, + ProductName: "Queso Cabrales", + QuantityPerUnit: "1 kg pkg.", + UnitPrice: 21.0000, + UnitsInStock: 22, + ReorderLevel: 30, + Discontinued: false, + OrderDate: new Date("2009-01-17") + }, { + ProductID: 12, + ProductName: "Queso Manchego La Pastora", + QuantityPerUnit: "10 - 500 g pkgs.", + UnitPrice: 38.0000, + UnitsInStock: 86, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date("2015-11-17") + }, { + ProductID: 13, + ProductName: "Konbu", + QuantityPerUnit: "2 kg box", + UnitPrice: 6.0000, + UnitsInStock: 24, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date("2015-03-17") + }, { + ProductID: 14, + ProductName: "Tofu", + QuantityPerUnit: "40 - 100 g pkgs.", + UnitPrice: 23.2500, + UnitsInStock: 35, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date("2017-06-17") + }, { + ProductID: 15, + ProductName: "Genen Shouyu", + QuantityPerUnit: "24 - 250 ml bottles", + UnitPrice: 15.5000, + UnitsInStock: 39, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date("2014-03-17") + }, { + ProductID: 16, + ProductName: "Pavlova", + QuantityPerUnit: "32 - 500 g boxes", + UnitPrice: 17.4500, + UnitsInStock: 29, + ReorderLevel: 10, + Discontinued: false, + OrderDate: new Date("2018-03-28") + }, { + ProductID: 17, + ProductName: "Alice Mutton", + QuantityPerUnit: "20 - 1 kg tins", + UnitPrice: 39.0000, + UnitsInStock: 0, + ReorderLevel: 0, + Discontinued: true, + OrderDate: new Date("2015-08-17") + }, { + ProductID: 18, + ProductName: "Carnarvon Tigers", + QuantityPerUnit: "16 kg pkg.", + UnitPrice: 62.5000, + UnitsInStock: 42, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date("2005-09-27") + }, { + ProductID: 19, + ProductName: "Teatime Chocolate Biscuits", + QuantityPerUnit: "", + UnitPrice: 9.2000, + UnitsInStock: 25, + ReorderLevel: 5, + Discontinued: false, + OrderDate: new Date("2001-03-17") + }, { + ProductID: 20, + ProductName: "Sir Rodneys Marmalade", + QuantityPerUnit: undefined, + UnitPrice: undefined, + UnitsInStock: 40, + ReorderLevel: 0, + Discontinued: false, + OrderDate: new Date("2005-03-17") + }]; + } + + + public formatDate(val: Date) { + return new Intl.DateTimeFormat("en-US").format(val); + } + + public formatCurrency(val: string) { + return parseInt(val, 10).toFixed(2); + } + + public filter(term) { + this.grid1.filter("ProductName", term, IgxStringFilteringOperand.instance().condition("contains")); + } +} diff --git a/src/app/routing.ts b/src/app/routing.ts index f3f556b5a9b..877acb27715 100644 --- a/src/app/routing.ts +++ b/src/app/routing.ts @@ -55,6 +55,7 @@ import { GridCellStylingSampleComponent } from './gird-cell-styling/grid-cell-st import { GridRowEditSampleComponent } from './grid-row-edit/grid-row-edit-sample.component'; import { TreeGridSampleComponent } from './tree-grid/tree-grid.sample'; import { TreeGridFlatDataSampleComponent } from './tree-grid-flat-data/tree-grid-flat-data.sample'; +import { GridColumnPercentageWidthsSampleComponent } from './grid-percentage-columns/grid-percantge-widths.sample'; const appRoutes = [ { @@ -286,6 +287,10 @@ const appRoutes = [ { path: 'tooltip', component: TooltipSampleComponent + }, + { + path: 'gridPercentage', + component: GridColumnPercentageWidthsSampleComponent } ];