diff --git a/src/demo/app/app.component.ts b/src/demo/app/app.component.ts
index e335df66..92cf53ac 100644
--- a/src/demo/app/app.component.ts
+++ b/src/demo/app/app.component.ts
@@ -31,7 +31,7 @@ declare const alertify: any;
@@ -175,9 +179,17 @@ declare const alertify: any;
})
export class AppComponent implements OnInit {
public settings: Ng2TreeSettings = {
- rootIsVisible: false
+ rootIsVisible: false,
+ showCheckboxes: true,
+ };
+
+ public disabledCheckboxesSettings: Ng2TreeSettings = {
+ rootIsVisible: false,
+ showCheckboxes: true,
+ enableCheckboxes: false
};
+
public fonts: TreeModel = {
value: 'Fonts',
children: [
@@ -188,18 +200,18 @@ export class AppComponent implements OnInit {
'static': true
},
children: [
- {value: '
Antiqua with HTML tags.', id: 2},
- {value: 'DejaVu Serif', id: 3},
- {value: 'Garamond', id: 4},
- {value: 'Georgia', id: 5},
- {value: 'Times New Roman', id: 6},
+ { value: '
Antiqua with HTML tags.', id: 2 },
+ { value: 'DejaVu Serif', id: 3 },
+ { value: 'Garamond', id: 4 },
+ { value: 'Georgia', id: 5 },
+ { value: 'Times New Roman', id: 6 },
{
value: 'Slab serif',
id: 7,
children: [
- {value: 'Candida', id: 8},
- {value: 'Swift', id: 9},
- {value: 'Guardian Egyptian', id: 10}
+ { value: 'Candida', id: 8 },
+ { value: 'Swift', id: 9 },
+ { value: 'Guardian Egyptian', id: 10 }
]
}
]
@@ -215,29 +227,29 @@ export class AppComponent implements OnInit {
]
},
children: [
- {value: 'Arial', id: 12},
- {value: 'Century Gothic', id: 13},
- {value: 'DejaVu Sans', id: 14},
- {value: 'Futura', id: 15},
- {value: 'Geneva', id: 16},
- {value: 'Liberation Sans', id: 17}
+ { value: 'Arial', id: 12 },
+ { value: 'Century Gothic', id: 13 },
+ { value: 'DejaVu Sans', id: 14 },
+ { value: 'Futura', id: 15 },
+ { value: 'Geneva', id: 16 },
+ { value: 'Liberation Sans', id: 17 }
]
},
{
value: 'Monospace - With ASYNC CHILDREN',
id: 18,
// children property is ignored if "loadChildren" is present
- children: [{value: 'I am the font that will be ignored'}],
+ children: [{ value: 'I am the font that will be ignored' }],
loadChildren: (callback) => {
setTimeout(() => {
callback([
- {value: 'Input Mono', id: 19},
- {value: 'Roboto Mono', id: 20},
- {value: 'Liberation Mono', id: 21},
- {value: 'Hack', id: 22},
- {value: 'Consolas', id: 23},
- {value: 'Menlo', id: 24},
- {value: 'Source Code Pro', id: 25}
+ { value: 'Input Mono', id: 19 },
+ { value: 'Roboto Mono', id: 20 },
+ { value: 'Liberation Mono', id: 21 },
+ { value: 'Hack', id: 22 },
+ { value: 'Consolas', id: 23 },
+ { value: 'Menlo', id: 24 },
+ { value: 'Source Code Pro', id: 25 }
]);
}, 5000);
}
@@ -253,6 +265,7 @@ export class AppComponent implements OnInit {
value: '/',
id: 1,
settings: {
+
cssClasses: {
expanded: 'fa fa-caret-down',
collapsed: 'fa fa-caret-right',
@@ -269,6 +282,7 @@ export class AppComponent implements OnInit {
value: 'bin',
id: 2,
children: [
+
{value: 'bash', id: 3},
{value: 'umount', id: 4},
{value: 'cp', id: 5},
@@ -292,13 +306,13 @@ export class AppComponent implements OnInit {
value: 'grub',
id: 14,
children: [
- {value: 'fonts', id: 15},
- {value: 'gfxblacklist.txt', id: 16},
- {value: 'grub.cfg', id: 17},
- {value: 'grubenv', id: 18},
- {value: 'i386-pc', id: 19},
- {value: 'locale', id: 20},
- {value: 'unicode.pf2', id: 21}
+ { value: 'fonts', id: 15 },
+ { value: 'gfxblacklist.txt', id: 16 },
+ { value: 'grub.cfg', id: 17 },
+ { value: 'grubenv', id: 18 },
+ { value: 'i386-pc', id: 19 },
+ { value: 'locale', id: 20 },
+ { value: 'unicode.pf2', id: 21 }
]
},
{
@@ -306,15 +320,15 @@ export class AppComponent implements OnInit {
id: 22,
children: []
},
- {value: 'abi-4.4.0-57-generic', id: 23},
- {value: 'config-4.4.0-57-generic', id: 24},
- {value: 'initrd.img-4.4.0-47-generic', id: 25},
- {value: 'initrd.img-4.4.0-57-generic', id: 26},
- {value: 'memtest86+.bin', id: 27},
- {value: 'System.map-4.4.0-57-generic', id: 28},
- {value: 'memtest86+.elf', id: 29},
- {value: 'vmlinuz-4.4.0-57-generic', id: 30},
- {value: 'memtest86+_multiboot.bin', id: 31}
+ { value: 'abi-4.4.0-57-generic', id: 23 },
+ { value: 'config-4.4.0-57-generic', id: 24 },
+ { value: 'initrd.img-4.4.0-47-generic', id: 25 },
+ { value: 'initrd.img-4.4.0-57-generic', id: 26 },
+ { value: 'memtest86+.bin', id: 27 },
+ { value: 'System.map-4.4.0-57-generic', id: 28 },
+ { value: 'memtest86+.elf', id: 29 },
+ { value: 'vmlinuz-4.4.0-57-generic', id: 30 },
+ { value: 'memtest86+_multiboot.bin', id: 31 }
]
},
{
@@ -348,8 +362,8 @@ export class AppComponent implements OnInit {
}
]
},
- {value: 'cdrom', id: 34, children: []},
- {value: 'dev', id: 35, children: []},
+ { value: 'cdrom', id: 34, children: [] },
+ { value: 'dev', id: 35, children: [] },
{
value: 'etc',
id: 36,
@@ -357,10 +371,10 @@ export class AppComponent implements OnInit {
console.log('callback function called to load etc`s children');
setTimeout(() => {
callback([
- {value: 'apache2', id: 82, children: []},
- {value: 'nginx', id: 83, children: []},
- {value: 'dhcp', id: 84, children: []},
- {value: 'dpkg', id: 85, children: []}
+ { value: 'apache2', id: 82, children: [] },
+ { value: 'nginx', id: 83, children: [] },
+ { value: 'dhcp', id: 84, children: [] },
+ { value: 'dpkg', id: 85, children: [] }
]);
});
}
@@ -385,38 +399,38 @@ export class AppComponent implements OnInit {
value: 'bills',
id: 41,
children: [
- {value: '2016-07-01-mobile.pdf', id: 42},
- {value: '2016-07-01-electricity.pdf', id: 43},
- {value: '2016-07-01-water.pdf', id: 44},
- {value: '2016-07-01-internet.pdf', id: 45},
- {value: '2016-08-01-mobile.pdf', id: 46},
- {value: '2016-10-01-internet.pdf', id: 47}
+ { value: '2016-07-01-mobile.pdf', id: 42 },
+ { value: '2016-07-01-electricity.pdf', id: 43 },
+ { value: '2016-07-01-water.pdf', id: 44 },
+ { value: '2016-07-01-internet.pdf', id: 45 },
+ { value: '2016-08-01-mobile.pdf', id: 46 },
+ { value: '2016-10-01-internet.pdf', id: 47 }
]
},
- {value: 'photos', id: 48, children: []}
+ { value: 'photos', id: 48, children: [] }
]
}
]
},
- {value: 'Downloads', id: 49, children: []},
- {value: 'Desktop', id: 50, children: []},
- {value: 'Pictures', id: 51, children: []},
+ { value: 'Downloads', id: 49, children: [] },
+ { value: 'Desktop', id: 50, children: [] },
+ { value: 'Pictures', id: 51, children: [] },
{
value: 'Music',
id: 52,
- children: [{value: 'won\'t be displayed'}],
+ children: [{ value: 'won\'t be displayed' }],
loadChildren: (callback) => {
setTimeout(() => {
callback([
- {value: '2Cellos', id: 78, children: []},
- {value: 'Michael Jackson', id: 79, children: []},
- {value: 'AC/DC', id: 80, children: []},
- {value: 'Adel', id: 81, children: []}
+ { value: '2Cellos', id: 78, children: [] },
+ { value: 'Michael Jackson', id: 79, children: [] },
+ { value: 'AC/DC', id: 80, children: [] },
+ { value: 'Adel', id: 81, children: [] }
]);
}, 5000);
}
},
- {value: 'Public', id: 53, children: []}
+ { value: 'Public', id: 53, children: [] }
]
},
{
@@ -426,7 +440,7 @@ export class AppComponent implements OnInit {
leftMenu: true
},
children: [
- {value: 'Documents', id: 55, children: []},
+ { value: 'Documents', id: 55, children: [] },
{
value: 'Downloads - custom left menu template',
id: 56,
@@ -436,33 +450,33 @@ export class AppComponent implements OnInit {
}
},
children: [
- {value: 'Actobat3', id: 57},
- {value: 'Complib', id: 58},
- {value: 'Eudora', id: 59},
- {value: 'java', id: 60},
- {value: 'drivers', id: 61},
- {value: 'kathy', id: 62}
+ { value: 'Actobat3', id: 57 },
+ { value: 'Complib', id: 58 },
+ { value: 'Eudora', id: 59 },
+ { value: 'java', id: 60 },
+ { value: 'drivers', id: 61 },
+ { value: 'kathy', id: 62 }
]
},
- {value: 'Desktop', id: 63, children: []},
- {value: 'Pictures', id: 64, children: []},
- {value: 'Music', id: 65, children: []},
- {value: 'Public', id: 66, children: []}
+ { value: 'Desktop', id: 63, children: [] },
+ { value: 'Pictures', id: 64, children: [] },
+ { value: 'Music', id: 65, children: [] },
+ { value: 'Public', id: 66, children: [] }
]
}
]
},
- {value: 'lib', id: 67, children: []},
- {value: 'media', id: 68, children: []},
- {value: 'opt', id: 69, children: []},
- {value: 'proc', id: 70, children: []},
- {value: 'root', id: 71, children: []},
- {value: 'run', id: 72, children: []},
- {value: 'sbin', id: 73, children: []},
- {value: 'srv', id: 74, children: []},
- {value: 'sys', id: 75, children: []},
- {value: 'usr', id: 76, children: []},
- {value: 'var', id: 77, children: []}
+ { value: 'lib', id: 67, children: [] },
+ { value: 'media', id: 68, children: [] },
+ { value: 'opt', id: 69, children: [] },
+ { value: 'proc', id: 70, children: [] },
+ { value: 'root', id: 71, children: [] },
+ { value: 'run', id: 72, children: [] },
+ { value: 'sbin', id: 73, children: [] },
+ { value: 'srv', id: 74, children: [] },
+ { value: 'sys', id: 75, children: [] },
+ { value: 'usr', id: 76, children: [] },
+ { value: 'var', id: 77, children: [] }
]
};
private lastFFSNodeId = 86;
@@ -475,31 +489,31 @@ export class AppComponent implements OnInit {
{
value: 'Web Application Icons',
children: [
- {value: 'calendar', icon: 'fa-calendar' },
- {value: 'download', icon: 'fa-download' },
- {value: 'group', icon: 'fa-group' },
- {value: 'print', icon: 'fa-print' }
+ { value: 'calendar', icon: 'fa-calendar' },
+ { value: 'download', icon: 'fa-download' },
+ { value: 'group', icon: 'fa-group' },
+ { value: 'print', icon: 'fa-print' }
]
},
{
value: 'Hand Icons',
children: [
- {value: 'pointer', icon: 'fa-hand-pointer-o' },
- {value: 'grab', icon: 'fa-hand-rock-o' },
- {value: 'thumbs up', icon: 'fa-thumbs-o-up ' },
- {value: 'thumbs down', icon: 'fa-thumbs-o-down' }
+ { value: 'pointer', icon: 'fa-hand-pointer-o' },
+ { value: 'grab', icon: 'fa-hand-rock-o' },
+ { value: 'thumbs up', icon: 'fa-thumbs-o-up ' },
+ { value: 'thumbs down', icon: 'fa-thumbs-o-down' }
]
},
{
value: 'File Type Icons',
children: [
- {value: 'file', icon: 'fa-file-o' },
- {value: 'audio', icon: 'fa-file-audio-o' },
- {value: 'movie', icon: 'fa-file-movie-o ' },
- {value: 'archive', icon: 'fa-file-zip-o' }
+ { value: 'file', icon: 'fa-file-o' },
+ { value: 'audio', icon: 'fa-file-audio-o' },
+ { value: 'movie', icon: 'fa-file-movie-o ' },
+ { value: 'archive', icon: 'fa-file-zip-o' }
]
},
- ]
+ ]
};
private static logEvent(e: NodeEvent, message: string): void {
@@ -515,8 +529,8 @@ export class AppComponent implements OnInit {
{
value: 'Aspect-oriented programming',
children: [
- {value: 'AspectJ'},
- {value: 'AspectC++'}
+ { value: 'AspectJ' },
+ { value: 'AspectC++' }
]
},
{
@@ -533,16 +547,16 @@ export class AppComponent implements OnInit {
}
} as RenamableNode
},
- {value: 'C++'},
- {value: 'C#'}
+ { value: 'C++' },
+ { value: 'C#' }
]
},
{
value: 'Prototype-based programming',
children: [
- {value: 'JavaScript'},
- {value: 'CoffeeScript'},
- {value: 'TypeScript'}
+ { value: 'JavaScript' },
+ { value: 'CoffeeScript' },
+ { value: 'TypeScript' }
]
}
]
@@ -611,11 +625,11 @@ export class AppComponent implements OnInit {
const treeController = this.treeFFS.getControllerByNodeId(id);
if (treeController && typeof treeController.setChildren === 'function') {
treeController.setChildren([
- {value: 'apache2', id: 82, children: []},
- {value: 'nginx', id: 83, children: []},
- {value: 'dhcp', id: 84, children: []},
- {value: 'dpkg', id: 85, children: []},
- {value: 'gdb', id: 86, children: []}
+ { value: 'apache2', id: 82, children: [] },
+ { value: 'nginx', id: 83, children: [] },
+ { value: 'dhcp', id: 84, children: [] },
+ { value: 'dpkg', id: 85, children: [] },
+ { value: 'gdb', id: 86, children: [] }
]);
} else {
console.log('There isn`t a controller for a node with id - ' + id);
@@ -631,4 +645,24 @@ export class AppComponent implements OnInit {
console.log(`Controller is absent for a node with id: ${id}`);
}
}
+
+ public checkFolder(id: number): void {
+ const treeController = this.treeFFS.getControllerByNodeId(id);
+ if (treeController) {
+ treeController.check();
+ } else {
+ console.log(`Controller is absent for a node with id: ${id}`);
+ }
+
+ }
+
+ public uncheckFolder(id: number): void {
+ const treeController = this.treeFFS.getControllerByNodeId(id);
+ if (treeController) {
+ treeController.uncheck();
+ } else {
+ console.log(`Controller is absent for a node with id: ${id}`);
+ }
+
+ }
}
diff --git a/src/tree-controller.ts b/src/tree-controller.ts
index 86fbe530..ff351f89 100644
--- a/src/tree-controller.ts
+++ b/src/tree-controller.ts
@@ -92,6 +92,13 @@ export class TreeController {
public startRenaming(): void {
this.tree.markAsBeingRenamed();
+ }
- }
+ public check() : void {
+ this.component.onNodeChecked()
+}
+
+public uncheck() : void {
+ this.component.onNodeUnchecked()
+}
}
diff --git a/src/tree-internal.component.ts b/src/tree-internal.component.ts
index 874c73fe..d542ba33 100644
--- a/src/tree-internal.component.ts
+++ b/src/tree-internal.component.ts
@@ -1,3 +1,4 @@
+
import {
Component,
ElementRef,
@@ -6,19 +7,22 @@ import {
OnDestroy,
OnInit,
SimpleChanges,
- TemplateRef
+ TemplateRef,
+ ViewChild
} from '@angular/core';
+
import * as TreeTypes from './tree.types';
import { Tree } from './tree';
import { TreeController } from './tree-controller';
import { NodeMenuService } from './menu/node-menu.service';
import { NodeMenuItemAction, NodeMenuItemSelectedEvent } from './menu/menu.events';
import { NodeEditableEvent, NodeEditableEventAction } from './editable/editable.events';
+import { NodeEvent, NodeRemovedEvent, NodeCheckedEvent, NodeIndeterminateEvent } from './tree.events'
import { TreeService } from './tree.service';
import * as EventUtils from './utils/event.utils';
import { NodeDraggableEvent } from './draggable/draggable.events';
import { Subscription } from 'rxjs/Subscription';
-import { get } from './utils/fn.utils';
+import { get, has } from './utils/fn.utils';
@Component({
selector: 'tree-internal',
@@ -33,6 +37,11 @@ import { get } from './utils/fn.utils';
[tree]="tree">
+
+
+
+
+
-
@@ -64,7 +73,7 @@ import { get } from './utils/fn.utils';
(menuItemSelected)="onMenuItemSelected($event)">
-
+
@@ -83,13 +92,20 @@ export class TreeInternalComponent implements OnInit, OnChanges, OnDestroy {
public isSelected = false;
public isRightMenuVisible = false;
public isLeftMenuVisible = false;
+ public isChecked = false;
+ public isReadOnly = false;
public controller: TreeController;
+
+ @ViewChild('checkbox')
+ _checkboxElement: ElementRef;
+
private subscriptions: Subscription[] = [];
+
public constructor(private nodeMenuService: NodeMenuService,
- public treeService: TreeService,
- public element: ElementRef) {
+ public treeService: TreeService,
+ public element: ElementRef) {
}
public ngOnInit(): void {
@@ -98,7 +114,13 @@ export class TreeInternalComponent implements OnInit, OnChanges, OnDestroy {
this.treeService.setController(this.tree.node.id, this.controller);
}
- this.settings = this.settings || { rootIsVisible: true };
+
+ this.settings = this.settings || { rootIsVisible: true, showCheckboxes: false, enableCheckboxes: true };
+
+ this.isChecked = this.tree.isChecked;
+
+ this.isReadOnly = has(this.settings, 'enableCheckboxes') ? !this.settings.enableCheckboxes : false;
+
this.subscriptions.push(this.nodeMenuService.hideMenuStream(this.element)
.subscribe(() => {
this.isRightMenuVisible = false;
@@ -118,6 +140,28 @@ export class TreeInternalComponent implements OnInit, OnChanges, OnDestroy {
this.moveNodeToParentTreeAndRemoveFromPreviousOne(e, this.tree);
}
}));
+
+ this.subscriptions.push(this.treeService.nodeChecked$
+ .filter((e: NodeCheckedEvent) => this.eventContainsId(e) && this.tree.children
+ && this.tree.children.some((child: Tree) => child.id === e.node.id))
+ .subscribe((e: NodeCheckedEvent) => {
+ this.updateIndeterminateState();
+ }));
+
+
+ this.subscriptions.push(this.treeService.nodeUnchecked$
+ .filter((e: NodeCheckedEvent) => this.eventContainsId(e) && this.tree.children
+ && this.tree.children.some((child: Tree) => child.id === e.node.id))
+ .subscribe((e: NodeCheckedEvent) => {
+ this.updateIndeterminateState();
+ }));
+
+
+ this.subscriptions.push(this.treeService.nodeIndeterminate$
+ .filter((e: NodeIndeterminateEvent) => this.eventContainsId(e) &&
+ this.tree.children && this.tree.children.some((child: Tree) => child.id === e.node.id))
+ .subscribe((e: NodeIndeterminateEvent) => {
+ }));
}
public ngOnChanges(changes: SimpleChanges): void {
@@ -256,4 +300,84 @@ export class TreeInternalComponent implements OnInit, OnChanges, OnDestroy {
public hasCustomMenu(): boolean {
return this.tree.hasCustomMenu();
}
+
+ public NodeCheckSatusChanged() {
+ if (!this.isChecked) {
+ this.onNodeChecked();
+ }
+ else {
+ this.onNodeUnchecked();
+ }
+
+ }
+
+ public onNodeChecked(): void {
+ this._checkboxElement.nativeElement.indeterminate = false;
+ this.treeService.fireNodeChecked(this.tree);
+ this.executeOnChildController(controller => controller.check());
+ this.isChecked = true;
+ this.tree.isChecked = true;
+ }
+
+ public onNodeUnchecked(): void {
+ this._checkboxElement.nativeElement.indeterminate = false;
+
+ this.treeService.fireNodeUnchecked(this.tree);
+
+ this.executeOnChildController(controller => controller.uncheck());
+ this.isChecked = false;
+ this.tree.isChecked = false;
+ }
+
+ private executeOnChildController(executor: (controller: TreeController) => void) {
+ if (this.tree.children) {
+ this.tree.children.forEach((child: Tree) => {
+ let controller = this.treeService.getController(child.id);
+ if (controller != null) {
+ executor(controller);
+ }
+ });
+ }
+ }
+
+ public updateIndeterminateState(): void {
+
+ setTimeout(() => { // Calling setTimeout so the value of isChecked will be updated and after that I'll check the children status.
+ this.updateIndeterminateStateInternal();
+ }, 1)
+ };
+
+
+ private updateIndeterminateStateInternal(): void {
+ const checkedChildren = this.tree.children.filter(child => child.isChecked).length;
+
+ if (checkedChildren === 0) {
+ this._checkboxElement.nativeElement.indeterminate = false;
+ this.isChecked = false;
+ this.tree.isChecked = false;
+ this.treeService.fireNodeUnchecked(this.tree)
+ }
+ else if (checkedChildren === this.tree.children.length) {
+ this._checkboxElement.nativeElement.indeterminate = false;
+ this.isChecked = true;
+ this.tree.isChecked = true;
+ this.treeService.fireNodeChecked(this.tree)
+ }
+ else {
+ this.setNodeInderminated();
+ }
+ }
+
+ private setNodeInderminated(): void {
+ this._checkboxElement.nativeElement.indeterminate = true;
+ this.treeService.fireNodeIndeterminate(this.tree);
+ }
+
+ private eventContainsId(event: NodeEvent): boolean {
+ if (!event.node.id) {
+ console.log('Checking feature requires a well known id for every node, lease prvide a unique id.')
+ return false;
+ }
+ return true;
+ }
}
diff --git a/src/tree.component.ts b/src/tree.component.ts
index c5540830..735ff7e8 100644
--- a/src/tree.component.ts
+++ b/src/tree.component.ts
@@ -4,7 +4,9 @@ import {
} from '@angular/core';
import { TreeService } from './tree.service';
import * as TreeTypes from './tree.types';
-import { NodeEvent, MenuItemSelectedEvent } from './tree.events';
+
+import { NodeEvent, NodeCheckedEvent, NodeUncheckedEvent,MenuItemSelectedEvent } from './tree.events';
+
import { Tree } from './tree';
import { TreeController } from './tree-controller';
import { Subscription } from 'rxjs/Subscription';
@@ -15,7 +17,7 @@ import { Subscription } from 'rxjs/Subscription';
providers: [TreeService]
})
export class TreeComponent implements OnInit, OnChanges, OnDestroy {
- private static EMPTY_TREE: Tree = new Tree({value: ''});
+ private static EMPTY_TREE: Tree = new Tree({ value: '' });
/* tslint:disable:no-input-rename */
@Input('tree')
@@ -47,11 +49,17 @@ export class TreeComponent implements OnInit, OnChanges, OnDestroy {
public nodeCollapsed: EventEmitter
= new EventEmitter();
@Output()
- public menuItemSelected: EventEmitter = new EventEmitter();
- @Output()
public loadNextLevel: EventEmitter = new EventEmitter();
+ @Output()
+ public nodeChecked: EventEmitter = new EventEmitter();
+
+ @Output()
+ public nodeUnchecked: EventEmitter = new EventEmitter();
+
+ public menuItemSelected: EventEmitter = new EventEmitter();
+
public tree: Tree;
@ViewChild('rootComponent') public rootComponent;
@@ -59,7 +67,7 @@ export class TreeComponent implements OnInit, OnChanges, OnDestroy {
private subscriptions: Subscription[] = [];
- public constructor(@Inject(TreeService) private treeService: TreeService) {
+ public constructor( @Inject(TreeService) private treeService: TreeService) {
}
public ngOnChanges(changes: SimpleChanges): void {
@@ -106,6 +114,11 @@ export class TreeComponent implements OnInit, OnChanges, OnDestroy {
this.subscriptions.push(this.treeService.loadNextLevel$.subscribe((e: NodeEvent) => {
this.loadNextLevel.emit(e);
}));
+
+ this.subscriptions.push(this.treeService.nodeChecked$.subscribe((e: NodeCheckedEvent) => this.nodeChecked.emit(e)));
+
+ this.subscriptions.push(this.treeService.nodeUnchecked$.subscribe((e: NodeUncheckedEvent) => this.nodeChecked.emit(e)));
+
}
public getController(): TreeController {
diff --git a/src/tree.events.ts b/src/tree.events.ts
index 63b3e73f..f4e317de 100644
--- a/src/tree.events.ts
+++ b/src/tree.events.ts
@@ -66,3 +66,21 @@ export class LoadNextLevelEvent extends NodeEvent {
super(node);
}
}
+
+export class NodeCheckedEvent extends NodeEvent {
+ public constructor(node: Tree) {
+ super(node);
+ }
+}
+
+export class NodeUncheckedEvent extends NodeEvent {
+ public constructor(node: Tree) {
+ super(node);
+ }
+}
+
+export class NodeIndeterminateEvent extends NodeEvent {
+ public constructor(node: Tree) {
+ super(node);
+ }
+}
\ No newline at end of file
diff --git a/src/tree.service.ts b/src/tree.service.ts
index 44751ba9..7042b090 100644
--- a/src/tree.service.ts
+++ b/src/tree.service.ts
@@ -6,9 +6,11 @@ import {
NodeRemovedEvent,
NodeRenamedEvent,
NodeSelectedEvent,
+ LoadNextLevelEvent,
+ NodeCheckedEvent,
+ NodeUncheckedEvent,
MenuItemSelectedEvent,
- LoadNextLevelEvent
-} from './tree.events';
+NodeIndeterminateEvent} from './tree.events';
import { RenamableNode } from './tree.types';
import { Tree } from './tree';
import { TreeController } from './tree-controller';
@@ -30,6 +32,9 @@ export class TreeService {
public nodeCollapsed$: Subject = new Subject();
public menuItemSelected$: Subject = new Subject();
public loadNextLevel$: Subject = new Subject();
+ public nodeChecked$ : Subject = new Subject();
+ public nodeUnchecked$ : Subject = new Subject();
+ public nodeIndeterminate$ : Subject = new Subject();
private controllers: Map = new Map();
@@ -88,6 +93,14 @@ export class TreeService {
this.loadNextLevel$.next(new LoadNextLevelEvent(tree));
}
+ public fireNodeChecked(tree: Tree) : void {
+ this.nodeChecked$.next(new NodeCheckedEvent(tree));
+ }
+
+ public fireNodeUnchecked(tree: Tree) : void {
+ this.nodeUnchecked$.next(new NodeUncheckedEvent(tree));
+ }
+
public draggedStream(tree: Tree, element: ElementRef): Observable {
return this.nodeDraggableService.draggableNodeEvents$
.filter((e: NodeDraggableEvent) => e.target === element)
@@ -129,4 +142,8 @@ export class TreeService {
return shouldLoadNextLevel;
}
+
+ public fireNodeIndeterminate(tree: Tree) : void {
+ this.nodeIndeterminate$.next(new NodeIndeterminateEvent(tree));
+ }
}
diff --git a/src/tree.ts b/src/tree.ts
index 780f4952..07f6e2e7 100644
--- a/src/tree.ts
+++ b/src/tree.ts
@@ -45,6 +45,7 @@ export class Tree {
public node: TreeModel;
public parent: Tree;
+ public isChecked: boolean;
// STATIC METHODS ----------------------------------------------------------------------------------------------------
diff --git a/src/tree.types.ts b/src/tree.types.ts
index 3633afeb..23fd1d52 100644
--- a/src/tree.types.ts
+++ b/src/tree.types.ts
@@ -27,6 +27,7 @@ export interface TreeModel {
_status?: TreeStatus;
_foldingType?: FoldingType;
[additionalData: string]: any;
+ checked?: boolean;
}
export interface CssClasses {
@@ -111,6 +112,8 @@ export interface Ng2TreeSettings {
* @type boolean
*/
rootIsVisible?: boolean;
+ showCheckboxes?: boolean;
+ enableCheckboxes?: boolean;
}
export enum TreeStatus {