This repository has been archived by the owner on Feb 2, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 162
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(data-table): Add Column Sorting
Add column sorting via an attribute direcive which styles its host,
subsribes to and calls method on a service with an observable model.
Closes #144
- Loading branch information
samuel.jones
committed
Aug 16, 2016
1 parent
81116f4
commit c09c878
Showing
12 changed files
with
576 additions
and
27 deletions.
There are no files selected for viewing
16 changes: 16 additions & 0 deletions
16
modules/site/src/app/examples/data-table/data-table-sorting.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<md-data-table layout-fill> | ||
<thead> | ||
<tr> | ||
<th class="md-text-cell" md-data-column-sort="name">Picnic Item</th> | ||
<th md-data-column-sort="quantity">Quantity</th> | ||
<th md-data-column-sort="price">Price</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
<tr *ngFor="let item of picnicItems"> | ||
<td class="md-text-cell">{{ item.name }}</td> | ||
<td>{{ item.quantity }}</td> | ||
<td>£{{ item.price }}</td> | ||
</tr> | ||
</tbody> | ||
</md-data-table> |
46 changes: 46 additions & 0 deletions
46
modules/site/src/app/examples/data-table/data-table-sorting.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { | ||
Component, | ||
OnDestroy | ||
} from '@angular/core'; | ||
import { | ||
MdDataColumnSortDirective, MdDataColumnSortingService, SortDirection | ||
} from 'ng2-material'; | ||
import {Subscription} from 'rxjs/Subscription'; | ||
|
||
|
||
@Component({ | ||
moduleId: module.id, | ||
selector: 'data-table-sorting', | ||
providers: [MdDataColumnSortingService], | ||
directives: [MdDataColumnSortDirective], | ||
templateUrl: 'data-table-sorting.component.html', | ||
}) | ||
export class DataTableSortingComponent implements OnDestroy { | ||
|
||
private colSortChanges: Subscription; | ||
|
||
picnicItems: Array<any> = [ | ||
{'name': 'Wine', 'quantity': 12, 'price': 22.90}, | ||
{'name': 'Cheese', 'quantity': 4, 'price': 32.25}, | ||
{'name': 'Crackers', 'quantity': 117, 'price': 2.35} | ||
] | ||
|
||
constructor(private sortingService: MdDataColumnSortingService) { | ||
// assign default | ||
this.sortingService.setSorting({ column: 'name', direction: SortDirection.ASCEND }); | ||
|
||
// respond to changes | ||
this.colSortChanges = this.sortingService.sortingColumn.subscribe((col) => { | ||
this.picnicItems.sort(function (a, b) { | ||
let valA = col.direction == SortDirection.ASCEND ? a[col.column] : b[col.column]; | ||
let valB = col.direction == SortDirection.DESCEND ? a[col.column] : b[col.column]; | ||
|
||
return valA < valB ? -1 : valA > valB ? 1 : 0; | ||
}); | ||
}); | ||
} | ||
|
||
ngOnDestroy() { | ||
this.colSortChanges.unsubscribe(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
82 changes: 82 additions & 0 deletions
82
src/components/data-table/column-sorting/column-sort.directive.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import { | ||
Directive, | ||
Input, | ||
HostBinding, | ||
HostListener, | ||
OnDestroy | ||
} from "@angular/core"; | ||
import {Subscription} from 'rxjs/Subscription'; | ||
import { | ||
MdDataColumnSortingService, | ||
SortDirection, | ||
ColumnSortingModel | ||
} from './column-sort.service'; | ||
|
||
/** | ||
* @name mdDataSortColumnDirective | ||
* | ||
* @description | ||
* A directive that styles its host with sorting class names, and calls | ||
* {@link MdDataColumnSortingService.changeSorting} to the service instance in its | ||
* execution context. | ||
* | ||
* @usage | ||
* | ||
* <hljs lang="html"> | ||
* <tr> | ||
* <th md-data-column-sort="1">Name</th> | ||
* <th md-data-column-sort="deux">Occupation</th> | ||
* <th md-data-column-sort="your_id_format_3">Status</th> | ||
* <tr> | ||
* </hljs> | ||
*/ | ||
@Directive({ | ||
selector: '[md-data-column-sort]' | ||
}) | ||
export class MdDataColumnSortDirective implements OnDestroy { | ||
|
||
/** | ||
* Sorting value of the group of columns. | ||
* The group is defined by the injection scope of the {@link MdDataColumnSortingService} in the parent component. | ||
*/ | ||
sortingColumn: ColumnSortingModel; | ||
sortingSubscription: Subscription; | ||
|
||
/** Unique column identifier */ | ||
@Input('md-data-column-sort') mdDataSortColumn: string; | ||
|
||
/** Applies 'sortable' CSS class to host */ | ||
@HostBinding('class.sortable') get sortable() { return true; } | ||
|
||
/** Conditionally applies 'sorted-ascending' CSS class to host */ | ||
@HostBinding('class.sorted-ascending') get sortingAscending() { | ||
return this.isCurrentColumn() && this.sortingColumn.direction === SortDirection.ASCEND; | ||
} | ||
|
||
/** Conditionally applies 'sorted-descending' CSS class to host */ | ||
@HostBinding('class.sorted-descending') get sortingDescending() { | ||
return this.isCurrentColumn() && this.sortingColumn.direction === SortDirection.DESCEND; | ||
} | ||
|
||
/** | ||
* Click handler on host element to tell service to sort by this column | ||
* @param clickEvent - the clickEvent. | ||
*/ | ||
@HostListener('click', ['$event']) sortBy(clickEvent: Event) { | ||
this.sortingService.onColumnSelect(this.mdDataSortColumn, this.sortingColumn); | ||
} | ||
|
||
constructor(private sortingService: MdDataColumnSortingService) { | ||
this.sortingSubscription = this.sortingService.sortingColumn.subscribe( | ||
(sorting: ColumnSortingModel) => this.sortingColumn = sorting); | ||
} | ||
|
||
ngOnDestroy() { | ||
this.sortingSubscription.unsubscribe(); | ||
} | ||
|
||
private isCurrentColumn():boolean { | ||
return this.sortingColumn && this.sortingColumn.column === this.mdDataSortColumn | ||
} | ||
|
||
} |
52 changes: 52 additions & 0 deletions
52
src/components/data-table/column-sorting/column-sort.service.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import {Injectable} from '@angular/core'; | ||
import {BehaviorSubject} from 'rxjs/BehaviorSubject'; | ||
|
||
/** Specifies sorting direction */ | ||
export enum SortDirection { | ||
ASCEND, DESCEND | ||
} | ||
|
||
/** Sorting model. */ | ||
export interface ColumnSortingModel { | ||
column: string; | ||
direction: SortDirection; | ||
} | ||
|
||
|
||
/** | ||
* Service handling column sort change events as an observable stream. | ||
*/ | ||
@Injectable() | ||
export class MdDataColumnSortingService { | ||
public sortingColumn: BehaviorSubject<ColumnSortingModel> = new BehaviorSubject( | ||
{ column: 'NONE', direction: SortDirection.ASCEND }); | ||
|
||
/** | ||
* Programatically set the column / direction of sorting | ||
* @param sorting column & direction to sort by. | ||
*/ | ||
public setSorting(sorting: ColumnSortingModel) { | ||
this.sortingColumn.next(sorting); | ||
} | ||
|
||
/** | ||
* Respond to user action on a particular column heading. | ||
* Inputting the currently sorted-by column will invert the sort direction. | ||
* @param id identifier of column to sort by | ||
* @param sorting current sorting model to compare against id | ||
*/ | ||
public onColumnSelect(fromId:string, sorting:ColumnSortingModel) { | ||
let newSort: ColumnSortingModel = { | ||
column: fromId, | ||
direction: SortDirection.ASCEND | ||
}; | ||
|
||
if (sorting && sorting.column === fromId) { | ||
// invert currently selected column | ||
newSort.direction = sorting.direction === SortDirection.DESCEND ? | ||
SortDirection.ASCEND : SortDirection.DESCEND; | ||
} | ||
|
||
this.setSorting(newSort); | ||
} | ||
} |
Oops, something went wrong.