Skip to content

Commit aa30601

Browse files
committed
Merge branch 'feature/filterExample' of https://github.com/DigitalFlow/react-checkbox-tree into DigitalFlow-feature/filterExample
2 parents e5e6ab6 + 3bbf3b9 commit aa30601

File tree

3 files changed

+170
-0
lines changed

3 files changed

+170
-0
lines changed

examples/src/index.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ <h2>Large Data Example</h2>
9393
<p>The checkbox tree is capable of supporting a large number of nodes at once.</p>
9494
<div id="large-data-example"></div>
9595

96+
<h2>Filter Example</h2>
97+
<p>Filtering of nodes is also easily possible</p>
98+
<div id="filter-example"></div>
99+
96100
<footer class="site-footer">
97101
<span class="site-footer-owner">
98102
<a href="https://github.com/jakezatecky/react-checkbox-tree">React Checkbox Tree</a> is maintained by <a href="https://github.com/jakezatecky">jakezatecky</a>.

examples/src/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import HiddenCheckboxesExample from './js/HiddenCheckboxesExample';
1010
import NoCascadeExample from './js/NoCascadeExample';
1111
import LargeDataExample from './js/LargeDataExample';
1212
import PessimisticToggleExample from './js/PessimisticToggleExample';
13+
import FilterExample from './js/FilterExample';
1314

1415
ReactDOM.render(<BasicExample />, document.getElementById('basic-example'));
1516
ReactDOM.render(<CustomIconsExample />, document.getElementById('custom-icons-example'));
@@ -20,3 +21,4 @@ ReactDOM.render(<ClickableLabelsExample />, document.getElementById('clickable-l
2021
ReactDOM.render(<HiddenCheckboxesExample />, document.getElementById('hidden-checkboxes-example'));
2122
ReactDOM.render(<ExpandAllExample />, document.getElementById('expand-all-example'));
2223
ReactDOM.render(<LargeDataExample />, document.getElementById('large-data-example'));
24+
ReactDOM.render(<FilterExample />, document.getElementById('filter-example'));

examples/src/js/FilterExample.js

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
import React from 'react';
2+
import CheckboxTree from 'react-checkbox-tree';
3+
4+
const nodes = [
5+
{
6+
value: '/app',
7+
label: 'app',
8+
children: [
9+
{
10+
value: '/app/Http',
11+
label: 'Http',
12+
children: [
13+
{
14+
value: '/app/Http/Controllers',
15+
label: 'Controllers',
16+
children: [{
17+
value: '/app/Http/Controllers/WelcomeController.js',
18+
label: 'WelcomeController.js',
19+
}],
20+
},
21+
{
22+
value: '/app/Http/routes.js',
23+
label: 'routes.js',
24+
},
25+
],
26+
},
27+
{
28+
value: '/app/Providers',
29+
label: 'Providers',
30+
children: [{
31+
value: '/app/Http/Providers/EventServiceProvider.js',
32+
label: 'EventServiceProvider.js',
33+
}],
34+
},
35+
],
36+
},
37+
{
38+
value: '/config',
39+
label: 'config',
40+
children: [
41+
{
42+
value: '/config/app.js',
43+
label: 'app.js',
44+
},
45+
{
46+
value: '/config/database.js',
47+
label: 'database.js',
48+
},
49+
],
50+
},
51+
{
52+
value: '/public',
53+
label: 'public',
54+
children: [
55+
{
56+
value: '/public/assets/',
57+
label: 'assets',
58+
children: [{
59+
value: '/public/assets/style.css',
60+
label: 'style.css',
61+
}],
62+
},
63+
{
64+
value: '/public/index.html',
65+
label: 'index.html',
66+
},
67+
],
68+
},
69+
{
70+
value: '/.env',
71+
label: '.env',
72+
},
73+
{
74+
value: '/.gitignore',
75+
label: '.gitignore',
76+
},
77+
{
78+
value: '/README.md',
79+
label: 'README.md',
80+
},
81+
];
82+
83+
class FilterExample extends React.Component {
84+
constructor() {
85+
super();
86+
87+
this.state = {
88+
checked: [
89+
'/app/Http/Controllers/WelcomeController.js',
90+
'/app/Http/routes.js',
91+
'/public/assets/style.css',
92+
'/public/index.html',
93+
'/.gitignore',
94+
],
95+
expanded: [
96+
'/app',
97+
],
98+
filterText: '',
99+
nodesFiltered: nodes,
100+
nodes,
101+
};
102+
103+
this.onCheck = this.onCheck.bind(this);
104+
this.onExpand = this.onExpand.bind(this);
105+
this.setFilterText = this.setFilterText.bind(this);
106+
this.filterTree = this.filterTree.bind(this);
107+
this.nodeFilter = this.nodeFilter.bind(this);
108+
}
109+
110+
onCheck(checked) {
111+
this.setState({ checked });
112+
}
113+
114+
onExpand(expanded) {
115+
this.setState({ expanded });
116+
}
117+
118+
setFilterText(e) {
119+
this.setState({ filterText: e.target.value }, this.filterTree);
120+
}
121+
122+
filterTree() {
123+
if (!this.state.filterText) {
124+
this.setState(prevState => ({
125+
nodesFiltered: prevState.nodes,
126+
}));
127+
128+
return;
129+
}
130+
131+
const nodesFiltered = prevState => (
132+
{ nodesFiltered: prevState.nodes.map(this.nodeFilter).filter(n => n !== null) }
133+
);
134+
135+
this.setState(nodesFiltered);
136+
}
137+
138+
nodeFilter(node) {
139+
const children = (node.children || []).map(this.nodeFilter).filter(c => c !== null);
140+
141+
return node.label.indexOf(this.state.filterText) !== -1 || children.length ?
142+
{ ...node, children } :
143+
null;
144+
}
145+
146+
render() {
147+
const { checked, expanded } = this.state;
148+
149+
return (
150+
<div>
151+
<input type='text' placeholder='Search' value={this.state.filterText} onChange={this.setFilterText} />
152+
<CheckboxTree
153+
checked={checked}
154+
expanded={expanded}
155+
nodes={this.state.nodesFiltered}
156+
onCheck={this.onCheck}
157+
onExpand={this.onExpand}
158+
/>
159+
</div>
160+
);
161+
}
162+
}
163+
164+
export default FilterExample;

0 commit comments

Comments
 (0)