Accordion Trees

Accordions are multi-pane panels that keep only one panel expanded at a time. They are commonly used for navigation. You can use the TreeView control to implement accordions. This sample creates an Accordion using the TreeView and CSS by customizing the header display, hiding glyphs and setting autoCollapse property to true.

import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './styles.css'; import * as wjNav from '@grapecity/wijmo.nav'; import * as wjCore from '@grapecity/wijmo'; import { getData } from './data'; // document.readyState === 'complete' ? init() : window.onload = init; // function init() { // // create the tree var tree = new wjNav.TreeView('#theTree', { itemsSource: getData(), displayMemberPath: 'header', childItemsPath: 'items', isContentHtml: true, }); // // toggle accordion style document.getElementById('customCss').addEventListener('click', function (e) { wjCore.toggleClass(tree.hostElement, 'accordion', e.target.checked); }); // // handle clicks on accordion items tree.hostElement.addEventListener('click', function (e) { if (e.target.tagName == 'A') { var msg = document.getElementById('msg'); msg.innerHTML = wjCore.format('Navigating to <b>** {href} **</b>', e.target); e.preventDefault(); } }); } <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>GrapeCity Sample</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app'); </script> </head> <body> <div class="container-fluid"> <label> Use Custom CSS <input id="customCss" type="checkbox" checked="checked"> </label> <div id="msg" class="msg">Ready</div> <div id="theTree" class="accordion"></div> </div> </body> </html> // get the tree data export function getData() { return [ { header: 'Angular', items: [ { header: '<a href="ng/intro">Introduction</a>' }, { header: '<a href="ng/samples">Samples</a>' }, { header: '<a href="ng/perf">Performance</a>' } ] }, { header: 'React', items: [ { header: '<a href="rc/intro">Introduction</a>' }, { header: '<a href="rc/samples">Samples</a>' }, { header: '<a href="rc/perf">Performance</a>' } ] }, { header: 'Vue', items: [ { header: '<a href="vue/intro">Introduction</a>' }, { header: '<a href="vue/samples">Samples</a>' }, { header: '<a href="vue/perf">Performance</a>' } ] }, { header: 'Knockout', items: [ { header: '<a href="ko/intro">Introduction</a>' }, { header: '<a href="ko/samples">Samples</a>' }, { header: '<a href="ko/perf">Performance</a>' } ] } ]; } /* style for messages */ .msg { float: right; text-align: right; color: orange; } /* accordion tree styles */ .accordion.wj-treeview { background: transparent; box-shadow: none; } /* hide collapse/expand glyphs */ .accordion.wj-treeview .wj-nodelist .wj-node:before { display: none; } /* level 0 nodes (headers) */ .accordion.wj-treeview .wj-nodelist > .wj-node { font-size: 120%; font-weight: bold; padding: 6px 10px; color: white; background: #106cc8; margin-bottom: 4px; box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); } /* level 1 nodes (navigation items) */ .accordion.wj-treeview .wj-nodelist > .wj-nodelist > .wj-node { font-size: inherit; font-weight: normal; padding: 4px 1em; color: inherit; background: inherit; box-shadow: none; } .accordion.wj-treeview .wj-nodelist { padding-bottom: 6px; } /* default trees on this sample */ .wj-treeview { display:block; height: 350px; font-size: 120%; margin-bottom: 8px; padding: 6px; background: #f0f0f0; box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23); } body { margin-bottom: 24pt; } import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './styles.css'; import * as wjCore from '@grapecity/wijmo'; // import { Component, Inject, enableProdMode, NgModule, ViewChild, AfterViewInit } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { BrowserModule } from '@angular/platform-browser'; import { WjNavModule, WjTreeView } from '@grapecity/wijmo.angular2.nav'; import { DataService, TreeItem } from './app.data'; // @Component({ selector: 'app-component', templateUrl: 'src/app.component.html' }) export class AppComponent implements AfterViewInit { @ViewChild('theTree') theTree: WjTreeView; data: TreeItem[]; msg: string = "Ready"; // constructor(@Inject(DataService) private dataService: DataService) { this.data = dataService.getData(); } // ngAfterViewInit() { var self = this; self.theTree.hostElement.addEventListener('click', function (e: MouseEvent) { if ((e.target as HTMLElement).tagName == 'A') { self.msg = wjCore.format('Navigating to <b>** {href} **</b>', e.target); e.preventDefault(); } }); } // onCustomCssClick(e: MouseEvent) { wjCore.toggleClass(this.theTree.hostElement, 'accordion', (e.target as HTMLInputElement).checked); } } // @NgModule({ imports: [WjNavModule, BrowserModule], declarations: [AppComponent], providers: [DataService], bootstrap: [AppComponent] }) export class AppModule { } // enableProdMode(); // Bootstrap application with hash style navigation and global services. platformBrowserDynamic().bootstrapModule(AppModule); <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>GrapeCity Wijmo TreeView Styling Accordion Trees</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- Polyfills --> <script src="node_modules/core-js/client/shim.min.js"></script> <script src="node_modules/zone.js/dist/zone.min.js"></script> <!-- SystemJS --> <script src="node_modules/systemjs/dist/system.js"></script> <script src="systemjs.config.js"></script> <script> // workaround to load 'rxjs/operators' from the rxjs bundle System.import('rxjs').then(function (m) { System.set(SystemJS.resolveSync('rxjs/operators'), System.newModule(m.operators)); System.import('./src/app.component'); }); </script> </head> <body> <app-component></app-component> </body> </html> <div class="container-fluid"> <label> Use Custom CSS <input id="customCss" type="checkbox" checked="checked" (click)="onCustomCssClick($event)"> </label> <div id="msg" class="msg" [innerHtml]="msg">Ready</div> <wj-tree-view #theTree [itemsSource]="data" [displayMemberPath]="'header'" [childItemsPath]="'items'" [isContentHtml]=true class="accordion"></wj-tree-view> </div> import { Injectable } from '@angular/core'; export class TreeItem { header: string; items?: TreeItem[] } @Injectable() export class DataService { getData(): TreeItem[] { return [ { header: 'Angular', items: [ { header: '<a href="ng/intro">Introduction</a>' }, { header: '<a href="ng/samples">Samples</a>' }, { header: '<a href="ng/perf">Performance</a>' }] }, { header: 'React', items: [ { header: '<a href="rc/intro">Introduction</a>' }, { header: '<a href="rc/samples">Samples</a>' }, { header: '<a href="rc/perf">Performance</a>' }] }, { header: 'Vue', items: [ { header: '<a href="vue/intro">Introduction</a>' }, { header: '<a href="vue/samples">Samples</a>' }, { header: '<a href="vue/perf">Performance</a>' }] }, { header: 'Knockout', items: [ { header: '<a href="ko/intro">Introduction</a>' }, { header: '<a href="ko/samples">Samples</a>' }, { header: '<a href="ko/perf">Performance</a>' }] } ]; } } /* style for messages */ .msg { float: right; text-align: right; color: orange; } /* accordion tree styles */ .accordion.wj-treeview { background: transparent; box-shadow: none; } /* hide collapse/expand glyphs */ .accordion.wj-treeview .wj-nodelist .wj-node:before { display: none; } /* level 0 nodes (headers) */ .accordion.wj-treeview .wj-nodelist > .wj-node { font-size: 120%; font-weight: bold; padding: 6px 10px; color: white; background: #106cc8; margin-bottom: 4px; box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); } /* level 1 nodes (navigation items) */ .accordion.wj-treeview .wj-nodelist > .wj-nodelist > .wj-node { font-size: inherit; font-weight: normal; padding: 4px 1em; color: inherit; background: inherit; box-shadow: none; } .accordion.wj-treeview .wj-nodelist { padding-bottom: 6px; } /* default trees on this sample */ .wj-treeview { display:block; height: 350px; font-size: 120%; margin-bottom: 8px; padding: 6px; background: #f0f0f0; box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23); } body { margin-bottom: 24pt; } <template> <div class="container-fluid"> <div> <label> Use Custom CSS <input id="customCSS" type="checkbox" checked="true" v-on:click="onCustomCSSClick($event)"> </label> <div id="msg" class="msg" v-html="msg"></div> </div> <wj-tree-view :items-source="data" display-member-path="header" child-items-path="items" :is-content-html=true :initialized="initTreeView" class="accordion"></wj-tree-view> </div> </template> <script> import 'bootstrap.css'; import "@grapecity/wijmo.styles/wijmo.css"; import Vue from 'vue'; import '@grapecity/wijmo.vue2.nav'; import * as wjCore from '@grapecity/wijmo'; import { getData } from './data'; new Vue({ el: '#app', data: function () { return { data: getData(), msg: 'Ready' } }, methods:{ initTreeView: function(ctl){ this.wjTreeViewControl = ctl; }, onCustomCSSClick(e) { wjCore.toggleClass(this.wjTreeViewControl.hostElement, 'accordion', (e.target).checked); } }, mounted: function(e) { var self = this; this.wjTreeViewControl.hostElement.addEventListener("click", function(e) { if ((e.target).tagName == 'A') { self.msg = wjCore.format('Navigating to <b>** {href} **</b>', e.target); e.preventDefault(); } }); } }) </script> <style> /* style for messages */ .msg { float: right; text-align: right; color: orange; } /* accordion tree styles */ .accordion.wj-treeview { background: transparent; box-shadow: none; } /* hide collapse/expand glyphs */ .accordion.wj-treeview .wj-nodelist .wj-node:before { display: none; } /* level 0 nodes (headers) */ .accordion.wj-treeview .wj-nodelist > .wj-node { font-size: 120%; font-weight: bold; padding: 6px 10px; color: white; background: #106cc8; margin-bottom: 4px; box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); } /* level 1 nodes (navigation items) */ .accordion.wj-treeview .wj-nodelist > .wj-nodelist > .wj-node { font-size: inherit; font-weight: normal; padding: 4px 1em; color: inherit; background: inherit; box-shadow: none; } .accordion.wj-treeview .wj-nodelist { padding-bottom: 6px; } /* default trees on this sample */ .container-fluid .wj-treeview { display:block; height: 350px; font-size: 120%; margin-bottom: 8px; padding: 6px; background: #f0f0f0; box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23); } body { margin-bottom: 24pt; } </style> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>GrapeCity Sample</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app.vue'); </script> </head> <body> <div id="app"> </div> </body> </html> export function getData(){ return [ { header: 'Angular', items: [ { header: '<a href="ng/intro">Introduction</a>' }, { header: '<a href="ng/samples">Samples</a>' }, { header: '<a href="ng/perf">Performance</a>' }] }, { header: 'React', items: [ { header: '<a href="rc/intro">Introduction</a>' }, { header: '<a href="rc/samples">Samples</a>' }, { header: '<a href="rc/perf">Performance</a>' }] }, { header: 'Vue', items: [ { header: '<a href="vue/intro">Introduction</a>' }, { header: '<a href="vue/samples">Samples</a>' }, { header: '<a href="vue/perf">Performance</a>' }] }, { header: 'Knockout', items: [ { header: '<a href="ko/intro">Introduction</a>' }, { header: '<a href="ko/samples">Samples</a>' }, { header: '<a href="ko/perf">Performance</a>' }] } ]; } import './app.css'; import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; // import * as React from 'react'; import * as ReactDOM from 'react-dom'; // import * as wjNav from '@grapecity/wijmo.react.nav'; import * as wjCore from '@grapecity/wijmo'; import { getData } from './data'; class App extends React.Component { constructor(props) { super(props); this.state = { data: getData(), msg: 'Ready', customCSS: true }; } render() { return (<div className="container-fluid"> <div> <label> Use Custom CSS <input id="customCSS" type="checkbox" checked={this.state.customCSS} onClick={this.onCustomCSSClick.bind(this)}/> </label> <div id="msg" className="msg">{this.state.msg}</div> </div> <wjNav.TreeView itemsSource={this.state.data} displayMemberPath="header" childItemsPath="items" isContentHtml={true} initialized={this.initTreeView.bind(this)} className={this.state.customCSS ? "accordion" : ""}></wjNav.TreeView> </div>); } initTreeView(ctl) { this._wjTreeViewControl = ctl; } onCustomCSSClick() { wjCore.toggleClass(this._wjTreeViewControl.hostElement, 'accordion', !this.state.customCSS); this.setState({ customCSS: !this.state.customCSS }); } componentDidMount() { let self = this; this._wjTreeViewControl.hostElement.addEventListener("click", function (e) { if ((e.target).tagName == 'A') { self.setState({ msg: (<p> Navigating to <b>** {e.target.href} **</b> </p>) }); e.preventDefault(); } }); } } ReactDOM.render(<App />, document.getElementById('app')); <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>AutoComplete</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app'); </script> </head> <body> <div id="app"></div> </body> </html> /* style for messages */ .msg { float: right; text-align: right; color: orange; } /* accordion tree styles */ .accordion.wj-treeview { background: transparent; box-shadow: none; } /* hide collapse/expand glyphs */ .accordion.wj-treeview .wj-nodelist .wj-node:before { display: none; } /* level 0 nodes (headers) */ .accordion.wj-treeview .wj-nodelist > .wj-node { font-size: 120%; font-weight: bold; padding: 6px 10px; color: white; background: #106cc8; margin-bottom: 4px; box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); } /* level 1 nodes (navigation items) */ .accordion.wj-treeview .wj-nodelist > .wj-nodelist > .wj-node { font-size: inherit; font-weight: normal; padding: 4px 1em; color: inherit; background: inherit; box-shadow: none; } .accordion.wj-treeview .wj-nodelist { padding-bottom: 6px; } /* default trees on this sample */ .container-fluid .wj-treeview { display:block; height: 350px; font-size: 120%; margin-bottom: 8px; padding: 6px; background: #f0f0f0; box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23); } body { margin-bottom: 24pt; } export function getData() { return [ { header: 'Angular', items: [ { header: '<a href="ng/intro">Introduction</a>' }, { header: '<a href="ng/samples">Samples</a>' }, { header: '<a href="ng/perf">Performance</a>' } ] }, { header: 'React', items: [ { header: '<a href="rc/intro">Introduction</a>' }, { header: '<a href="rc/samples">Samples</a>' }, { header: '<a href="rc/perf">Performance</a>' } ] }, { header: 'Vue', items: [ { header: '<a href="vue/intro">Introduction</a>' }, { header: '<a href="vue/samples">Samples</a>' }, { header: '<a href="vue/perf">Performance</a>' } ] }, { header: 'Knockout', items: [ { header: '<a href="ko/intro">Introduction</a>' }, { header: '<a href="ko/samples">Samples</a>' }, { header: '<a href="ko/perf">Performance</a>' } ] } ]; }