Skip to content

Commit 98abd83

Browse files
authored
Merge branch '9.1.x' into ibarakov/fix-8372-9.1.x
2 parents ab29858 + 1d3b984 commit 98abd83

File tree

13 files changed

+126
-74
lines changed

13 files changed

+126
-74
lines changed

angular.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@
7070
"with": "src/environments/environment.hmr.ts"
7171
}
7272
]
73+
},
74+
"es5": {
75+
"tsConfig": "src/tsconfig-es5.app.json"
7376
}
7477
}
7578
},
@@ -86,6 +89,9 @@
8689
"hmr": true,
8790
"hmrWarning": false,
8891
"browserTarget": "igniteui-dev-demos:build:hmr"
92+
},
93+
"es5": {
94+
"browserTarget": "igniteui-dev-demos:build:es5"
8995
}
9096
}
9197
},

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"scripts": {
55
"ng": "ng",
66
"start": "ng serve --open --configuration hmr",
7+
"start-es5": "ng serve --configuration es5 -o",
78
"build": "ng build",
89
"test": "ng test",
910
"lint": "ng lint",

projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,9 @@ export class IgxDatePickerComponent implements IDatePicker, ControlValueAccessor
392392
private _cdr: ChangeDetectorRef,
393393
private _moduleRef: NgModuleRef<any>,
394394
private _injector: Injector,
395-
private _renderer: Renderer2) { }
395+
private _renderer: Renderer2) {
396+
}
397+
396398

397399
/**
398400
* Gets the input group template.
@@ -792,7 +794,7 @@ export class IgxDatePickerComponent implements IDatePicker, ControlValueAccessor
792794
return this._inputGroup || this._inputGroupUserTemplate || null;
793795
}
794796

795-
/** @hidden @internal */
797+
/** @hidden @internal */
796798
public get inputDirective(): IgxInputDirective {
797799
return this._inputDirective || this._inputDirectiveUserTemplates.first || null;
798800
}
@@ -885,7 +887,7 @@ export class IgxDatePickerComponent implements IDatePicker, ControlValueAccessor
885887

886888
this._inputDirectiveUserTemplates.changes.subscribe(() => {
887889
this.attachTemplateBlur();
888-
});
890+
});
889891
this.attachTemplateBlur();
890892
}
891893

@@ -901,8 +903,8 @@ export class IgxDatePickerComponent implements IDatePicker, ControlValueAccessor
901903
this.rawDateString = (res.target as HTMLInputElement).value;
902904
this.onBlur(res, false);
903905
});
904-
// TODO: Refactor custom template handling.
905-
// Revise blur handling when custom template is passed
906+
// TODO: Refactor custom template handling.
907+
// Revise blur handling when custom template is passed
906908
}
907909
}
908910

@@ -1141,6 +1143,12 @@ export class IgxDatePickerComponent implements IDatePicker, ControlValueAccessor
11411143

11421144
/** @hidden @internal */
11431145
public onInput(event) {
1146+
/**
1147+
* Fix for #8165 until refactoring (#6483).
1148+
* The IgxDateTimeEditor will be used to handle all inputs, i.e. this handler will be removed.
1149+
* It extends the IgxMaskDirective which contains logic that handles this issue.
1150+
*/
1151+
if (isIE() && !this._isInEditMode && !this.inputGroup.isFocused) { return; }
11441152
const targetValue = event.target.value;
11451153
const cursorPosition = this._getCursorPosition();
11461154
const checkInput = DatePickerUtil.checkForCompleteDateInput(this.dateFormatParts, targetValue);

projects/igniteui-angular/src/lib/directives/mask/mask.directive.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ export class IgxMaskDirective implements OnInit, AfterViewChecked, ControlValueA
154154
/** @hidden */
155155
public ngOnInit(): void {
156156
if (!this.nativeElement.placeholder) {
157-
this.renderer.setAttribute(this.nativeElement, 'placeholder', this.maskOptions.format);
157+
this.renderer.setAttribute(this.nativeElement, 'placeholder', this.maskOptions.format);
158158
}
159159
}
160160

@@ -188,7 +188,15 @@ export class IgxMaskDirective implements OnInit, AfterViewChecked, ControlValueA
188188
/** @hidden */
189189
@HostListener('input')
190190
public onInputChanged(): void {
191-
if (isIE() && this._stopPropagation) {
191+
/**
192+
* '!this._focused' is a fix for #8165
193+
* On page load IE triggers input events before focus events and
194+
* it does so for every single input on the page.
195+
* The mask needs to be prevented from doing anything while this is happening because
196+
* the end user will be unable to blur the input.
197+
* https://stackoverflow.com/questions/21406138/input-event-triggered-on-internet-explorer-when-placeholder-changed
198+
*/
199+
if (isIE() && (this._stopPropagation || !this._focused)) {
192200
this._stopPropagation = false;
193201
return;
194202
}

projects/igniteui-angular/src/lib/grids/api.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ export class GridBaseAPIService <T extends IgxGridBaseDirective & GridType> {
443443

444444
public get_all_data(includeTransactions = false): any[] {
445445
const grid = this.grid;
446-
let data = grid.data ? grid.data : [];
446+
let data = grid && grid.data ? grid.data : [];
447447
data = includeTransactions ? grid.dataWithAddedInTransactionRows : data;
448448
return data;
449449
}

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

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ export class IgxGridExcelStyleFilteringComponent implements OnDestroy {
155155
requestAnimationFrame(() => {
156156
this.isColumnPinnable = this.column.pinnable;
157157
if (!(this.cdr as ViewRef).destroyed) {
158-
this.cdr.detectChanges();
158+
this.cdr.detectChanges();
159159
}
160160
});
161161
});
@@ -528,20 +528,20 @@ export class IgxGridExcelStyleFilteringComponent implements OnDestroy {
528528
private areExpressionsSelectable () {
529529
if (this.expressionsList.length === 1 &&
530530
(this.expressionsList[0].expression.condition.name === 'equals' ||
531-
this.expressionsList[0].expression.condition.name === 'true' ||
532-
this.expressionsList[0].expression.condition.name === 'false' ||
533-
this.expressionsList[0].expression.condition.name === 'empty' ||
534-
this.expressionsList[0].expression.condition.name === 'in')) {
531+
this.expressionsList[0].expression.condition.name === 'true' ||
532+
this.expressionsList[0].expression.condition.name === 'false' ||
533+
this.expressionsList[0].expression.condition.name === 'empty' ||
534+
this.expressionsList[0].expression.condition.name === 'in')) {
535535
return true;
536536
}
537537

538538
const selectableExpressionsCount = this.expressionsList.filter(exp =>
539539
(exp.beforeOperator === 1 || exp.afterOperator === 1) &&
540540
(exp.expression.condition.name === 'equals' ||
541-
exp.expression.condition.name === 'true' ||
542-
exp.expression.condition.name === 'false' ||
543-
exp.expression.condition.name === 'empty' ||
544-
exp.expression.condition.name === 'in')).length;
541+
exp.expression.condition.name === 'true' ||
542+
exp.expression.condition.name === 'false' ||
543+
exp.expression.condition.name === 'empty' ||
544+
exp.expression.condition.name === 'in')).length;
545545

546546
return selectableExpressionsCount === this.expressionsList.length;
547547
}
@@ -581,7 +581,12 @@ export class IgxGridExcelStyleFilteringComponent implements OnDestroy {
581581
this.excelStyleSearch.isLoading = true;
582582
const expressionsTree: FilteringExpressionsTree = this.getColumnFilterExpressionsTree();
583583

584+
const prevColumn = this.column;
584585
this.grid.uniqueColumnValuesStrategy(this.column, expressionsTree, (colVals: any[]) => {
586+
if (!this.column || this.column !== prevColumn) {
587+
return;
588+
}
589+
585590
const columnValues = (this.column.dataType === DataType.Date) ?
586591
colVals.map(val => val ? val.toDateString() : val) : colVals;
587592

@@ -618,7 +623,7 @@ export class IgxGridExcelStyleFilteringComponent implements OnDestroy {
618623
if (this.column.dataType === DataType.String && this.column.filteringIgnoreCase) {
619624
const filteredUniqueValues = columnValues.map(s => s?.toString().toLowerCase())
620625
.reduce((map, val, i) => map.get(val) ? map : map.set(val, columnValues[i]),
621-
new Map);
626+
new Map);
622627

623628
this.uniqueValues = Array.from(filteredUniqueValues.values());
624629
} else {

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

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6413,6 +6413,37 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
64136413
return this.transactions.enabled ? this.dataWithAddedInTransactionRows.length : this.gridAPI.get_all_data().length;
64146414
}
64156415

6416+
/**
6417+
* @hidden @internal
6418+
*/
6419+
public get template(): TemplateRef<any> {
6420+
if (this.isLoading && (this.hasZeroResultFilter || this.hasNoData)) {
6421+
return this.loadingGridTemplate ? this.loadingGridTemplate : this.loadingGridDefaultTemplate;
6422+
}
6423+
6424+
if (this.hasZeroResultFilter) {
6425+
return this.emptyGridTemplate ? this.emptyGridTemplate : this.emptyFilteredGridTemplate;
6426+
}
6427+
6428+
if (this.hasNoData) {
6429+
return this.emptyGridTemplate ? this.emptyGridTemplate : this.emptyGridDefaultTemplate;
6430+
}
6431+
}
6432+
6433+
/**
6434+
* @hidden @internal
6435+
*/
6436+
private get hasZeroResultFilter(): boolean {
6437+
return this.filteredData && this.filteredData.length === 0;
6438+
}
6439+
6440+
/**
6441+
* @hidden @internal
6442+
*/
6443+
private get hasNoData(): boolean {
6444+
return !this.data || this.dataLength === 0;
6445+
}
6446+
64166447
/**
64176448
* @hidden @internal
64186449
*/
@@ -6451,7 +6482,7 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
64516482
* @hidden @internal
64526483
*/
64536484
get shouldOverlayLoading(): boolean {
6454-
return this.isLoading && this.data && this.data.length > 0;
6485+
return this.isLoading && !this.hasNoData && !this.hasZeroResultFilter;
64556486
}
64566487

64576488
/**

projects/igniteui-angular/src/lib/grids/grid/grid-filtering-ui.spec.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4511,6 +4511,17 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => {
45114511
loadingIndicator = GridFunctions.getExcelFilteringLoadingIndicator(fix);
45124512
expect(loadingIndicator).toBeNull('esf loading indicator is visible');
45134513
}));
4514+
4515+
it('Should not execute done callback for null column', fakeAsync(() => {
4516+
const compInstance = fix.componentInstance as IgxGridFilteringESFLoadOnDemandComponent;
4517+
GridFunctions.clickExcelFilterIcon(fix, 'ProductName');
4518+
fix.detectChanges();
4519+
4520+
expect(() => {
4521+
GridFunctions.clickExcelFilterIcon(fix, 'Downloads');
4522+
tick(2000);
4523+
}).not.toThrowError(/\'dataType\' of null/);
4524+
}));
45144525
});
45154526

45164527
describe(null, () => {

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

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ import { SortingDirection, ISortingExpression } from '../../data-operations/sort
2222
import { configureTestSuite } from '../../test-utils/configure-suite';
2323
import { IgxTabsModule, IgxTabsComponent } from '../../tabs/public_api';
2424
import { GridSelectionMode } from '../common/enums';
25-
25+
import { FilteringExpressionsTree } from '../../data-operations/filtering-expressions-tree';
26+
import { FilteringLogic } from '../../data-operations/filtering-expression.interface';
2627

2728
describe('IgxGrid Component Tests #grid', () => {
2829
const MIN_COL_WIDTH = '136px';
@@ -345,7 +346,7 @@ describe('IgxGrid Component Tests #grid', () => {
345346
grid.filter(columns[0].field, 546000, IgxNumberFilteringOperand.instance().condition('equals'));
346347
fixture.detectChanges();
347348
tick(100);
348-
expect(gridBody.nativeElement.textContent).toEqual(grid.emptyFilteredGridMessage);
349+
expect(gridBody.nativeElement.textContent).not.toEqual(grid.emptyFilteredGridMessage);
349350
expect(parseInt(window.getComputedStyle(gridBody.nativeElement).height, 10)).toBe(548);
350351

351352
// Clear filter and check if grid's body height is restored based on all loaded rows
@@ -397,7 +398,7 @@ describe('IgxGrid Component Tests #grid', () => {
397398
grid.filter(columns[0].field, 546000, IgxNumberFilteringOperand.instance().condition('equals'));
398399
fixture.detectChanges();
399400
tick(100);
400-
expect(gridBody.nativeElement.textContent).toEqual(grid.emptyFilteredGridMessage);
401+
expect(gridBody.nativeElement.textContent).not.toEqual(grid.emptyFilteredGridMessage);
401402

402403
// Clear filter and check if grid's body height is restored based on all loaded rows
403404
grid.clearFilter(columns[0].field);
@@ -481,6 +482,33 @@ describe('IgxGrid Component Tests #grid', () => {
481482
expect(parseInt(window.getComputedStyle(gridBody.nativeElement).height, 10)).toBeGreaterThan(500);
482483
}));
483484

485+
it('should render loading indicator when loading is enabled and the grid has empty filtering pre-applied', fakeAsync(() => {
486+
const fixture = TestBed.createComponent(IgxGridTestComponent);
487+
const grid = fixture.componentInstance.grid;
488+
grid.filteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.And);
489+
grid.filteringExpressionsTree.filteringOperands = [
490+
{
491+
condition: IgxNumberFilteringOperand.instance().condition('equals'),
492+
fieldName: 'index',
493+
searchVal: 0
494+
}
495+
];
496+
grid.isLoading = true;
497+
fixture.detectChanges();
498+
tick(16);
499+
500+
const gridBody = fixture.debugElement.query(By.css(TBODY_CLASS));
501+
const loadingIndicator = gridBody.query(By.css('.igx-grid__loading'));
502+
const domGrid = fixture.debugElement.query(By.css('igx-grid')).nativeElement;
503+
504+
// make sure default width/height are applied when there is no data
505+
expect(domGrid.style.height).toBe('100%');
506+
expect(domGrid.style.width).toBe('100%');
507+
508+
expect(loadingIndicator).not.toBeNull();
509+
expect(gridBody.nativeElement.textContent).not.toEqual(grid.emptyFilteredGridMessage);
510+
}));
511+
484512
it('should allow applying custom loading indicator', fakeAsync(() => {
485513
const fixture = TestBed.createComponent(IgxGridRemoteOnDemandComponent);
486514
fixture.componentInstance.instance.loadingGridTemplate = fixture.componentInstance.customTemaplate;

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

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -810,24 +810,6 @@ export class IgxGridComponent extends IgxGridBaseDirective implements GridType,
810810
}
811811
}
812812

813-
814-
/**
815-
* @hidden @internal
816-
*/
817-
public get template(): TemplateRef<any> {
818-
if (this.filteredData && this.filteredData.length === 0) {
819-
return this.emptyGridTemplate ? this.emptyGridTemplate : this.emptyFilteredGridTemplate;
820-
}
821-
822-
if (this.isLoading && (!this.data || this.dataLength === 0)) {
823-
return this.loadingGridTemplate ? this.loadingGridTemplate : this.loadingGridDefaultTemplate;
824-
}
825-
826-
if (this.dataLength === 0) {
827-
return this.emptyGridTemplate ? this.emptyGridTemplate : this.emptyGridDefaultTemplate;
828-
}
829-
}
830-
831813
/**
832814
* @hidden @internal
833815
*/

0 commit comments

Comments
 (0)