Skip to content

Commit 0b78b5d

Browse files
mobilutzmrchief
authored andcommitted
feat: Allow to display children of found matches (#204)
* Use different classname than bootstrap `hide` classname is being used by bootstrap to hide elements. For us, we need to change the classname here in react-dropdown-tree-select to display everything correctly. * Option to show children on search results This allows for children of found matches to be displayed. With this option, one can search for the parent and then see all children and select any. * Add docs/bundle.js * Remove unnecessary line * nicer code * Code optimization * Rename addChildrensToTree * Update docs * ESLint * Remove bootstrap hide workaround * test: Updated syntax after merging latest develop * chore: Updated bundle after merging latest develop
1 parent 621988a commit 0b78b5d

File tree

8 files changed

+75
-14
lines changed

8 files changed

+75
-14
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ A lightweight and fast control to render a select component that can display hie
4646
- [placeholderText](#placeholdertext)
4747
- [noMatchesText](#nomatchestext)
4848
- [keepTreeOnSearch](#keeptreeonsearch)
49+
- [keepChildrenOnSearch](#keepchildrenonsearch)
4950
- [simpleSelect](#simpleselect)
5051
- [showPartiallySelected](#showpartiallyselected)
5152
- [showDropdown](#showDropdown)
@@ -275,6 +276,14 @@ Type: `bool`
275276

276277
Displays search results as a tree instead of flattened results
277278

279+
### keepChildrenOnSearch
280+
281+
Type: `bool`
282+
283+
Displays children of found nodes to allow searching for a parent node on then selecting any child node of the found node. Defaults to `false`
284+
285+
*NOTE* this works only in combination with `keepTreeOnSearch`
286+
278287
### simpleSelect
279288

280289
Type: `bool` (default: `false`)

docs/bundle.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class DropdownTreeSelect extends Component {
2424
data: PropTypes.oneOfType([PropTypes.object, PropTypes.array]).isRequired,
2525
clearSearchOnChange: PropTypes.bool,
2626
keepTreeOnSearch: PropTypes.bool,
27+
keepChildrenOnSearch: PropTypes.bool,
2728
placeholderText: PropTypes.string,
2829
showDropdown: PropTypes.bool,
2930
className: PropTypes.string,
@@ -117,7 +118,7 @@ class DropdownTreeSelect extends Component {
117118
}
118119

119120
onInputChange = value => {
120-
const { allNodesHidden, tree } = this.treeManager.filterTree(value, this.props.keepTreeOnSearch)
121+
const { allNodesHidden, tree } = this.treeManager.filterTree(value, this.props.keepTreeOnSearch, this.props.keepChildrenOnSearch)
121122
const searchModeOn = value.length > 0
122123

123124
this.setState({
@@ -220,6 +221,7 @@ class DropdownTreeSelect extends Component {
220221
<Tree
221222
data={this.state.tree}
222223
keepTreeOnSearch={this.props.keepTreeOnSearch}
224+
keepChildrenOnSearch={this.props.keepChildrenOnSearch}
223225
searchModeOn={this.state.searchModeOn}
224226
onAction={this.onAction}
225227
onCheckboxChange={this.onCheckboxChange}

src/tree-manager/index.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,22 @@ class TreeManager {
6565
}
6666
}
6767

68-
filterTree(searchTerm, keepTreeOnSearch) {
68+
addChildrenToTree(ids, tree, matches) {
69+
if (ids !== undefined) {
70+
ids.forEach(id => {
71+
if (matches && matches.includes(id)) {
72+
// if a child is found by search anyways, don't display it as a child here
73+
return
74+
}
75+
const node = this.getNodeById(id)
76+
node.matchInParent = true
77+
tree.set(id, node)
78+
this.addChildrenToTree(node._children, tree)
79+
})
80+
}
81+
}
82+
83+
filterTree(searchTerm, keepTreeOnSearch, keepChildrenOnSearch) {
6984
const matches = this.getMatches(searchTerm.toLowerCase())
7085

7186
const matchTree = new Map()
@@ -78,6 +93,10 @@ class TreeManager {
7893
this.addParentsToTree(node._parent, matchTree)
7994
}
8095
matchTree.set(m, node)
96+
if (keepTreeOnSearch && keepChildrenOnSearch) {
97+
// add children nodes after a found match
98+
this.addChildrenToTree(node._children, matchTree, matches)
99+
}
81100
})
82101

83102
const allNodesHidden = matches.length === 0

src/tree-manager/tests/flatten-tree.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ test('does not check parent with empty children when showing partial state', t =
394394
name: 'item3',
395395
value: 'value3',
396396
partial: false
397-
},
397+
}
398398
}
399399

400400
const { list } = flattenTree(tree, false, true)

src/tree-manager/tests/index.test.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,3 +543,34 @@ test('should restore default values', t => {
543543
t.true(manager.getNodeById('c1').checked)
544544
t.true(manager.getNodeById('i2').checked)
545545
})
546+
547+
test('should return children when search with `keepChildrenOnSearch`', t => {
548+
const tree = [
549+
{
550+
id: 'i1',
551+
label: 'search me',
552+
value: 'v1',
553+
children: [
554+
{
555+
id: 'c1',
556+
label: 'SeaRch me too',
557+
value: 'l1v1',
558+
children: [
559+
{
560+
id: 'c2',
561+
label: 'You can see me',
562+
value: 'l2v1'
563+
}
564+
]
565+
}
566+
]
567+
}
568+
]
569+
const manager = new TreeManager({ data: tree })
570+
const keepTreeOnSearch = true
571+
const keepChildrenOnSearch = true
572+
const { allNodesHidden, tree: matchTree } = manager.filterTree('search me', keepTreeOnSearch, keepChildrenOnSearch)
573+
t.false(allNodesHidden)
574+
const nodes = ['i1', 'c1', 'c2']
575+
nodes.forEach(n => t.not(matchTree.get(n), undefined))
576+
})

src/tree-node/index.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ const cx = cn.bind(styles)
1414
const isLeaf = children => isEmpty(children)
1515

1616
const getNodeCx = props => {
17-
const { keepTreeOnSearch, _children, matchInChildren, disabled, partial, hide, className, showPartiallySelected, readOnly } = props
17+
const {
18+
keepTreeOnSearch, keepChildrenOnSearch, _children, matchInChildren, matchInParent,
19+
disabled, partial, hide, className, showPartiallySelected, readOnly
20+
} = props
1821

1922
return cx(
2023
'node',
@@ -24,6 +27,7 @@ const getNodeCx = props => {
2427
disabled,
2528
hide,
2629
'match-in-children': keepTreeOnSearch && matchInChildren,
30+
'match-in-parent': keepTreeOnSearch && keepChildrenOnSearch && matchInParent,
2731
partial: showPartiallySelected && partial,
2832
readOnly
2933
},
@@ -47,6 +51,7 @@ class TreeNode extends PureComponent {
4751
partial: PropTypes.bool,
4852
dataset: PropTypes.object,
4953
keepTreeOnSearch: PropTypes.bool,
54+
keepChildrenOnSearch: PropTypes.bool,
5055
searchModeOn: PropTypes.bool,
5156
onNodeToggle: PropTypes.func,
5257
onAction: PropTypes.func,

src/tree/index.js

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class Tree extends Component {
1717
static propTypes = {
1818
data: PropTypes.object,
1919
keepTreeOnSearch: PropTypes.bool,
20+
keepChildrenOnSearch: PropTypes.bool,
2021
searchModeOn: PropTypes.bool,
2122
onChange: PropTypes.func,
2223
onNodeToggle: PropTypes.func,
@@ -59,22 +60,16 @@ class Tree extends Component {
5960

6061
getNodes = props => {
6162
const {
62-
data,
63-
keepTreeOnSearch,
64-
searchModeOn,
65-
simpleSelect,
66-
showPartiallySelected,
67-
readOnly,
68-
onAction,
69-
onChange,
70-
onCheckboxChange,
63+
data, keepTreeOnSearch, keepChildrenOnSearch, searchModeOn, simpleSelect,
64+
showPartiallySelected, readOnly, onAction, onChange, onCheckboxChange,
7165
onNodeToggle
7266
} = props
7367
const items = []
7468
data.forEach(node => {
7569
if (shouldRenderNode(node, searchModeOn, data)) {
7670
items.push(<TreeNode
7771
keepTreeOnSearch={keepTreeOnSearch}
72+
keepChildrenOnSearch={keepChildrenOnSearch}
7873
key={node._id}
7974
{...node}
8075
searchModeOn={searchModeOn}

0 commit comments

Comments
 (0)