Skip to content

Commit 9bebb0f

Browse files
Hristo PopovzdrawkuSisIvanova
authored
feat(grid): Add Column Sorting Indicators (#7782)
feat(grid): Add Column Sorting Indicators Co-authored-by: Zdravko Kolev <[email protected]> Co-authored-by: Silvia Ivanova <[email protected]>
1 parent 23a17cb commit 9bebb0f

File tree

6 files changed

+66
-6
lines changed

6 files changed

+66
-6
lines changed

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1515,6 +1515,19 @@
15151515
height: rem(15px);
15161516
min-width: rem(15px); /* yeah IE, it really needs to be 15px wide... */
15171517
font-size: rem(15px);
1518+
position: relative;
1519+
1520+
&::after {
1521+
content: attr(data-sortIndex);
1522+
position: absolute;
1523+
top: -5px;
1524+
#{$right}: -1px;
1525+
font-size: rem(10px);
1526+
text-align: $right;
1527+
font-family: sans-serif;
1528+
line-height: rem(10px);
1529+
background: --var($theme, 'header-background');
1530+
}
15181531
}
15191532
}
15201533

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

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,26 +124,36 @@ describe('IgxGrid - Grid Sorting #grid', () => {
124124
expect(grid.getCellByColumn(grid.data.length - 1, firstColumn).value).toEqual(6);
125125
expect(grid.getCellByColumn(grid.data.length - 1, thirdColumn).value).toEqual('Jones');
126126

127+
expect(GridFunctions.getColumnSortingIndex(GridFunctions.getColumnHeader(secondColumn, fixture))).toEqual(1);
128+
expect(GridFunctions.getColumnSortingIndex(GridFunctions.getColumnHeader(firstColumn, fixture))).toEqual(2);
129+
expect(GridFunctions.getColumnSortingIndex(GridFunctions.getColumnHeader(thirdColumn, fixture))).toBeNull();
130+
127131
// Clear sorting on a column
128132
grid.clearSort(firstColumn);
129133
fixture.detectChanges();
130134

131135
expect(grid.sortingExpressions.length).toEqual(1);
132136
expect(grid.sortingExpressions[0].fieldName).toEqual(secondColumn);
137+
expect(GridFunctions.getColumnSortingIndex(GridFunctions.getColumnHeader(firstColumn, fixture))).toBeNull();
138+
expect(GridFunctions.getColumnSortingIndex(GridFunctions.getColumnHeader(secondColumn, fixture))).toEqual(1);
133139

134140
grid.sortingExpressions = [
135-
{ fieldName: secondColumn, dir: SortingDirection.Asc, ignoreCase: true },
136-
{ fieldName: firstColumn, dir: SortingDirection.Desc, ignoreCase: true }
141+
{ fieldName: firstColumn, dir: SortingDirection.Desc, ignoreCase: true },
142+
{ fieldName: secondColumn, dir: SortingDirection.Asc, ignoreCase: true }
137143
];
138144
fixture.detectChanges();
139145

140146
expect(grid.sortingExpressions.length).toEqual(2);
147+
expect(GridFunctions.getColumnSortingIndex(GridFunctions.getColumnHeader(firstColumn, fixture))).toEqual(1);
148+
expect(GridFunctions.getColumnSortingIndex(GridFunctions.getColumnHeader(secondColumn, fixture))).toEqual(2);
141149

142150
// Clear sorting on all columns
143151
grid.clearSort();
144152
fixture.detectChanges();
145153

146154
expect(grid.sortingExpressions.length).toEqual(0);
155+
expect(GridFunctions.getColumnSortingIndex(GridFunctions.getColumnHeader(firstColumn, fixture))).toBeNull();
156+
expect(GridFunctions.getColumnSortingIndex(GridFunctions.getColumnHeader(secondColumn, fixture))).toBeNull();
147157
});
148158

149159
it('Should sort grid by multiple expressions through API using ignoreCase for the second expression', () => {
@@ -202,6 +212,7 @@ describe('IgxGrid - Grid Sorting #grid', () => {
202212
expect(grid.getCellByColumn(grid.data.length - 1, secondColumn).value).toEqual('ALex');
203213
expect(grid.getCellByColumn(grid.data.length - 1, thirdColumn).value).toEqual('Smith');
204214
expect(grid.getCellByColumn(grid.data.length - 1, firstColumn).value).toEqual(5);
215+
205216
});
206217

207218
it(`Should allow sorting using a custom Sorting Strategy.`, () => {
@@ -246,6 +257,7 @@ describe('IgxGrid - Grid Sorting #grid', () => {
246257
const lastRowSecondCell = GridFunctions.getCurrentCellFromGrid(grid, grid.data.length - 1, 1);
247258
expect(GridFunctions.getValueFromCellElement(lastRowFirstCell)).toEqual('7');
248259
expect(GridFunctions.getValueFromCellElement(lastRowSecondCell)).toEqual('Rick');
260+
249261
});
250262

251263
it('Should sort grid descending by clicking twice on sort icon UI', () => {
@@ -274,6 +286,7 @@ describe('IgxGrid - Grid Sorting #grid', () => {
274286
fixture.detectChanges();
275287
GridFunctions.clickHeaderSortIcon(firstHeaderCell);
276288
fixture.detectChanges();
289+
expect(GridFunctions.getColumnSortingIndex(GridFunctions.getColumnHeader('ID', fixture))).toEqual(1);
277290
GridFunctions.clickHeaderSortIcon(firstHeaderCell);
278291
fixture.detectChanges();
279292

@@ -283,6 +296,8 @@ describe('IgxGrid - Grid Sorting #grid', () => {
283296
const lastRowSecondCell = GridFunctions.getCurrentCellFromGrid(grid, grid.data.length - 1, 1);
284297
expect(GridFunctions.getValueFromCellElement(lastRowSecondCell)).toEqual('Connor');
285298

299+
expect(GridFunctions.getColumnSortingIndex(GridFunctions.getColumnHeader('ID', fixture))).toBeNull();
300+
286301
});
287302

288303
it('Should have a valid sorting icon when sorting using the API.', () => {
@@ -297,7 +312,6 @@ describe('IgxGrid - Grid Sorting #grid', () => {
297312
fixture.detectChanges();
298313

299314
GridFunctions.verifyHeaderSortIndicator(firstHeaderCell, false, true);
300-
301315
grid.clearSort();
302316
fixture.detectChanges();
303317
GridFunctions.verifyHeaderSortIndicator(firstHeaderCell, false, false);
@@ -345,13 +359,17 @@ describe('IgxGrid - Grid Sorting #grid', () => {
345359
// tslint:disable-next-line: max-line-length
346360
expect(GridFunctions.getValueFromCellElement(GridFunctions.getCurrentCellFromGrid(grid, grid.data.length - 1, 1))).toEqual('Connor');
347361

362+
expect(GridFunctions.getColumnSortingIndex(firstHeaderCell)).toEqual(1);
363+
348364
GridFunctions.clickHeaderSortIcon(firstHeaderCell);
349365
fixture.detectChanges();
350366

351367
// Verify that the grid is NOT sorted.
352368
expect(GridFunctions.getValueFromCellElement(GridFunctions.getCurrentCellFromGrid(grid, 0, 1))).toEqual('Jane');
353369
// tslint:disable-next-line: max-line-length
354370
expect(GridFunctions.getValueFromCellElement(GridFunctions.getCurrentCellFromGrid(grid, grid.data.length - 1, 1))).toEqual('Connor');
371+
372+
expect(GridFunctions.getColumnSortingIndex(firstHeaderCell)).toEqual(1);
355373
});
356374
});
357375
});

projects/igniteui-angular/src/lib/grids/headers/grid-header.component.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
</ng-container>
88
</span>
99
<div class="igx-grid__th-icons" *ngIf="!column.columnGroup">
10-
<igx-icon [attr.draggable]="false"
10+
<igx-icon
11+
[attr.draggable]="false"
12+
[attr.data-sortIndex]="column.field | sortingIndex:grid.sortingExpressions"
1113
class="sort-icon"
1214
*ngIf="column.sortable"
1315
(click)="onSortingIconClick($event)">

projects/igniteui-angular/src/lib/grids/headers/headers.module.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@ import { IgxGridSharedModules } from '../common/shared.module';
55
import { IgxColumnMovingModule } from '../moving/moving.module';
66
import { IgxGridFilteringModule } from '../filtering/base/filtering.module';
77
import { IgxGridResizingModule } from '../resizing/resize.module';
8-
8+
import { SortingIndexPipe } from './sorting-index.pipe';
99

1010
@NgModule({
1111
declarations: [
1212
IgxGridHeaderComponent,
13-
IgxGridHeaderGroupComponent
13+
IgxGridHeaderGroupComponent,
14+
SortingIndexPipe
1415
],
1516
imports: [
1617
IgxGridSharedModules,
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { Pipe, PipeTransform } from '@angular/core';
2+
import { ISortingExpression } from '../../data-operations/sorting-expression.interface';
3+
4+
@Pipe({
5+
name: 'sortingIndex',
6+
pure: true
7+
})
8+
export class SortingIndexPipe implements PipeTransform {
9+
10+
transform(columnField: string, sortingExpressions: ISortingExpression[]): number {
11+
let sortIndex = sortingExpressions.findIndex(expression => expression.fieldName === columnField);
12+
return sortIndex !== -1 ? ++sortIndex : null;
13+
}
14+
15+
}
16+

projects/igniteui-angular/src/lib/test-utils/grid-functions.spec.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ const COLUMN_PINNING_CLASS = 'igx-column-pinning';
8080
const GRID_TOOLBAR_CLASS = 'igx-grid-toolbar';
8181
const GRID_TOOLBAR_EXPORT_BUTTON_CLASS = '.igx-grid-toolbar__dropdown#btnExport';
8282
const GRID_OUTLET_CLASS = 'div.igx-grid__outlet';
83+
const SORT_INDEX_ATTRIBUTE = 'data-sortIndex';
8384
export const GRID_SCROLL_CLASS = 'igx-grid__scroll';
8485
export const GRID_MRL_BLOCK_CLASS = 'igx-grid__mrl-block';
8586
export const CELL_PINNED_CLASS = 'igx-grid__td--pinned';
@@ -1889,6 +1890,15 @@ export class GridFunctions {
18891890
return columnChooserElement.query(By.css(COLUMN_HIDING_COLUMNS_CLASS));
18901891
}
18911892

1893+
public static getColumnSortingIndex(columnHeader: DebugElement): number {
1894+
let sortIndex = columnHeader.query(By.css(SORT_ICON_CLASS)).nativeElement.getAttribute(SORT_INDEX_ATTRIBUTE);
1895+
sortIndex = parseInt(sortIndex?.trim(), 10);
1896+
if (!isNaN(sortIndex)) {
1897+
return sortIndex;
1898+
}
1899+
return null;
1900+
}
1901+
18921902
public static verifyLayoutHeadersAreAligned(headerCells, rowCells) {
18931903
for (let i; i < headerCells.length; i++) {
18941904
expect(headerCells[i].headerCell.elementRef.nativeElement.offsetWidth)

0 commit comments

Comments
 (0)