Skip to content

Commit 279e093

Browse files
committed
Merge branch 'DigitalFlow-feature/filterExample'
2 parents e5e6ab6 + 76e03cb commit 279e093

File tree

4 files changed

+202
-0
lines changed

4 files changed

+202
-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: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
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+
state = {
85+
checked: [
86+
'/app/Http/Controllers/WelcomeController.js',
87+
'/app/Http/routes.js',
88+
'/public/assets/style.css',
89+
'/public/index.html',
90+
'/.gitignore',
91+
],
92+
expanded: [
93+
'/app',
94+
],
95+
filterText: '',
96+
nodesFiltered: nodes,
97+
nodes,
98+
};
99+
100+
constructor(props) {
101+
super(props);
102+
103+
this.onCheck = this.onCheck.bind(this);
104+
this.onExpand = this.onExpand.bind(this);
105+
this.onFilterChange = this.onFilterChange.bind(this);
106+
this.filterTree = this.filterTree.bind(this);
107+
this.filterNodes = this.filterNodes.bind(this);
108+
}
109+
110+
onCheck(checked) {
111+
this.setState({ checked });
112+
}
113+
114+
onExpand(expanded) {
115+
this.setState({ expanded });
116+
}
117+
118+
onFilterChange(e) {
119+
this.setState({ filterText: e.target.value }, this.filterTree);
120+
}
121+
122+
filterTree() {
123+
// Reset nodes back to unfiltered state
124+
if (!this.state.filterText) {
125+
this.setState(prevState => ({
126+
nodesFiltered: prevState.nodes,
127+
}));
128+
129+
return;
130+
}
131+
132+
const nodesFiltered = prevState => (
133+
{ nodesFiltered: prevState.nodes.reduce(this.filterNodes, []) }
134+
);
135+
136+
this.setState(nodesFiltered);
137+
}
138+
139+
filterNodes(filtered, node) {
140+
const { filterText } = this.state;
141+
const children = (node.children || []).reduce(this.filterNodes, []);
142+
143+
if (
144+
// Node's label matches the search string
145+
node.label.toLocaleLowerCase().indexOf(filterText.toLocaleLowerCase()) > -1 ||
146+
// Or a children has a matching node
147+
children.length
148+
) {
149+
filtered.push({ ...node, children });
150+
}
151+
152+
return filtered;
153+
}
154+
155+
render() {
156+
const {
157+
checked,
158+
expanded,
159+
filterText,
160+
nodesFiltered,
161+
} = this.state;
162+
163+
return (
164+
<div className="filter-container">
165+
<input
166+
className="filter-text"
167+
placeholder="Search..."
168+
type="text"
169+
value={filterText}
170+
onChange={this.onFilterChange}
171+
/>
172+
<CheckboxTree
173+
checked={checked}
174+
expanded={expanded}
175+
nodes={nodesFiltered}
176+
onCheck={this.onCheck}
177+
onExpand={this.onExpand}
178+
/>
179+
</div>
180+
);
181+
}
182+
}
183+
184+
export default FilterExample;

examples/src/scss/style.scss

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ $header-bg-color-secondary: #2c3e50;
33
$section-headings-color: #3498db;
44
$rct-color: #444;
55
$rct-border-color: #ccc;
6+
$input-border-color: #ced4da;
67

78
@import "../../../src/scss/react-checkbox-tree";
89
@import "cayman";
@@ -23,3 +24,14 @@ $rct-border-color: #ccc;
2324
.expand-all-container {
2425
max-width: 400px;
2526
}
27+
28+
.filter-container > .filter-text {
29+
display: block;
30+
margin-bottom: .75rem;
31+
border: 1px solid $input-border-color;
32+
border-radius: .25rem;
33+
background-clip: padding-box;
34+
padding: .375rem .75rem;
35+
line-height: 1.5;
36+
font-size: 1rem;
37+
}

0 commit comments

Comments
 (0)