how to make parent node checked if all child nodes checked
swuqi opened this issue · 3 comments
swuqi commented
Is there an option to make a parent node checked if all child nodes checked?
sorexalpinus commented
Looks like cascade check/uncheck functionality is not covered yet ...
You can use the following:
<div v-if="loaded">
<tree
:nodes="nodes"
:config="config"
@node-checked="onNodeStateChange"
@node-unchecked="onNodeStateChange"
></tree>
</div>
</template>
<script>
import Tree from "vue3-treeview";
import "vue3-treeview/dist/style.css";
export default {
name: "Test",
components: {Tree},
created() {
for(const nId in this.nodes) this.nodes[nId].id = nId;
this.loaded = true;
},
methods: {
onNodeStateChange(node) {
this.cascadeCheck(node);
},
cascadeCheck(node) {
node.state.indeterminate = false;
this.updateChildNodes(node);
this.updateParentNodes(node);
},
updateChildNodes(node) {
if(node.children?.length) {
node.children.forEach(chNodeId => {
if(!this.nodes[chNodeId].state) this.nodes[chNodeId].state = {};
this.nodes[chNodeId].state.checked = node.state.checked;
this.updateChildNodes(this.nodes[chNodeId]);
});
}
},
updateParentNodes(node)
{
let parents = [];
while (node) {
let parent = this.findParent(node);
if(parent) parents.push(parent);
node = parent;
}
parents.forEach(pNode => {
let checked = 0;
let total = pNode.children.length;
pNode.children.forEach(ch => {
if(this.nodes[ch].state.checked) checked++;
});
if(checked === total) {
pNode.state.indeterminate = false;
pNode.state.checked = true;
}
else if(checked === 0) {
pNode.state.indeterminate = false;
pNode.state.checked = false;
}
else {
pNode.state.indeterminate = true;
pNode.state.checked = false;
}
});
},
findParent(node) {
for(const nId in this.nodes) {
let cNode = this.nodes[nId];
if (cNode.children) {
if(cNode.children.includes(node.id)) return cNode;
}
}
return null;
}
},
data() {
return {
loaded: false,
config: {
roots: ["id1", "id2"],
checkboxes: true,
checkMode: 'auto'
},
nodes: {
id1: {
text: "text1",
children: ["id11", "id12"],
},
id11: {
text: "text11",
children: ["id111","id112"]
},
id111: {
text: "text 1.1.1"
},
id112: {
text: "text 1.1.2"
},
id12: {
text: "text12",
},
id2: {
text: "text2",
},
},
};
},
}
</script>`
N00ts commented
You are completely right. Cascading is only handeled for normal purpose which is
Parent node is checked only if all his child are checked.
If you need another behavior, you can still use the "manual" check mode :)
N00ts commented
closed