示例
搜索TreeViews
搜索TreeViews并不简单,因为它们具有层次性。节点通常反映由其父节点部分定义的上下文,但也反映与该节点相关联的附加内容。
例如,如果用户在下面的TreeView中搜索“Electronics”,您可能想要也可能不想在结果中包含子节点。此外,如果项目包含详细说明,您可能需要添加关键字以帮助进行搜索。因此,如果用户输入例如“胡子”,您可能希望选择“修剪器/剃须刀”节点。
AutoComplete控件提供了一种实现与TreeView一起使用的搜索框的好方法。在此示例中,我们使用完整节点路径和关键字构建一个平面searchArray,并将其用作itemsSource以搜索TreeView。
除了'itemsSource'和'displayMemberPath'属性之外,我们还使用'searchMemberPath'属性来指定包含要包含在搜索中的关键字的字段的名称。例如,尝试在搜索框中输入“collect”或“food”:
import 'bootstrap.css';
import '@grapecity/wijmo.styles/wijmo.css';
import './styles.css';
import * as wjInput from '@grapecity/wijmo.input';
import * as wjNav from '@grapecity/wijmo.nav';
import { getData } from './data';
//
document.readyState === 'complete' ? init() : window.onload = init;
//
class searchItem {
}
function getSearchList(items, searchList, path) {
// set defaults
if (searchList == null)
searchList = [];
if (path == null)
path = '';
// add items and sub-items
for (var i = 0; i < items.length; i++) {
var item = items[i];
searchList.push({
item: item,
path: path + item.header,
keywords: item.keywords
});
if (item.items) {
getSearchList(item.items, searchList, path + item.header + ' / ');
}
}
return searchList;
}
//
function init() {
// create the tree
var tree = new wjNav.TreeView('#theTree', {
itemsSource: getData(),
displayMemberPath: 'header',
childItemsPath: 'items',
});
// create the search AutoComplete
var search = new wjInput.AutoComplete('#search', {
itemsSource: getSearchList(tree.itemsSource),
selectedIndex: -1,
displayMemberPath: 'path',
searchMemberPath: 'keywords',
selectedIndexChanged: function (s) {
if (s.selectedItem) {
tree.selectedItem = s.selectedItem.item;
}
}
});
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>GrapeCity Wijmo TreeView Searching</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 for="search">Search: </label>
<div id="search"></div>
<div id="theTree"></div>
</div>
</body>
</html>
export function getData() {
return [
{
header: 'Electronics', items: [
{ header: 'Trimmers/Shavers', keywords: 'beard hair' },
{ header: 'Tablets', keywords: 'screen computer android ios facebook' },
{
header: 'Phones', keywords: 'talk listen email fabebook', items: [
{ header: 'Apple' },
{ header: 'Motorola' },
{ header: 'Nokia' },
{ header: 'Samsung' }
]
},
{ header: 'Speakers', keywords: 'music loudspeaker' },
{ header: 'Monitors', keywords: 'screen color lcd oled' }
]
},
{
header: 'Toys', items: [
{ header: 'Shopkins', keywords: 'animals collectibles' },
{ header: 'Train Sets', keywords: 'models rail collectibles' },
{ header: 'Science Kit', keywords: 'education physics chemistry' },
{ header: 'Play-Doh', keywords: 'clay sculpt models' },
{ header: 'Crayola', keywords: 'drawing painting wax chalk pencils' }
]
},
{
header: 'Home', items: [
{ header: 'Coffeee Maker', keywords: 'kitchen appliance drink' },
{ header: 'Breadmaker', keywords: 'kitchen appliance food cooking' },
{ header: 'Solar Panel', keywords: 'electric sun renewable energy' },
{ header: 'Work Table', keywords: 'shop tools' },
{ header: 'Propane Grill', keywords: 'food cooking barbecue meat' }
]
}
];
}
.wj-control {
margin-bottom: 6px;
}
.wj-treeview {
display:block;
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 { Component, Inject, enableProdMode, NgModule, ViewChild, AfterViewInit } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { BrowserModule } from '@angular/platform-browser';
import { WjInputModule, WjAutoComplete } from '@grapecity/wijmo.angular2.input';
import { WjNavModule, WjTreeView } from '@grapecity/wijmo.angular2.nav';
import { DataService, TreeItem } from './app.data';
class searchItem {
item: any;
path: string;
keywords: string
}
//
@Component({
selector: 'app-component',
templateUrl: 'src/app.component.html'
})
export class AppComponent implements AfterViewInit {
@ViewChild('theTree') theTree: WjTreeView;
treeData: TreeItem[];
autoCompleteData: searchItem[];
//
constructor(@Inject(DataService) private dataService: DataService) {
}
//
ngAfterViewInit() {
this.theTree.itemsSource = this.dataService.getData();
this.autoCompleteData = this._getSearchList(this.theTree.itemsSource);
}
//
onSelectedIndexChanged(s: WjAutoComplete) {
if (s.selectedItem) {
this.theTree.selectedItem = s.selectedItem.item;
}
}
private _getSearchList(items: TreeItem[], searchList?: null | searchItem[], path?: string | null): searchItem[] {
// set defaults
if (searchList == null) searchList = [];
if (path == null) path = '';
// add items and sub-items
for (var i = 0; i < items.length; i++) {
var item = items[i];
searchList.push({
item: item,
path: path + item.header,
keywords: item.keywords
});
if (item.items) {
this._getSearchList(item.items, searchList, path + item.header + ' / ');
}
}
return searchList;
}
}
//
@NgModule({
imports: [WjNavModule, WjInputModule, 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 Searching</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 for="search">Search: </label>
<wj-auto-complete #searchAutoComplete [itemsSource]="autoCompleteData" [selectedIndex]=-1 [displayMemberPath]="'path'"
[searchMemberPath]="keywords" (selectedIndexChanged)="onSelectedIndexChanged(searchAutoComplete)"></wj-auto-complete>
<wj-tree-view #theTree [displayMemberPath]="'header'" [childItemsPath]="'items'"></wj-tree-view>
</div>
import { Injectable } from '@angular/core';
export class TreeItem {
header: string;
keywords?: string;
items?: TreeItem[]
}
@Injectable()
export class DataService {
getData(): TreeItem[] {
return [
{
header: 'Electronics', items: [
{ header: 'Trimmers/Shavers', keywords: 'beard hair' },
{ header: 'Tablets', keywords: 'screen computer android ios facebook' },
{
header: 'Phones', keywords: 'talk listen email fabebook', items: [
{ header: 'Apple' },
{ header: 'Motorola' },
{ header: 'Nokia' },
{ header: 'Samsung' }
]
},
{ header: 'Speakers', keywords: 'music loudspeaker' },
{ header: 'Monitors', keywords: 'screen color lcd oled' }
]
},
{
header: 'Toys', items: [
{ header: 'Shopkins', keywords: 'animals collectibles' },
{ header: 'Train Sets', keywords: 'models rail collectibles' },
{ header: 'Science Kit', keywords: 'education physics chemistry' },
{ header: 'Play-Doh', keywords: 'clay sculpt models' },
{ header: 'Crayola', keywords: 'drawing painting wax chalk pencils' }
]
},
{
header: 'Home', items: [
{ header: 'Coffeee Maker', keywords: 'kitchen appliance drink' },
{ header: 'Breadmaker', keywords: 'kitchen appliance food cooking' },
{ header: 'Solar Panel', keywords: 'electric sun renewable energy' },
{ header: 'Work Table', keywords: 'shop tools' },
{ header: 'Propane Grill', keywords: 'food cooking barbecue meat' }
]
}
];
}
}
.wj-control {
margin-bottom: 6px;
}
.wj-treeview {
display:block;
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">
<label for="search">Search: </label>
<wj-auto-complete :items-source="autoCompleteData" :selected-index=-1 display-member-path="path"
search-member-path="keywords" :selected-index-changed="onSelectedIndexChanged"></wj-auto-complete>
<wj-tree-view :items-source="data" display-member-path="header" child-items-path="items" :initialized="initTreeView"></wj-tree-view>
</div>
</template>
<script>
import 'bootstrap.css';
import "@grapecity/wijmo.styles/wijmo.css";
import Vue from 'vue';
import '@grapecity/wijmo.vue2.input';
import '@grapecity/wijmo.vue2.nav';
import * as wjCore from '@grapecity/wijmo';
import { getData } from './data';
var wjTreeViewControl = null;
var treeViewData= getData();
new Vue({
el: '#app',
data: function () {
return {
data: treeViewData,
autoCompleteData: _getSearchList(treeViewData)
}
},
methods:{
initTreeView: function(ctl){
wjTreeViewControl = ctl;
},
onSelectedIndexChanged: function(s) {
if (s.selectedItem) {
wjTreeViewControl.selectedItem = s.selectedItem.item;
}
}
}
})
function _getSearchList(items, searchList, path){
// set defaults
if (searchList == null) searchList = [];
if (path == null) path = '';
// add items and sub-items
for (var i = 0; i < items.length; i++) {
var item = items[i];
searchList.push({
item: item,
path: path + item.header,
keywords: item.keywords
});
if (item.items) {
_getSearchList(item.items, searchList, path + item.header + ' / ');
}
}
return searchList;
}
</script>
<style>
.container-fluid .wj-control {
margin-bottom: 6px;
}
.container-fluid .wj-treeview {
display:block;
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 Wijmo TreeView Searching</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: 'Electronics', img: 'resources/electronics.png', items: [
{ header: 'Trimmers/Shavers' },
{ header: 'Tablets' },
{
header: 'Phones', img: 'resources/phones.png', items: [
{ header: 'Apple' },
{ header: 'Motorola', newItem: true },
{ header: 'Nokia' },
{ header: 'Samsung' }]
},
{ header: 'Speakers', newItem: true },
{ header: 'Monitors' }]
},
{
header: 'Toys', img: 'resources/toys.png', items: [
{ header: 'Shopkins' },
{ header: 'Train Sets' },
{ header: 'Science Kit', newItem: true },
{ header: 'Play-Doh' },
{ header: 'Crayola' }]
},
{
header: 'Home', img: 'resources/home.png', items: [
{ header: 'Coffeee Maker' },
{ header: 'Breadmaker', newItem: true },
{ header: 'Solar Panel', newItem: true },
{ header: 'Work Table' },
{ header: 'Propane Grill' }]
}
];
}
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 wjInput from '@grapecity/wijmo.react.input';
import { getData } from './data';
class App extends React.Component {
constructor(props) {
super(props);
this._wjTreeViewControl = null;
this._treeViewData = getData();
this.state = {
data: this._treeViewData,
autoCompleteData: this.getSearchList(this._treeViewData, null, null)
};
}
initTreeView(ctl) {
this._wjTreeViewControl = ctl;
}
onSelectedIndexChanged(s) {
if (s.selectedItem) {
this._wjTreeViewControl.selectedItem = s.selectedItem.item;
}
}
getSearchList(items, searchList, path) {
// set defaults
if (searchList == null)
searchList = [];
if (path == null)
path = '';
// add items and sub-items
for (var i = 0; i < items.length; i++) {
var item = items[i];
searchList.push({
item: item,
path: path + item.header,
keywords: item.keywords
});
if (item.items) {
this.getSearchList(item.items, searchList, path + item.header + ' / ');
}
}
return searchList;
}
render() {
return (<div className="container-fluid">
<label htmlFor="search">Search: </label>
<wjInput.AutoComplete itemsSource={this.state.autoCompleteData} selectedIndex={-1} displayMemberPath="path" searchMemberPath="keywords" selectedIndexChanged={this.onSelectedIndexChanged.bind(this)}></wjInput.AutoComplete>
<wjNav.TreeView itemsSource={this.state.data} displayMemberPath="header" childItemsPath="items" initialized={this.initTreeView.bind(this)}></wjNav.TreeView>
</div>);
}
}
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>
.container-fluid .wj-control {
margin-bottom: 6px;
}
.container-fluid .wj-treeview {
display: block;
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: 'Electronics', img: 'resources/electronics.png', items: [
{ header: 'Trimmers/Shavers' },
{ header: 'Tablets' },
{
header: 'Phones', img: 'resources/phones.png', items: [
{ header: 'Apple' },
{ header: 'Motorola', newItem: true },
{ header: 'Nokia' },
{ header: 'Samsung' }
]
},
{ header: 'Speakers', newItem: true },
{ header: 'Monitors' }
]
},
{
header: 'Toys', img: 'resources/toys.png', items: [
{ header: 'Shopkins' },
{ header: 'Train Sets' },
{ header: 'Science Kit', newItem: true },
{ header: 'Play-Doh' },
{ header: 'Crayola' }
]
},
{
header: 'Home', img: 'resources/home.png', items: [
{ header: 'Coffeee Maker' },
{ header: 'Breadmaker', newItem: true },
{ header: 'Solar Panel', newItem: true },
{ header: 'Work Table' },
{ header: 'Propane Grill' }
]
}
];
}