Skip to content

Commit 1ba8f80

Browse files
authored
Merge branch '9.0.x' into mevtimov/datepicker-selection-9.0.x
2 parents 15d1c1e + 2be44a9 commit 1ba8f80

File tree

16 files changed

+188
-44
lines changed

16 files changed

+188
-44
lines changed

projects/igniteui-angular/src/lib/calendar/calendar-base.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor {
379379
const result = [];
380380
start = this.getDateOnly(start);
381381
end = this.getDateOnly(end);
382-
while (start.getTime() !== end.getTime()) {
382+
while (start.getTime() < end.getTime()) {
383383
start = this.calendarModel.timedelta(start, 'day', 1);
384384
result.push(start);
385385
}

projects/igniteui-angular/src/lib/core/styles/components/grid/_excel-filtering-theme.scss

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@
108108

109109
%grid-excel-sort {
110110
display: block;
111-
padding: rem(8px) rem(16px);
111+
padding-top: rem(8px);
112+
padding-bottom: rem(8px);
112113

113114
header {
114115
color: igx-color($palette, 'grays', 700);
@@ -239,7 +240,8 @@
239240
}
240241

241242
%grid-excel-sort {
242-
padding: rem(8px);
243+
padding-top: rem(8px);
244+
padding-bottom: rem(8px);
243245
}
244246

245247
%grid-excel-actions {
@@ -271,7 +273,8 @@
271273
}
272274

273275
%grid-excel-sort {
274-
padding: rem(4px);
276+
padding-top: rem(4px);
277+
padding-bottom: rem(4px);
275278

276279
@extend %grid-excel-action--compact;
277280

projects/igniteui-angular/src/lib/directives/autocomplete/autocomplete.directive.spec.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,31 @@ describe('IgxAutocomplete', () => {
593593
UIInteractions.triggerKeyDownEvtUponElem('enter', input.nativeElement, true);
594594
expect(fixture.componentInstance.townSelected).toBe('s');
595595
}));
596+
it('Should trigger onItemSelected only once when the event is cancelled (issue #7483)', fakeAsync(() => {
597+
spyOn(autocomplete.onItemSelected, 'emit').and.callThrough();
598+
599+
fixture.componentInstance.onItemSelected = (args) => { args.cancel = true; };
600+
UIInteractions.setInputElementValue(input, 's', fixture);
601+
fixture.detectChanges();
602+
tick();
603+
UIInteractions.triggerKeyDownEvtUponElem('enter', input.nativeElement, true);
604+
expect(fixture.componentInstance.townSelected).toBe('s');
605+
tick();
606+
fixture.detectChanges();
607+
expect(autocomplete.onItemSelected.emit).toHaveBeenCalledTimes(1);
608+
expect(autocomplete.onItemSelected.emit).toHaveBeenCalledWith({ value: 'Sofia', cancel: true });
609+
610+
fixture.componentInstance.onItemSelected = (args) => { args.cancel = true; };
611+
UIInteractions.setInputElementValue(input, 's', fixture);
612+
fixture.detectChanges();
613+
tick();
614+
UIInteractions.triggerKeyDownEvtUponElem('enter', input.nativeElement, true);
615+
expect(fixture.componentInstance.townSelected).toBe('s');
616+
tick();
617+
fixture.detectChanges();
618+
expect(autocomplete.onItemSelected.emit).toHaveBeenCalledTimes(2);
619+
expect(autocomplete.onItemSelected.emit).toHaveBeenCalledWith({ value: 'Sofia', cancel: true });
620+
}));
596621
it('Should call onInput/open/close methods properly', fakeAsync(() => {
597622
let startsWith = 'g';
598623
spyOn(autocomplete, 'onInput').and.callThrough();

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

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {
33
NgModule, ElementRef, HostListener, ChangeDetectorRef, OnDestroy } from '@angular/core';
44
import { NgModel, FormControlName } from '@angular/forms';
55
import { CommonModule } from '@angular/common';
6-
import { Subject } from 'rxjs';
6+
import { Subject, Subscription } from 'rxjs';
77
import { first, takeUntil } from 'rxjs/operators';
88
import { CancelableEventArgs, IBaseEventArgs } from '../../core/utils';
99
import { OverlaySettings, AbsoluteScrollStrategy, IScrollStrategy, IPositionStrategy, AutoPositionStrategy } from '../../services/index';
@@ -68,6 +68,9 @@ export class IgxAutocompleteDirective extends IgxDropDownItemNavigationDirective
6868
excludePositionTarget: true
6969
};
7070

71+
/** @hidden @internal */
72+
private subscriptions: Subscription[] = [];
73+
7174
protected id: string;
7275
protected dropDownOpened$ = new Subject<boolean>();
7376
protected get model() {
@@ -280,9 +283,18 @@ export class IgxAutocompleteDirective extends IgxDropDownItemNavigationDirective
280283
// If no drop-down width is set, the drop-down will be as wide as the autocomplete input;
281284
this.target.width = this.target.width || (this.parentElement.clientWidth + 'px');
282285
this.target.open(this.settings);
283-
this.target.onSelection.pipe(takeUntil(this.dropDownOpened$)).subscribe(this.select);
284-
this.target.onOpened.pipe(first()).subscribe(this.highlightFirstItem);
285-
this.target.children.changes.pipe(takeUntil(this.dropDownOpened$)).subscribe(this.highlightFirstItem);
286+
287+
// unsubscribe from previous subscriptions, before creating new subscriptions.
288+
this.unsubscribe();
289+
290+
this.subscriptions.push(this.target.onSelection.pipe(takeUntil(this.dropDownOpened$)).subscribe(this.select));
291+
this.subscriptions.push(this.target.onOpened.pipe(first()).subscribe(this.highlightFirstItem));
292+
this.subscriptions.push(this.target.children.changes.pipe(takeUntil(this.dropDownOpened$)).subscribe(this.highlightFirstItem));
293+
}
294+
295+
/** @hidden @internal */
296+
private unsubscribe() {
297+
this.subscriptions.forEach(subscription => subscription.unsubscribe());
286298
}
287299

288300
private get collapsed(): boolean {

projects/igniteui-angular/src/lib/directives/input/input.directive.spec.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,29 @@ describe('IgxInput', () => {
615615
expect(inputGroup.element.nativeElement.classList.contains(INPUT_GROUP_INVALID_CSS_CLASS)).toBe(false);
616616
expect(inputGroup.element.nativeElement.classList.contains(INPUT_GROUP_VALID_CSS_CLASS)).toBe(false);
617617
});
618+
619+
it('should not set null or undefined as input value', () => {
620+
const fixture = TestBed.createComponent(InputComponent);
621+
fixture.detectChanges();
622+
623+
const igxInput = fixture.componentInstance.igxInput;
624+
expect(igxInput.value).toBe('');
625+
626+
igxInput.value = undefined;
627+
expect(igxInput.value).toBe('');
628+
629+
igxInput.value = null;
630+
expect(igxInput.value).toBe('');
631+
632+
igxInput.value = 0;
633+
expect(igxInput.value).toBe('0');
634+
635+
igxInput.value = false;
636+
expect(igxInput.value).toBe('false');
637+
638+
igxInput.value = 'Test';
639+
expect(igxInput.value).toBe('Test');
640+
});
618641
});
619642

620643
@Component({ template: `

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export class IgxInputDirective implements AfterViewInit, OnDestroy {
7474
*/
7575
@Input('value')
7676
set value(value: any) {
77-
this.nativeElement.value = value;
77+
this.nativeElement.value = value ?? '';
7878
this.checkValidity();
7979
}
8080
/**

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -540,10 +540,6 @@ export class GridBaseAPIService <T extends IgxGridBaseDirective & GridType> {
540540
return false;
541541
}
542542

543-
public atInexistingPage(): boolean {
544-
return this.grid.totalPages - 1 > this.grid.page;
545-
}
546-
547543
public get_row_expansion_state(record: any): boolean {
548544
const grid = this.grid;
549545
const states = grid.expansionStates;

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,10 @@ <h4>{{ column.header || column.field }}</h4>
8484
</div>
8585
</header>
8686

87-
<div *ngIf="column.sortable">
88-
<ng-container *ngTemplateOutlet="sortingTemplate"></ng-container>
89-
</div>
90-
9187
<section class="igx-excel-filter__actions">
88+
<div *ngIf="column.sortable">
89+
<ng-container *ngTemplateOutlet="sortingTemplate"></ng-container>
90+
</div>
9291

9392
<div *ngIf="column.movable">
9493
<ng-container *ngTemplateOutlet="movingTemplate"></ng-container>

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ export class IgxFilteringService implements OnDestroy {
179179
}
180180

181181
/**
182-
* Clear the filter of a given column.
182+
* Clears the filter of a given column if name is provided. Otherwise clears the filters of all columns.
183183
*/
184184
public clearFilter(field: string): void {
185185
if (field) {
@@ -199,6 +199,11 @@ export class IgxFilteringService implements OnDestroy {
199199
if (field) {
200200
const expressions = this.getExpressions(field);
201201
expressions.length = 0;
202+
} else {
203+
this.grid.columns.forEach(c => {
204+
const expressions = this.getExpressions(c.field);
205+
expressions.length = 0;
206+
});
202207
}
203208

204209
this.isFiltering = false;

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

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import {
2828
Directive
2929
} from '@angular/core';
3030
import ResizeObserver from 'resize-observer-polyfill';
31-
import { Subject, combineLatest, pipe } from 'rxjs';
31+
import { Subject, pipe } from 'rxjs';
3232
import { takeUntil, first, filter, throttleTime, map } from 'rxjs/operators';
3333
import { cloneArray, isEdge, isNavigationKey, flatten, mergeObjects, isIE } from '../core/utils';
3434
import { DataType } from '../data-operations/data-util';
@@ -2495,11 +2495,10 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
24952495
this.zone.run(() => {
24962496
this.zone.onStable.pipe(first()).subscribe(() => {
24972497
this.verticalScrollContainer.onChunkLoad.emit(this.verticalScrollContainer.state);
2498+
if (this.rowEditable) {
2499+
this.changeRowEditingOverlayStateOnScroll(this.rowInEditMode);
2500+
}
24982501
});
2499-
2500-
if (this.rowEditable) {
2501-
this.changeRowEditingOverlayStateOnScroll(this.rowInEditMode);
2502-
}
25032502
});
25042503
this.disableTransitions = false;
25052504

@@ -2640,12 +2639,6 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
26402639
this.summaryService.clearSummaryCache();
26412640
this._pipeTrigger++;
26422641
this.notifyChanges();
2643-
if (this.transactions.getAggregatedChanges(false).length === 0) {
2644-
// Needs better check, calling 'transactions.clear()' will also trigger this
2645-
if (this.gridAPI.atInexistingPage()) {
2646-
this.page--;
2647-
}
2648-
}
26492642
});
26502643

26512644
this.resizeNotify.pipe(destructor, filter(() => !this._init), throttleTime(100))
@@ -2822,6 +2815,15 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
28222815
this.setupColumns();
28232816
}
28242817

2818+
/**
2819+
* @hidden
2820+
* @internal
2821+
*/
2822+
public setFilteredSortedData(data) {
2823+
this._filteredSortedData = data;
2824+
this.refreshSearch(true, false);
2825+
}
2826+
28252827
/**
28262828
* @hidden @internal
28272829
*/
@@ -4025,7 +4027,7 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
40254027
* ```
40264028
* @param updateActiveInfo
40274029
*/
4028-
public refreshSearch(updateActiveInfo?: boolean): number {
4030+
public refreshSearch(updateActiveInfo?: boolean, endEdit = true): number {
40294031
if (this.lastSearchInfo.searchText) {
40304032
this.rebuildMatchCache();
40314033

@@ -4040,7 +4042,12 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
40404042
});
40414043
}
40424044

4043-
return this.find(this.lastSearchInfo.searchText, 0, this.lastSearchInfo.caseSensitive, this.lastSearchInfo.exactMatch, false);
4045+
return this.find(this.lastSearchInfo.searchText,
4046+
0,
4047+
this.lastSearchInfo.caseSensitive,
4048+
this.lastSearchInfo.exactMatch,
4049+
false,
4050+
endEdit);
40444051
} else {
40454052
return 0;
40464053
}
@@ -5357,12 +5364,14 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
53575364
return col.field + col._calcWidth;
53585365
}
53595366

5360-
private find(text: string, increment: number, caseSensitive?: boolean, exactMatch?: boolean, scroll?: boolean) {
5367+
private find(text: string, increment: number, caseSensitive?: boolean, exactMatch?: boolean, scroll?: boolean, endEdit = true) {
53615368
if (!this.rowList) {
53625369
return 0;
53635370
}
53645371

5365-
this.endEdit(false);
5372+
if (endEdit) {
5373+
this.endEdit(false);
5374+
}
53665375

53675376
if (!text) {
53685377
this.clearSearch();
@@ -5438,10 +5447,6 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
54385447
get filteredSortedData(): any[] {
54395448
return this._filteredSortedData;
54405449
}
5441-
set filteredSortedData(value: any[]) {
5442-
this._filteredSortedData = value;
5443-
this.refreshSearch(true);
5444-
}
54455450

54465451
/**
54475452
* @hidden

0 commit comments

Comments
 (0)