Skip to content

Commit 3f8fe67

Browse files
authored
Merge branch 'master' into skrastev/fix-7284-9.1.x
2 parents d843a46 + 7d58a43 commit 3f8fe67

16 files changed

+180
-21
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@ All notable changes for each version of this project will be documented in this
162162
- Added `tabIndex` input so it can support change detection as well.
163163

164164

165+
- `IgxHighlightDirective`
166+
- New `metadata` property was introduced, which allows adding additional, custom logic to the activation condition of a highlighted element.
167+
165168
### RTL Support
166169
- `igxSlider` have full right-to-left (RTL) support.
167170

projects/igniteui-angular/src/lib/core/utils.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,3 +355,31 @@ export function resizeObservable(target: HTMLElement): Observable<ResizeObserver
355355
return unsubscribe;
356356
});
357357
}
358+
359+
/**
360+
* @hidden
361+
* @internal
362+
*
363+
* Compares two maps.
364+
*/
365+
export function compareMaps(map1: Map<any, any>, map2: Map<any, any>): boolean {
366+
if (!map2) {
367+
return !map1 ? true : false;
368+
}
369+
if (map1.size !== map2.size) {
370+
return false;
371+
}
372+
let match = true;
373+
const keys = Array.from(map2.keys());
374+
for (const key of keys) {
375+
if (map1.has(key)) {
376+
match = map1.get(key) === map2.get(key);
377+
} else {
378+
match = false;
379+
}
380+
if (!match) {
381+
break;
382+
}
383+
}
384+
return match;
385+
}

projects/igniteui-angular/src/lib/date-range-picker/README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,15 @@ With projected inputs:
108108
### Inputs
109109
| Name | Type | Description |
110110
|:-----------------|:-------------------|:------------|
111-
| mode | InteractionMode | Sets whether `IgxDateRangePickerComponent` is in dialog or dropdown mode. Default is `dialog` |
112-
| monthsViewNumber | number | Sets the number displayed month views. Default is `2`. |
111+
| doneButtonText | string | Changes the default text of the `done` button. It will show up only in `dialog` mode. Default value is `Done`. |
112+
| formatter | function => string | Applies a custom formatter function on the selected or passed date. |
113113
| hideOutsideDays | boolean | Sets whether dates that are not part of the current month will be displayed. Default value is `false`. |
114-
| weekStart | number | Sets the start day of the week. Can be assigned to a numeric value or to `WEEKDAYS` enum value. |
115114
| locale | string | Gets the `locale` of the calendar. Default value is `"en"`. |
116-
| formatter | function => string | Applies a custom formatter function on the selected or passed date. |
117-
| doneButtonText | string | Changes the default text of the `done` button. It will show up only in `dialog` mode. Default value is `Done`. |
118115
| overlaySettings | OverlaySettings | Changes the default overlay settings used by the `IgxDateRangePickerComponent`. |
116+
| mode | InteractionMode | Sets whether `IgxDateRangePickerComponent` is in dialog or dropdown mode. Default is `dialog` |
117+
| monthsViewNumber | number | Sets the number displayed month views. Default is `2`. |
118+
| placeholder | string | Sets the `placeholder` for single-input `IgxDateRangePickerComponent`. |
119+
| weekStart | number | Sets the start day of the week. Can be assigned to a numeric value or to `WEEKDAYS` enum value. |
119120

120121
### Outputs
121122
| Name | Type | Description |

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,15 @@ describe('IgxDateRangePicker', () => {
262262
});
263263

264264
describe('Properties & events tests', () => {
265+
it('should show date picker with placeholder', () => {
266+
fixture.detectChanges();
267+
expect(singleInputElement.nativeElement.placeholder).toEqual('MM/dd/yyyy - MM/dd/yyyy');
268+
269+
const placeholder = 'Some placeholder';
270+
fixture.componentInstance.dateRange.placeholder = placeholder;
271+
fixture.detectChanges();
272+
expect(singleInputElement.nativeElement.placeholder).toEqual(placeholder);
273+
});
265274
it('should close the calendar with the "Done" button', fakeAsync(() => {
266275
fixture.componentInstance.mode = InteractionMode.Dialog;
267276
fixture.detectChanges();
@@ -809,4 +818,7 @@ export class DateRangeDefaultCustomLabelComponent extends DateRangeTestComponent
809818
</igx-date-range-picker>
810819
`
811820
})
812-
export class DateRangeDefaultComponent extends DateRangeTestComponent { }
821+
export class DateRangeDefaultComponent extends DateRangeTestComponent {
822+
@ViewChild(IgxDateRangePickerComponent)
823+
public dateRange: IgxDateRangePickerComponent;
824+
}

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,16 @@ export class IgxDateRangePickerComponent extends DisplayDensityBase
270270
@Input()
271271
public disabled: boolean;
272272

273+
/**
274+
* Sets the `placeholder` for single-input `IgxDateRangePickerComponent`.
275+
* @example
276+
* ```html
277+
* <igx-date-range-picker [placeholder]="'Choose your dates'"></igx-date-range-picker>
278+
* ```
279+
*/
280+
@Input()
281+
public placeholder = '';
282+
273283
/**
274284
* Emitted when a range is selected.
275285
*
@@ -369,6 +379,9 @@ export class IgxDateRangePickerComponent extends DisplayDensityBase
369379
return this.formatter(this.value);
370380
}
371381
if (!this.hasProjectedInputs) {
382+
if (this.placeholder !== '') {
383+
return this.placeholder;
384+
}
372385
// TODO: use displayFormat - see how shortDate, longDate can be defined
373386
return this.inputFormat
374387
? `${this.inputFormat} - ${this.inputFormat}`

projects/igniteui-angular/src/lib/directives/text-highlight/text-highlight.directive.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
import { takeUntil } from 'rxjs/operators';
1515
import { Subject } from 'rxjs';
1616
import { DeprecateProperty } from '../../core/deprecateDecorators';
17+
import { compareMaps } from '../../core/utils';
1718

1819
interface ISearchInfo {
1920
searchedText: string;
@@ -39,6 +40,10 @@ export interface IActiveHighlightInfo {
3940
* The index of the highlight.
4041
*/
4142
index: number;
43+
/**
44+
* Additional, custom checks to perform prior an element highlighting.
45+
*/
46+
metadata?: Map<string, any>;
4247
}
4348

4449
@Directive({
@@ -163,6 +168,27 @@ export class IgxTextHighlightDirective implements AfterViewInit, AfterViewChecke
163168
@Input('column')
164169
public column: any;
165170

171+
/**
172+
* A map that contains all aditional conditions, that you need to activate a highlighted
173+
* element. To activate the condition, you will have to add a new metadata key to
174+
* the `metadata` property of the IActiveHighlightInfo interface.
175+
*
176+
* @example
177+
* ```typescript
178+
* // Set a property, which would disable the highlight for a given element on a cetain condition
179+
* const metadata = new Map<string, any>();
180+
* metadata.set('highlightElement', false);
181+
* ```
182+
* ```html
183+
* <div
184+
* igxTextHighlight
185+
* [metadata]="metadata">
186+
* </div>
187+
* ```
188+
*/
189+
@Input()
190+
public metadata: Map<string, any>;
191+
166192
/**
167193
* @hidden
168194
*/
@@ -317,7 +343,7 @@ export class IgxTextHighlightDirective implements AfterViewInit, AfterViewChecke
317343
public activateIfNecessary(): void {
318344
const group = IgxTextHighlightDirective.highlightGroupsMap.get(this.groupName);
319345

320-
if (group.column === this.column && group.row === this.row) {
346+
if (group.column === this.column && group.row === this.row && compareMaps(this.metadata, group.metadata)) {
321347
this.activate(group.index);
322348
}
323349
}

projects/igniteui-angular/src/lib/grids/cell.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<ng-template #defaultCell>
55
<div igxTextHighlight style="pointer-events: none" [cssClass]="highlightClass" [activeCssClass]="activeHighlightClass" [groupName]="gridID"
66
[value]="formatter ? formatter(value) : column.dataType === 'number' ? (value | igxdecimal: grid.locale) : column.dataType === 'date' ? (value | igxdate: grid.locale) : value"
7-
[row]="rowData" [column]="this.column.field" [containerClass]="'igx-grid__td-text'"
7+
[row]="rowData" [column]="this.column.field" [containerClass]="'igx-grid__td-text'" [metadata]="searchMetadata"
88
class="igx-grid__td-text">{{ formatter ? formatter(value) : column.dataType === 'number' ? (value | igxdecimal:
99
grid.locale) : column.dataType === 'date' ? (value | igxdate: grid.locale) : value }}</div>
1010
</ng-template>

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,4 +899,14 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy {
899899
return Math.max(...Array.from(this.nativeElement.children)
900900
.map((child) => getNodeSizeViaRange(range, child)));
901901
}
902+
903+
/**
904+
* @hidden
905+
* @internal
906+
*/
907+
public get searchMetadata() {
908+
const meta = new Map<string, any>();
909+
meta.set('pinned', this.grid.isRecordPinnedByViewIndex(this.row.index));
910+
return meta;
911+
}
902912
}

projects/igniteui-angular/src/lib/grids/filtering/base/grid-filtering-cell.component.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<ng-template #emptyFilter>
22
<igx-chips-area [attr.draggable]="false" class="igx-filtering-chips">
3-
<igx-chip #ghostChip [attr.draggable]="false" (click)="onChipClicked()" [displayDensity]="'cosy'">
3+
<igx-chip #ghostChip [attr.draggable]="false" (click)="onChipClicked()" [displayDensity]="'cosy'" tabIndex="-1">
44
<igx-icon [attr.draggable]="false" igxPrefix>filter_list</igx-icon>
55
<span [attr.draggable]="false">{{filteringService.grid.resourceStrings.igx_grid_filter}}</span>
66
</igx-chip>
@@ -12,6 +12,7 @@
1212
<ng-container *ngFor="let item of expressionsList; let last = last; let index = index;" >
1313
<igx-chip *ngIf="isChipVisible(index)"
1414
[removable]="true"
15+
tabIndex="-1"
1516
[displayDensity]="'cosy'"
1617
(click)="onChipClicked(item.expression)"
1718
(onRemove)="onChipRemoved($event, item)">
@@ -33,7 +34,7 @@
3334
</ng-template>
3435

3536
<ng-template #complexFilter>
36-
<igx-chip #complexChip [removable]="true" [displayDensity]="'cosy'" (onRemove)="clearFiltering()">
37+
<igx-chip #complexChip [removable]="true" [displayDensity]="'cosy'" (onRemove)="clearFiltering()" tabIndex="-1">
3738
<igx-icon igxPrefix>filter_list</igx-icon>
3839
<span>{{filteringService.grid.resourceStrings.igx_grid_complex_filter}}</span>
3940
</igx-chip>

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

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ import {
3030
import ResizeObserver from 'resize-observer-polyfill';
3131
import { Subject, pipe } from 'rxjs';
3232
import { takeUntil, first, filter, throttleTime, map } from 'rxjs/operators';
33-
import { cloneArray, flatten, mergeObjects, isIE } from '../core/utils';
33+
import { cloneArray, flatten, mergeObjects, isIE, compareMaps } from '../core/utils';
3434
import { DataType } from '../data-operations/data-util';
3535
import { FilteringLogic, IFilteringExpression } from '../data-operations/filtering-expression.interface';
3636
import { IGroupByRecord } from '../data-operations/groupby-record.interface';
3737
import { ISortingExpression } from '../data-operations/sorting-expression.interface';
3838
import { IForOfState, IgxGridForOfDirective } from '../directives/for-of/for_of.directive';
39-
import { IgxTextHighlightDirective } from '../directives/text-highlight/text-highlight.directive';
39+
import { IgxTextHighlightDirective, IActiveHighlightInfo } from '../directives/text-highlight/text-highlight.directive';
4040
import {
4141
AbsoluteScrollStrategy,
4242
HorizontalAlignment,
@@ -2723,14 +2723,31 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
27232723
}
27242724

27252725
/**
2726+
* Returns whether the record is pinned or not.
2727+
*
2728+
* @param rowIndex Index of the record in the `dataView` collection.
2729+
*
27262730
* @hidden
27272731
* @internal
27282732
*/
2729-
public isRecordPinnedByIndex(rowIndex: number) {
2733+
public isRecordPinnedByViewIndex(rowIndex: number) {
27302734
return this.hasPinnedRecords && (this.isRowPinningToTop && rowIndex < this.pinnedDataView.length) ||
27312735
(!this.isRowPinningToTop && rowIndex >= this.unpinnedDataView.length);
27322736
}
27332737

2738+
/**
2739+
* Returns whether the record is pinned or not.
2740+
*
2741+
* @param rowIndex Index of the record in the `filteredSortedData` collection.
2742+
*
2743+
* @hidden
2744+
* @internal
2745+
*/
2746+
public isRecordPinnedByIndex(rowIndex: number) {
2747+
return this.hasPinnedRecords && (this.isRowPinningToTop && rowIndex < this._filteredSortedPinnedData.length) ||
2748+
(!this.isRowPinningToTop && rowIndex >= this._filteredSortedUnpinnedData.length);
2749+
}
2750+
27342751
/**
27352752
* @hidden
27362753
* @internal
@@ -4334,7 +4351,8 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
43344351
this.lastSearchInfo.matchInfoCache.forEach((match, i) => {
43354352
if (match.column === activeInfo.column &&
43364353
match.row === activeInfo.row &&
4337-
match.index === activeInfo.index) {
4354+
match.index === activeInfo.index &&
4355+
compareMaps(match.metadata, activeInfo.metadata)) {
43384356
this.lastSearchInfo.activeMatchIndex = i;
43394357
}
43404358
});
@@ -5856,6 +5874,7 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
58565874
column: matchInfo.column,
58575875
row: matchInfo.row,
58585876
index: matchInfo.index,
5877+
metadata: matchInfo.metadata,
58595878
});
58605879

58615880
} else {
@@ -5994,7 +6013,7 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
59946013

59956014
const numberPipe = new IgxDecimalPipeComponent(this.locale);
59966015
const datePipe = new IgxDatePipeComponent(this.locale);
5997-
data.forEach((dataRow) => {
6016+
data.forEach((dataRow, rowIndex) => {
59986017
columnItems.forEach((c) => {
59996018
const value = c.formatter ? c.formatter(dataRow[c.field]) :
60006019
c.dataType === 'number' ? numberPipe.transform(dataRow[c.field], this.locale) :
@@ -6005,21 +6024,27 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
60056024

60066025
if (exactMatch) {
60076026
if (searchValue === searchText) {
6027+
const metadata = new Map<string, any>();
6028+
metadata.set('pinned', this.isRecordPinnedByIndex(rowIndex));
60086029
this.lastSearchInfo.matchInfoCache.push({
60096030
row: dataRow,
60106031
column: c.field,
60116032
index: 0,
6033+
metadata: metadata,
60126034
});
60136035
}
60146036
} else {
60156037
let occurenceIndex = 0;
60166038
let searchIndex = searchValue.indexOf(searchText);
60176039

60186040
while (searchIndex !== -1) {
6041+
const metadata = new Map<string, any>();
6042+
metadata.set('pinned', this.isRecordPinnedByIndex(rowIndex));
60196043
this.lastSearchInfo.matchInfoCache.push({
60206044
row: dataRow,
60216045
column: c.field,
60226046
index: occurenceIndex++,
6047+
metadata: metadata,
60236048
});
60246049

60256050
searchValue = searchValue.substring(searchIndex + searchText.length);

0 commit comments

Comments
 (0)