diff --git a/src/components/tree/Tree.vue b/src/components/tree/Tree.vue
index c9cd119b8..f5e34f8da 100644
--- a/src/components/tree/Tree.vue
+++ b/src/components/tree/Tree.vue
@@ -3,7 +3,7 @@
+ :selectionMode="selectionMode" :selectionKeys="selectionKeys" @checkbox-change="onCheckboxChange">
@@ -33,14 +33,6 @@ export default {
type: Boolean,
default: true
},
- propagateSelectionDown: {
- type: Boolean,
- default: true
- },
- propagateSelectionUp: {
- type: Boolean,
- default: true
- },
loading: {
type: Boolean,
default: false
@@ -78,19 +70,20 @@ export default {
},
onNodeClick(event) {
if (this.selectionMode != null && event.node.selectable !== false) {
- let _selectionKeys;
-
- if (this.isCheckboxSelectionMode()) {
-
- }
- else {
- const metaSelection = event.nodeTouched ? false : this.metaKeySelection;
- _selectionKeys = metaSelection ? this.handleSelectionWithMetaKey(event) : this.handleSelectionWithoutMetaKey(event);
- }
+ const metaSelection = event.nodeTouched ? false : this.metaKeySelection;
+ const _selectionKeys = metaSelection ? this.handleSelectionWithMetaKey(event) : this.handleSelectionWithoutMetaKey(event);
this.$emit('update:selectionKeys', _selectionKeys);
}
},
+ onCheckboxChange(event) {
+ this.$emit('update:selectionKeys', event.selectionKeys);
+
+ if (event.check)
+ this.$emit('node-select', event.node);
+ else
+ this.$emit('node-unselect', event.node);
+ },
handleSelectionWithMetaKey(event) {
const originalEvent = event.originalEvent;
const node = event.node;
@@ -156,6 +149,46 @@ export default {
return _selectionKeys;
},
+ /*handleCheckboxSelection(event) {
+ const node = event.node;
+ const checked = this.isChecked(node);
+ let _selectionKeys = this.selectionKeys ? {...this.selectionKeys} : {};
+
+ if (checked) {
+ if (this.propagateSelectionDown)
+ this.propagateDown(node, false, _selectionKeys);
+ else
+ delete _selectionKeys[node.key];
+
+ if (this.propagateSelectionUp && this.props.onPropagateUp) {
+ this.props.onPropagateUp({
+ originalEvent: event,
+ check: false,
+ selectionKeys: selectionKeys
+ });
+ }
+
+ this.$emit('node-unselect', node);
+ }
+ else {
+ if (this.props.propagateSelectionDown)
+ this.propagateDown(this.props.node, true, selectionKeys);
+ else
+ selectionKeys[this.props.node.key] = {checked: true};
+
+ if (this.props.propagateSelectionUp && this.props.onPropagateUp) {
+ this.props.onPropagateUp({
+ originalEvent: event,
+ check: true,
+ selectionKeys: selectionKeys
+ });
+ }
+
+ this.$emit('node-select', node);
+ }
+
+ return _selectionKeys;
+ },*/
isCheckboxSelectionMode() {
return this.selectionMode === 'checkbox';
},
@@ -167,7 +200,10 @@ export default {
},
isSelected(node) {
return (this.selectionMode && this.selectionKeys) ? this.selectionKeys[node.key] === true : false;
- }
+ },
+ isChecked(node) {
+ return this.selectionKeys ? this.selectionKeys[node.key] && this.selectionKeys[node.key].checked: false;
+ },
},
computed: {
containerClass() {
diff --git a/src/components/tree/TreeNode.vue b/src/components/tree/TreeNode.vue
index e54369ba7..cf19d7f1c 100644
--- a/src/components/tree/TreeNode.vue
+++ b/src/components/tree/TreeNode.vue
@@ -5,13 +5,19 @@
+
{{node.label}}
+ :selectionMode="selectionMode" :selectionKeys="selectionKeys"
+ @checkbox-change="propagateUp">
@@ -52,11 +58,17 @@ export default {
return;
}
- this.$emit('node-click', {
- originalEvent: event,
- nodeTouched: this.nodeTouched,
- node: this.node
- });
+ if (this.isCheckboxSelectionMode()) {
+ this.toggleCheckbox();
+ }
+ else {
+ this.$emit('node-click', {
+ originalEvent: event,
+ nodeTouched: this.nodeTouched,
+ node: this.node
+ });
+ }
+
this.nodeTouched = false;
},
onChildNodeClick(event) {
@@ -125,6 +137,66 @@ export default {
break;
}
},
+ toggleCheckbox() {
+ let _selectionKeys = this.selectionKeys ? {...this.selectionKeys} : {};
+ const _check = !this.checked;
+
+ this.propagateDown(this.node, _check, _selectionKeys);
+
+ this.$emit('checkbox-change', {
+ node: this.node,
+ check: _check,
+ selectionKeys: _selectionKeys
+ });
+ },
+ propagateDown(node, check, selectionKeys) {
+ if (check)
+ selectionKeys[node.key] = {checked: true, partialChecked: false};
+ else
+ delete selectionKeys[node.key];
+
+ if (node.children && node.children.length) {
+ for (let child of node.children) {
+ this.propagateDown(child, check, selectionKeys);
+ }
+ }
+ },
+ propagateUp(event) {
+ let check = event.check;
+ let _selectionKeys = {...event.selectionKeys};
+ let checkedChildCount = 0;
+ let childPartialSelected = false;
+
+ for(let child of this.node.children) {
+ if(_selectionKeys[child.key] && _selectionKeys[child.key].checked)
+ checkedChildCount++;
+ else if(_selectionKeys[child.key] && _selectionKeys[child.key].partialChecked)
+ childPartialSelected = true;
+ }
+
+ if(check && checkedChildCount === this.node.children.length) {
+ _selectionKeys[this.node.key] = {checked: true, partialChecked: false};
+ }
+ else {
+ if (!check) {
+ delete _selectionKeys[this.node.key];
+ }
+
+ if(childPartialSelected || (checkedChildCount > 0 && checkedChildCount !== this.node.children.length))
+ _selectionKeys[this.node.key] = {checked: false, partialChecked: true};
+ else
+ _selectionKeys[this.node.key] = {checked: false, partialChecked: false};
+ }
+
+ this.$emit('checkbox-change', {
+ node: event.node,
+ check: event.check,
+ selectionKeys: _selectionKeys
+ });
+ },
+ onChildCheckboxChange(event) {
+ this.$emit('checkbox-change', event);
+ },
findNextSiblingOfAncestor(nodeElement) {
let parentNodeElement = this.getParentNodeElement(nodeElement);
if (parentNodeElement) {
@@ -155,6 +227,9 @@ export default {
},
focusNode(element) {
element.children[0].focus();
+ },
+ isCheckboxSelectionMode() {
+ return this.selectionMode === 'checkbox';
}
},
computed: {
@@ -179,7 +254,7 @@ export default {
contentClass() {
return ['p-treenode-content', {
'p-treenode-selectable': this.selectable,
- 'p-highlight': this.selected
+ 'p-highlight': this.checkboxMode ? this.checked : this.selected
}];
},
icon() {
@@ -190,6 +265,21 @@ export default {
'pi-caret-down': this.expanded,
'pi-caret-right': !this.expanded
}];
+ },
+ checkboxClass() {
+ return ['p-checkbox-box', {'p-highlight': this.checked}];
+ },
+ checkboxIcon() {
+ return ['p-checkbox-icon p-c', {'pi pi-check': this.checked, 'pi pi-minus': this.partialChecked}];
+ },
+ checkboxMode() {
+ return this.selectionMode === 'checkbox' && this.node.selectable !== false;
+ },
+ checked() {
+ return this.selectionKeys ? this.selectionKeys[this.node.key] && this.selectionKeys[this.node.key].checked: false;
+ },
+ partialChecked() {
+ return this.selectionKeys ? this.selectionKeys[this.node.key] && this.selectionKeys[this.node.key].partialChecked: false;
}
}
}
diff --git a/src/views/tree/TreeSelectionDemo.vue b/src/views/tree/TreeSelectionDemo.vue
index 65926ffae..5094104b7 100644
--- a/src/views/tree/TreeSelectionDemo.vue
+++ b/src/views/tree/TreeSelectionDemo.vue
@@ -12,15 +12,15 @@
Single Selection
- {{selectedKey}}
Multiple Selection with MetaKey
- {{selectedKeys1}}
Multiple Selection without MetaKey
- {{selectedKeys2}}
+
+ Checkbox Selection
+