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

docs:(cookbook showing how to create a TreeView) #1145

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions public/docs/_examples/cb-tree-view/e2e-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/// <reference path='../_protractor/e2e.d.ts' />
'use strict';
/* tslint:disable:quotemark */
describe('Tree View', function () {

beforeEach(function () {
browser.get('');
});

it('should expand and collapse all nodes', function(){
let expandAll = element(by.xpath('//button[text()="Expand All"]'));
let collapseAll = element(by.xpath('//button[text()="Collapse All"]'));

expandAll.click()
.then(function(){
expect(findHeroCount('Dr IQ')).toBe(1);
expect(findHeroCount('Bombasto')).toBe(1);
expect(findHeroCount('Celeritas')).toBe(1);
expect(findHeroCount('RubberMan')).toBe(1);
expect(findHeroCount('Tornado')).toBe(1);
expect(findHeroCount('Dynama')).toBe(2);
expect(findHeroCount('Magma')).toBe(1);
});

collapseAll.click()
.then(function(){
expect(findHeroCount('Dr IQ')).toBe(0);
expect(findHeroCount('Bombasto')).toBe(0);
expect(findHeroCount('Celeritas')).toBe(0);
expect(findHeroCount('RubberMan')).toBe(0);
expect(findHeroCount('Tornado')).toBe(0);
expect(findHeroCount('Dynama')).toBe(0);
expect(findHeroCount('Magma')).toBe(0);
});
});

function findHeroCount(name: string) {
let length = element.all(by.xpath('//div[text()="Name: ' + name + '"]')).count();
return length;
}

it('should add hero', function () {
let usaNode = element.all(by.xpath('//a[text()="USA"]')).get(0);

usaNode.click().then(function() {
let name = element(by.xpath('//input[@placeholder="name"]'));

let rating = element(by.xpath('//input[@placeholder="ranking"]'));

name.sendKeys('New Hero');
rating.sendKeys('10');

let addButton = element(by.xpath('//button[text()="Add Hero"]'));
return addButton.click();
})
.then(function(){
let name = element(by.xpath('//div[text()="name: New Hero"]'));
expect(name).toBeDefined();

let rating = element(by.xpath('//div[text()="10"]'));
expect(rating).toBeDefined();
});
});

});
1 change: 1 addition & 0 deletions public/docs/_examples/cb-tree-view/ts/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
**/*.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<!-- #docregion -->
<input placeholder="name" [(ngModel)]="hero.name" />
<input placeholder="ranking" type="number" [(ngModel)]="hero.ranking" />
<div>
<button (click)="addHero()">Add Hero</button>
<button (click)="cancel()">Cancel</button>
</div>
30 changes: 30 additions & 0 deletions public/docs/_examples/cb-tree-view/ts/app/add-hero.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// #docregion
import { Component, OnInit } from '@angular/core';

import { TreeNodeService } from './tree-node.service';
import { Hero } from './hero';

@Component({
selector: 'add-hero',
templateUrl: 'app/add-hero.component.html'
})
export class AddHeroComponent implements OnInit {
hero: Hero;

constructor(private treeNodeService: TreeNodeService) { }

addHero(): void {
if (this.hero.name) {
this.treeNodeService.addHero(this.hero);
this.hero = new Hero();
}
}

cancel(): void {
this.treeNodeService.selectedNode.unselect();
}

ngOnInit(): void {
this.hero = new Hero();
}
}
30 changes: 30 additions & 0 deletions public/docs/_examples/cb-tree-view/ts/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// #docregion
import { Component, OnInit } from '@angular/core';

import { TreeNode } from './tree-node';
import { TreeNodeService } from './tree-node.service';

@Component({
selector: 'my-app',
template: `
<div>
<h2>Hero locations</h2>
<button (click)="treeNodeService.toggleNodes(nodes,true)">Expand All</button>
<button (click)="treeNodeService.toggleNodes(nodes,false)">Collapse All</button>
<tree-view id="heroes" [nodes]="nodes"></tree-view>
</div>
`
})
export class AppComponent implements OnInit {
nodes: TreeNode[] = [];

constructor(private treeNodeService: TreeNodeService) {
}

ngOnInit() {
this.treeNodeService
.getTreeNodes()
.then((nodes: TreeNode[]) => this.nodes = nodes)
.catch((error: any) => console.log(error)); // TODO: Display error
}
}
27 changes: 27 additions & 0 deletions public/docs/_examples/cb-tree-view/ts/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpModule } from '@angular/http';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { AddHeroComponent } from './add-hero.component';
import { HeroNodeComponent } from './hero-node.component';
import { TreeViewComponent } from './tree-view.component';
import { TreeNodeService } from './tree-node.service';

@NgModule({
imports: [
BrowserModule,
HttpModule,
FormsModule
],
declarations: [
AppComponent,
AddHeroComponent,
HeroNodeComponent,
TreeViewComponent
],
providers: [ TreeNodeService ],
bootstrap: [ AppComponent ]
})
export class AppModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<!-- #docregion -->
<div class="hero-node" [ngClass]="heroClass" >
<div>Name: {{hero.name}}</div>
<div>Ranking: {{hero.ranking}}</div>
</div>
23 changes: 23 additions & 0 deletions public/docs/_examples/cb-tree-view/ts/app/hero-node.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// #docregion
import { Component, Input, OnInit } from '@angular/core';

import { Hero } from './hero';

@Component({
selector: 'hero-node',
templateUrl: 'app/hero-node.component.html'
})
export class HeroNodeComponent implements OnInit {
@Input() hero: Hero;
heroClass: string;

ngOnInit(): void {
if (this.hero.ranking > 7) {
this.heroClass = 'hero-top';
}else if (this.hero.ranking > 4) {
this.heroClass = 'hero-ok';
}else {
this.heroClass = 'hero-low';
}
}
}
4 changes: 4 additions & 0 deletions public/docs/_examples/cb-tree-view/ts/app/hero.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// #docregion
export class Hero {
constructor(public name?: string, public ranking?: number) { }
}
8 changes: 8 additions & 0 deletions public/docs/_examples/cb-tree-view/ts/app/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// #docregion
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app.module';

import 'rxjs/Rx';

platformBrowserDynamic().bootstrapModule(AppModule);
25 changes: 25 additions & 0 deletions public/docs/_examples/cb-tree-view/ts/app/mock-data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"nodes":[
{
"title":"USA",
"nodes":[
{
"title":"New York City",
"nodes":[
{"title":"Brooklyn","heroes":[{"name":"Dr IQ","ranking":10}]},
{"title":"Manhattan","heroes":[{"name":"Bombasto","ranking":2}]},
{"title":"Bronx","heroes":[{"name":"Celeritas","ranking":4}]},
{"title":"Queens","heroes":[{"name":"RubberMan","ranking":6}]},
{"title":"Staten Island","heroes":[{"name":"Dynama","ranking":8}]}]
}
]
},
{
"title":"Canada",
"nodes":[
{"title":"Calgary","heroes":[{"name":"Tornado","ranking":3},{"name":"Dynama","ranking":8}]},
{"title":"Ottawa","heroes":[{"name":"Magma","ranking":10}]}
]
}
]
}
59 changes: 59 additions & 0 deletions public/docs/_examples/cb-tree-view/ts/app/tree-node.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// #docregion
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';

import { TreeNode } from './tree-node';
import { Hero } from './hero';

@Injectable()
export class TreeNodeService {
private root = new TreeNode('Hero Regions', [], []);
selectedNode: TreeNode;

constructor(private http: Http) {}

// #docregion build-tree
private buildTreeRecursive(root: TreeNode, nodes: any[]): TreeNode {
if (nodes) {
nodes.forEach(node => {
let heroes = (node.heroes || []).map((hero: any) => new Hero(hero.name, hero.ranking));
let treeNode = new TreeNode(node.title, [], heroes);
root.nodes.push(this.buildTreeRecursive(treeNode, node.nodes));
return treeNode;
});
}
return root;
}

getTreeNodes(): Promise<TreeNode[]> {
return this.http.get('./app/mock-data.json')
.toPromise()
.then(res => {
let root = this.buildTreeRecursive(this.root, res.json().nodes);
return root.nodes;
});
}
// #enddocregion build-tree

addHero(newHero: Hero): void {
this.selectedNode.heroes.push(newHero);
}

// #docregion toggle-nodes
toggleNodes(nodes: TreeNode[], state: boolean): void {
nodes.forEach(node => {
node.expanded = state;
this.toggleNodes(node.nodes, state);
});
}
// #enddocregion toggle-nodes

selectNode(node: TreeNode): void {
if (this.selectedNode) {
this.selectedNode.unselect();
}

this.selectedNode = node;
this.selectedNode.select();
}
}
41 changes: 41 additions & 0 deletions public/docs/_examples/cb-tree-view/ts/app/tree-node.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// #docregion
import { Hero } from './hero';

export class TreeNode {

expanded: boolean = false;
selected: boolean = false;

constructor(public title: string, public nodes?: TreeNode[], public heroes?: Hero[]) {
}

getIcon(): string {
if (this.hasChildren()) {
if (this.expanded) {
return '-';
}
return '+';
}
return '';
}

toggle(): void {
this.expanded = !this.expanded;
if (this.expanded === false) {
this.selected = false;
}
}

select(): void {
this.selected = true;
this.expanded = true;
}

unselect(): void {
this.selected = false;
}

private hasChildren() {
return (this.nodes.length + this.heroes.length) > 0;
}
}
21 changes: 21 additions & 0 deletions public/docs/_examples/cb-tree-view/ts/app/tree-view.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!-- #docregion -->
<ul *ngIf="nodes.length > 0">
<li *ngFor="let node of nodes">
<a class="tree-node-icon" (click)="node.toggle()">{{node.getIcon()}}</a>
<a class="hero-location" (click)="select(node)" [ngClass]="{'node-selected':node.selected}">{{node.title}}</a>
<div *ngIf="node.expanded">
<ul>
<li *ngFor="let hero of node.heroes">
<hero-node [hero]="hero"></hero-node>
</li>
<li>
<div class="add-section" *ngIf="node.selected">
<add-hero></add-hero>
</div>
</li>
</ul>
<!--Self reference in the template-->
<tree-view [nodes]="node.nodes"></tree-view>
</div>
</li>
</ul>
19 changes: 19 additions & 0 deletions public/docs/_examples/cb-tree-view/ts/app/tree-view.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// #docregion
import { Component, Input } from '@angular/core';

import { TreeNode } from './tree-node';
import { TreeNodeService } from './tree-node.service';

@Component({
selector: 'tree-view',
templateUrl: './app/tree-view.component.html'
})
export class TreeViewComponent {
@Input() nodes: Array<TreeNode>;

constructor(private treeNodeService: TreeNodeService) {}

select(node: TreeNode): void {
this.treeNodeService.selectNode(node);
}
}
Empty file.
Loading