[ui] feat: Implement table sorting

This commit is contained in:
ChronosX88 2019-09-26 00:57:32 +04:00
parent cc77c3a345
commit a772d5e376
Signed by: ChronosXYZ
GPG Key ID: 085A69A82C8C511A
7 changed files with 77 additions and 6 deletions

View File

@ -7,12 +7,14 @@ import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { NavMenuComponent } from './nav-menu/nav-menu.component';
import { HomeComponent } from './home/home.component';
import { NgbdSortableHeader } from './utils/ngbd-sortable-header';
@NgModule({
declarations: [
AppComponent,
NavMenuComponent,
HomeComponent,
NgbdSortableHeader
],
imports: [
BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),

View File

@ -1,9 +1,9 @@
<div style="text-align: center;"><h1>Add/Edit Instructor</h1></div>
<table class='table table-striped'>
<table class='table table-striped table-bordered table-sm'>
<thead>
<tr>
<th>First name</th>
<th>Last Name</th>
<th scope="col" sortable="firstName" (sort)="onSort($event)">First Name</th>
<th scope="col" sortable="lastName" (sort)="onSort($event)">Last Name</th>
<th>Manage</th>
</tr>
</thead>

View File

@ -1,11 +1,12 @@
import { Component, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Component, Inject, QueryList, ViewChildren } from '@angular/core';
import { Instructor } from '../models/instructor';
import { InstructorsHttpService } from '../services/instructors-http-service';
import { NgbdSortableHeader, SortEvent, compare } from '../utils/ngbd-sortable-header';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['../utils/ngbd-sortable-header.css'],
providers: [InstructorsHttpService]
})
export class HomeComponent {
@ -13,6 +14,8 @@ export class HomeComponent {
private changingInstructor: Instructor = new Instructor();
private savedInstructor: Instructor = new Instructor();
@ViewChildren(NgbdSortableHeader) headers: QueryList<NgbdSortableHeader>
constructor(private instructorsService: InstructorsHttpService) {}
ngOnInit() {
@ -62,4 +65,20 @@ export class HomeComponent {
this.instructors.splice(this.instructors.indexOf(instructor), 1)
})
}
onSort({column, direction}: SortEvent) {
// resetting other headers
this.headers.forEach(header => {
if (header.sortable !== column) {
header.direction = '';
}
});
if(direction != '') {
this.instructors.sort((a, b) => {
const res = compare(a[column], b[column]);
return direction === 'asc' ? res : -res;
});
}
}
}

View File

@ -0,0 +1,21 @@
th[sortable] {
cursor:pointer;
-moz-user-select:none;
-ms-user-select:none;
user-select:none;
-webkit-user-select:none
}
th[sortable].asc:after,
th[sortable].desc:after {
content:'';
display:block;
background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAmxJREFUeAHtmksrRVEUx72fH8CIGQNJkpGUUmakDEiZSJRIZsRQmCkTJRmZmJgQE0kpX0D5DJKJgff7v+ru2u3O3vvc67TOvsdatdrnnP1Y///v7HvvubdbUiIhBISAEBACQkAICAEhIAQ4CXSh2DnyDfmCPEG2Iv9F9MPlM/LHyAecdyMzHYNwR3fdNK/OH9HXl1UCozD24TCvILxizEDWIEzA0FcM8woCgRrJCoS5PIwrANQSMAJX1LEI9bqpQo4JYNFFKRSvIgsxHDVnqZgIkPnNBM0rIGtYk9YOOsqgbgepRCfdbmFtqhFkVEDVPjJp0+Z6e6hRHhqBKgg6ZDCvYBygVmUoEGoh5JTRvIJwhJo1aUOoh4CLPMyvxxi7EWOMgnCGsXXI1GIXlZUYX7ucU+kbR8NW8lh3O7cue0Pk32MKndfUxQFAwxdirk3fHappAnc0oqDPzDfGTBrCfHP04dM4oTV8cxr0SVzH9FF07xD3ib6xCDE+M+aUcVygtWzzbtGX2rPBrEUYfecfQkaFzYi6HjVnGBdtL7epqAlc1+jRdAap74RrnPc4BCijttY2tRcdN0g17w7HqZrXhdJTYAuS3hd8z+vKgK3V1zWPae0mZDMykadBn1hTQBLnZNwVrJpSe/NwEeDsEwCctEOsJTsgxLvCqUl2ACftEGvJDgjxrnBqkh3ASTvEWrIDQrwrnJpkB3DSDrGW7IAQ7wqnJtkBnLRztejXXVu4+mxz/nQ9jR1w5VB86ejLTFcnnDwhzV+F6T+CHZlx6THSjn76eyyBIOPHyDakhBAQAkJACAgBISAEhIAQYCLwC8JxpAmsEGt6AAAAAElFTkSuQmCC) 0 0/22px no-repeat;
width:22px;
height:22px;
float:left;
}
th[sortable].desc:after {
-webkit-transform:rotate(180deg);
transform:rotate(180deg);
-ms-transform:rotate(180deg)
}

View File

@ -0,0 +1,29 @@
import { Directive, Input, Output, EventEmitter } from '@angular/core'
export type SortDirection = 'asc' | 'desc' | '';
const rotate: {[key: string]: SortDirection} = { 'asc': 'desc', 'desc': '', '': 'asc' };
export const compare = (v1, v2) => v1 < v2 ? -1 : v1 > v2 ? 1 : 0;
export interface SortEvent {
column: string;
direction: SortDirection;
}
@Directive({
selector: 'th[sortable]',
host: {
'[class.asc]': 'direction === "asc"',
'[class.desc]': 'direction === "desc"',
'(click)': 'rotate()'
},
})
export class NgbdSortableHeader {
@Input() sortable: string;
@Input() direction: SortDirection = '';
@Output() sort = new EventEmitter<SortEvent>();
rotate() {
this.direction = rotate[this.direction];
this.sort.emit({column: this.sortable, direction: this.direction});
}
}

View File

@ -20,6 +20,6 @@
"core-js/es7/reflect": [
"node_modules/core-js/proposals/reflect-metadata"
]
}
}
}
}