Skip to content
This repository was archived by the owner on Dec 4, 2017. It is now read-only.

Commit 062b274

Browse files
committed
docs:(created virtual grid cookbook)
docs: update component name to have Component suffix + update display value for path in code samples data.json rc img
1 parent 6751f77 commit 062b274

File tree

18 files changed

+514
-0
lines changed

18 files changed

+514
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
**/*.js
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import {Component} from '@angular/core';
2+
3+
import {HeroGridComponent} from './hero-grid.component';
4+
5+
@Component({
6+
selector: 'app',
7+
template: '<hero-grid></hero-grid>',
8+
directives: [HeroGridComponent]
9+
})
10+
11+
export class AppComponent {
12+
13+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// #docregion
2+
import {Row} from './row';
3+
4+
export class Column{
5+
cellValue:string;
6+
row:Row;
7+
8+
constructor(public columnIndex:number, row:Row) {
9+
this.cellValue = '';
10+
this.row = row;
11+
}
12+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// #docregion
2+
import {Row} from './row';
3+
import {Column} from './column';
4+
5+
export class HeroDataService{
6+
7+
getApplicants(count:number):Array<Row>{
8+
9+
let rows:Array<Row> = [];
10+
let heroes:Array<string> = ['Mr. Nice',
11+
'Narco',
12+
'Bombasto',
13+
'Celeritas',
14+
'Magneta',
15+
'RubberMan',
16+
'Dynama',
17+
'Dr IQ',
18+
'Magma',
19+
'Tornado'];
20+
21+
for(let i = 0; i < count; i++) {
22+
let heroIndex = this.generateRandomNumber(heroes.length - 1);
23+
let heroData = [heroes[heroIndex], count - i, this.generateRandomNumber(70) + 30];
24+
rows.push(this.createCell(i,heroData));
25+
}
26+
return rows;
27+
}
28+
29+
private generateRandomNumber(upperBound:number) {
30+
return Math.floor(Math.random() * upperBound)
31+
}
32+
33+
private createCell(index:number,values:Array<any>):Row {
34+
let row = new Row(values.length);
35+
36+
for (let i = 0; i < values.length; i++) {
37+
row.columns[i].cellValue = values[i];
38+
}
39+
return row;
40+
}
41+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// #docregion
2+
import {Row} from './row';
3+
import {Injectable} from '@angular/core';
4+
5+
@Injectable()
6+
export class HeroGridSortingService {
7+
sortDirection:number = 1;
8+
9+
sort(rows:Array<Row>, colIndex:number) {
10+
this.sortDirection *= -1;
11+
rows.sort((a,b) => {
12+
if(a.columns[colIndex].cellValue === b.columns[colIndex].cellValue){
13+
return 0;
14+
}
15+
16+
if(a.columns[colIndex].cellValue > b.columns[colIndex].cellValue){
17+
return -1 * this.sortDirection;
18+
}
19+
20+
if(a.columns[colIndex].cellValue < b.columns[colIndex].cellValue){
21+
return 1 * this.sortDirection;
22+
}
23+
});
24+
}
25+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// #docregion
2+
import {Component, AfterViewChecked, ElementRef} from '@angular/core';
3+
4+
import {HeroGridSortingService} from './hero-grid-sorting.service';
5+
import {HeroGridService} from './hero-grid.service';
6+
import {KeyCodeService} from './key-code.service';
7+
import {HeroDataService} from './hero-data.service';
8+
import {Row} from './row';
9+
10+
@Component({
11+
selector: 'hero-grid',
12+
providers: [HeroGridService,KeyCodeService,HeroDataService,HeroGridSortingService],
13+
template: `<h1>Hero Grid</h1>
14+
<table id="hero-grid">
15+
<tr>
16+
<td class="row-number-column"></td>
17+
<td (click)="sort(colIndex)" class="columnHeader"
18+
*ngFor="#columnHeader of heroGridService.header; #colIndex = index">
19+
{{columnHeader}}
20+
</td>
21+
</tr>
22+
<tr *ngFor="#row of visibleRows">
23+
<td class="row-number-column">
24+
{{heroGridService.rows.indexOf(row)}}
25+
</td>
26+
<td *ngFor="#col of row.columns">
27+
<input [id]="heroGridService.createCellSelector(row,col)"
28+
[value]="col.cellValue" (input)="col.cellValue = $event.target.value"
29+
(click)="heroGridService.selectColumn(col)" (keydown)="navigate($event)" />
30+
</td>
31+
</tr>
32+
</table>`
33+
})
34+
35+
export class HeroGridComponent implements AfterViewChecked {
36+
37+
visibleRows:Array<Row> = [];
38+
heroGridService:HeroGridService;
39+
elementRef:ElementRef;
40+
41+
constructor(heroGridService:HeroGridService,elementRef:ElementRef) {
42+
this.elementRef = elementRef;
43+
this.heroGridService = heroGridService;
44+
this.visibleRows = this.heroGridService.getVisibleRows();
45+
}
46+
47+
navigate($event:any) {
48+
let res = this.heroGridService.navigate($event.keyCode);
49+
this.visibleRows = this.heroGridService.getVisibleRows();
50+
return res;
51+
}
52+
53+
sort(columnIndex:number) {
54+
this.heroGridService.sort(columnIndex);
55+
this.visibleRows = this.heroGridService.getVisibleRows();
56+
}
57+
58+
ngAfterViewChecked() {
59+
let cell = this.elementRef.nativeElement.querySelector('#' + this.heroGridService.getCurrentCellSelector());
60+
cell.focus();
61+
}
62+
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// #docregion
2+
import {Injectable} from '@angular/core';
3+
import {Row} from './row';
4+
import {Column} from './column';
5+
import {KeyCodeService} from './key-code.service';
6+
import {HeroDataService} from './hero-data.service';
7+
import {HeroGridSortingService} from './hero-grid-sorting.service';
8+
9+
@Injectable()
10+
export class HeroGridService {
11+
static maxRows = 1000;
12+
header:Array<string> = ['Name','Ranking', 'Age'];
13+
rows:Array<Row>;
14+
currentColumn:Column;
15+
currentRowIndex:number = 0;
16+
17+
private gridWindow:any;
18+
19+
keyCodeService:KeyCodeService;
20+
sortingService:HeroGridSortingService;
21+
22+
constructor(keyCodeService:KeyCodeService, heroDataService:HeroDataService, sortingService:HeroGridSortingService) {
23+
this.keyCodeService = keyCodeService;
24+
this.rows = heroDataService.getApplicants(HeroGridService.maxRows);
25+
this.sortingService = sortingService;
26+
27+
this.init();
28+
29+
let missingRows = this.gridWindow.pageSize - this.rows.length;
30+
31+
for(let i = 0; i <= missingRows; i++){
32+
this.rows.push(new Row(this.header.length));
33+
}
34+
}
35+
36+
selectColumn(col:Column) {
37+
this.currentColumn = col;
38+
this.currentRowIndex = this.rows.indexOf(this.currentColumn.row);
39+
}
40+
41+
sort(colIndex:number){
42+
this.sortingService.sort(this.rows,colIndex);
43+
this.init();
44+
}
45+
46+
createCellSelector(row:Row, col:Column):string {
47+
return 'cell' + this.rows.indexOf(row) + '-' + row.columns.indexOf(col)
48+
}
49+
50+
getCurrentCellSelector() {
51+
let cellIndex = this.rows[this.currentRowIndex].columns.indexOf(this.currentColumn);
52+
return 'cell' + this.currentRowIndex + '-' + cellIndex;
53+
}
54+
55+
getVisibleRows() {
56+
let visible:Array<Row> = [];
57+
for(let i = this.gridWindow.start; i <= this.gridWindow.end; i++){
58+
visible.push(this.rows[i]);
59+
}
60+
return visible;
61+
}
62+
63+
navigate(keyCode:number) {
64+
let navDirection = this.keyCodeService.getNavigationKey(keyCode);
65+
66+
if(navDirection.down) {
67+
this.ensureRow();
68+
this.currentColumn = this.rows[this.currentRowIndex + 1].columns[this.currentColumn.columnIndex];
69+
this.adjustRowRangeDownward();
70+
}
71+
72+
if(navDirection.up) {
73+
if(this.currentRowIndex > 0) {
74+
this.currentColumn = this.rows[this.currentRowIndex - 1].columns[this.currentColumn.columnIndex];
75+
this.adjustRowRangeUpward();
76+
}
77+
}
78+
79+
if(navDirection.left) {
80+
if(this.currentColumn.columnIndex > 0){
81+
this.currentColumn = this.rows[this.currentRowIndex].columns[this.currentColumn.columnIndex - 1];
82+
}
83+
}
84+
85+
if(navDirection.right) {
86+
if(this.currentColumn.columnIndex < this.header.length - 1){
87+
this.currentColumn = this.rows[this.currentRowIndex].columns[this.currentColumn.columnIndex + 1];
88+
}
89+
}
90+
91+
if(navDirection.tab) {
92+
return false;
93+
}
94+
95+
this.currentRowIndex = this.rows.indexOf(this.currentColumn.row);
96+
return true;
97+
}
98+
99+
private adjustRowRangeUpward() {
100+
if(this.currentRowIndex <= this.gridWindow.start) {
101+
this.shiftRowsBy(-1);
102+
}
103+
}
104+
105+
private adjustRowRangeDownward() {
106+
if(this.currentRowIndex === this.gridWindow.end) {
107+
this.shiftRowsBy(1);
108+
}
109+
}
110+
111+
private shiftRowsBy(offset:number){
112+
this.gridWindow.start = this.gridWindow.start + offset;
113+
this.gridWindow.end = this.gridWindow.end + offset;
114+
}
115+
116+
private ensureRow() {
117+
if(this.currentRowIndex + 1 >= this.rows.length) {
118+
this.rows.push(new Row(this.header.length));
119+
}
120+
}
121+
122+
private init() {
123+
this.gridWindow = {pageSize:10,start:0,end:10};
124+
this.currentColumn = this.rows[0].columns[0];
125+
this.currentRowIndex = 0;
126+
}
127+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// #docregion
2+
export class KeyCodeService {
3+
4+
getNavigationKey(keyCode:number):any {
5+
return {
6+
up: keyCode === 38,
7+
down: keyCode === 40,
8+
right: keyCode === 39,
9+
left: keyCode === 37,
10+
tab: keyCode === 9
11+
}
12+
}
13+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import {bootstrap} from '@angular/platform-browser-dynamic';
2+
import {AppComponent} from './app.component';
3+
4+
bootstrap(AppComponent);
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// #docregion
2+
import {Column} from './column';
3+
4+
export class Row{
5+
6+
columns:Array<Column>;
7+
8+
constructor(public columnCount:number) {
9+
this.columns = [];
10+
11+
for(let j = 0; j < this.columnCount; j++) {
12+
this.columns.push(new Column(j,this));
13+
}
14+
}
15+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
.row-number-column{
2+
width: 40px;
3+
background-color: #eeeeee;
4+
text-align: center;
5+
}
6+
7+
#hero-grid td{
8+
border: 1px solid gray;
9+
}
10+
11+
#hero-grid input{
12+
border:0;
13+
}
14+
15+
#hero-grid .columnHeader{
16+
background-color: #eeeeee;
17+
text-transform: uppercase;
18+
text-align: center;
19+
}
20+
21+
#hero-grid{
22+
border-collapse: collapse;
23+
}

0 commit comments

Comments
 (0)