parent
f39b351f10
commit
435de17919
|
@ -5,6 +5,12 @@ const TreeTableProps = [
|
||||||
default: 'null',
|
default: 'null',
|
||||||
description: 'An array of treenodes.'
|
description: 'An array of treenodes.'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'dataKey',
|
||||||
|
type: 'string|function',
|
||||||
|
default: 'null',
|
||||||
|
description: 'Name of the field that uniquely identifies the a record in the data.'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'expandedKeys',
|
name: 'expandedKeys',
|
||||||
type: 'array',
|
type: 'array',
|
||||||
|
|
|
@ -10,6 +10,10 @@ export default {
|
||||||
type: null,
|
type: null,
|
||||||
default: null
|
default: null
|
||||||
},
|
},
|
||||||
|
dataKey: {
|
||||||
|
type: [String, Function],
|
||||||
|
default: 'key'
|
||||||
|
},
|
||||||
expandedKeys: {
|
expandedKeys: {
|
||||||
type: null,
|
type: null,
|
||||||
default: null
|
default: null
|
||||||
|
|
|
@ -395,6 +395,11 @@ export interface TreeTableProps {
|
||||||
* An array of treenodes.
|
* An array of treenodes.
|
||||||
*/
|
*/
|
||||||
value?: TreeNode[] | undefined;
|
value?: TreeNode[] | undefined;
|
||||||
|
/**
|
||||||
|
* Name of the field that uniquely identifies the a record in the data.
|
||||||
|
* @defaultValue "key"
|
||||||
|
*/
|
||||||
|
dataKey?: string | ((item: any) => string) | undefined;
|
||||||
/**
|
/**
|
||||||
* A map of keys to represent the state of the tree expansion state in controlled mode.
|
* A map of keys to represent the state of the tree expansion state in controlled mode.
|
||||||
* @see TreeTableExpandedKeys
|
* @see TreeTableExpandedKeys
|
||||||
|
|
|
@ -83,7 +83,8 @@
|
||||||
<template v-if="!empty">
|
<template v-if="!empty">
|
||||||
<TTRow
|
<TTRow
|
||||||
v-for="(node, index) of dataToRender"
|
v-for="(node, index) of dataToRender"
|
||||||
:key="node.key"
|
:key="nodeKey(node)"
|
||||||
|
:dataKey="dataKey"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:node="node"
|
:node="node"
|
||||||
:level="0"
|
:level="0"
|
||||||
|
@ -252,8 +253,7 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
onNodeToggle(node) {
|
onNodeToggle(node) {
|
||||||
const key = node.key;
|
const key = this.nodeKey(node);
|
||||||
|
|
||||||
if (this.d_expandedKeys[key]) {
|
if (this.d_expandedKeys[key]) {
|
||||||
delete this.d_expandedKeys[key];
|
delete this.d_expandedKeys[key];
|
||||||
this.$emit('node-collapse', node);
|
this.$emit('node-collapse', node);
|
||||||
|
@ -273,9 +273,13 @@ export default {
|
||||||
this.$emit('update:selectionKeys', _selectionKeys);
|
this.$emit('update:selectionKeys', _selectionKeys);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
nodeKey(node) {
|
||||||
|
return ObjectUtils.resolveFieldData(node, this.dataKey);
|
||||||
|
},
|
||||||
handleSelectionWithMetaKey(event) {
|
handleSelectionWithMetaKey(event) {
|
||||||
const originalEvent = event.originalEvent;
|
const originalEvent = event.originalEvent;
|
||||||
const node = event.node;
|
const node = event.node;
|
||||||
|
const nodeKey = this.nodeKey(node);
|
||||||
const metaKey = originalEvent.metaKey || originalEvent.ctrlKey;
|
const metaKey = originalEvent.metaKey || originalEvent.ctrlKey;
|
||||||
const selected = this.isNodeSelected(node);
|
const selected = this.isNodeSelected(node);
|
||||||
let _selectionKeys;
|
let _selectionKeys;
|
||||||
|
@ -285,7 +289,7 @@ export default {
|
||||||
_selectionKeys = {};
|
_selectionKeys = {};
|
||||||
} else {
|
} else {
|
||||||
_selectionKeys = { ...this.selectionKeys };
|
_selectionKeys = { ...this.selectionKeys };
|
||||||
delete _selectionKeys[node.key];
|
delete _selectionKeys[nodeKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$emit('node-unselect', node);
|
this.$emit('node-unselect', node);
|
||||||
|
@ -296,7 +300,7 @@ export default {
|
||||||
_selectionKeys = !metaKey ? {} : this.selectionKeys ? { ...this.selectionKeys } : {};
|
_selectionKeys = !metaKey ? {} : this.selectionKeys ? { ...this.selectionKeys } : {};
|
||||||
}
|
}
|
||||||
|
|
||||||
_selectionKeys[node.key] = true;
|
_selectionKeys[nodeKey] = true;
|
||||||
this.$emit('node-select', node);
|
this.$emit('node-select', node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,6 +308,7 @@ export default {
|
||||||
},
|
},
|
||||||
handleSelectionWithoutMetaKey(event) {
|
handleSelectionWithoutMetaKey(event) {
|
||||||
const node = event.node;
|
const node = event.node;
|
||||||
|
const nodeKey = this.nodeKey(node);
|
||||||
const selected = this.isNodeSelected(node);
|
const selected = this.isNodeSelected(node);
|
||||||
let _selectionKeys;
|
let _selectionKeys;
|
||||||
|
|
||||||
|
@ -313,18 +318,18 @@ export default {
|
||||||
this.$emit('node-unselect', node);
|
this.$emit('node-unselect', node);
|
||||||
} else {
|
} else {
|
||||||
_selectionKeys = {};
|
_selectionKeys = {};
|
||||||
_selectionKeys[node.key] = true;
|
_selectionKeys[nodeKey] = true;
|
||||||
this.$emit('node-select', node);
|
this.$emit('node-select', node);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (selected) {
|
if (selected) {
|
||||||
_selectionKeys = { ...this.selectionKeys };
|
_selectionKeys = { ...this.selectionKeys };
|
||||||
delete _selectionKeys[node.key];
|
delete _selectionKeys[nodeKey];
|
||||||
|
|
||||||
this.$emit('node-unselect', node);
|
this.$emit('node-unselect', node);
|
||||||
} else {
|
} else {
|
||||||
_selectionKeys = this.selectionKeys ? { ...this.selectionKeys } : {};
|
_selectionKeys = this.selectionKeys ? { ...this.selectionKeys } : {};
|
||||||
_selectionKeys[node.key] = true;
|
_selectionKeys[nodeKey] = true;
|
||||||
|
|
||||||
this.$emit('node-select', node);
|
this.$emit('node-select', node);
|
||||||
}
|
}
|
||||||
|
@ -572,7 +577,7 @@ export default {
|
||||||
return matched;
|
return matched;
|
||||||
},
|
},
|
||||||
isNodeSelected(node) {
|
isNodeSelected(node) {
|
||||||
return this.selectionMode && this.selectionKeys ? this.selectionKeys[node.key] === true : false;
|
return this.selectionMode && this.selectionKeys ? this.selectionKeys[this.nodeKey(node)] === true : false;
|
||||||
},
|
},
|
||||||
isNodeLeaf(node) {
|
isNodeLeaf(node) {
|
||||||
return node.leaf === false ? false : !(node.children && node.children.length);
|
return node.leaf === false ? false : !(node.children && node.children.length);
|
||||||
|
|
|
@ -41,7 +41,8 @@
|
||||||
<template v-if="expanded && node.children && node.children.length">
|
<template v-if="expanded && node.children && node.children.length">
|
||||||
<TreeTableRow
|
<TreeTableRow
|
||||||
v-for="childNode of node.children"
|
v-for="childNode of node.children"
|
||||||
:key="childNode.key"
|
:key="nodeKey(childNode)"
|
||||||
|
:dataKey="dataKey"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:node="childNode"
|
:node="childNode"
|
||||||
:parentNode="node"
|
:parentNode="node"
|
||||||
|
@ -76,6 +77,10 @@ export default {
|
||||||
type: null,
|
type: null,
|
||||||
default: null
|
default: null
|
||||||
},
|
},
|
||||||
|
dataKey: {
|
||||||
|
type: [String, Function],
|
||||||
|
default: 'key'
|
||||||
|
},
|
||||||
parentNode: {
|
parentNode: {
|
||||||
type: null,
|
type: null,
|
||||||
default: null
|
default: null
|
||||||
|
@ -150,6 +155,9 @@ export default {
|
||||||
onTouchEnd() {
|
onTouchEnd() {
|
||||||
this.nodeTouched = true;
|
this.nodeTouched = true;
|
||||||
},
|
},
|
||||||
|
nodeKey(node) {
|
||||||
|
return ObjectUtils.resolveFieldData(node, this.dataKey);
|
||||||
|
},
|
||||||
onKeyDown(event, item) {
|
onKeyDown(event, item) {
|
||||||
switch (event.code) {
|
switch (event.code) {
|
||||||
case 'ArrowDown':
|
case 'ArrowDown':
|
||||||
|
@ -320,8 +328,8 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
propagateDown(node, check, selectionKeys) {
|
propagateDown(node, check, selectionKeys) {
|
||||||
if (check) selectionKeys[node.key] = { checked: true, partialChecked: false };
|
if (check) selectionKeys[this.nodeKey(node)] = { checked: true, partialChecked: false };
|
||||||
else delete selectionKeys[node.key];
|
else delete selectionKeys[this.nodeKey(node)];
|
||||||
|
|
||||||
if (node.children && node.children.length) {
|
if (node.children && node.children.length) {
|
||||||
for (let child of node.children) {
|
for (let child of node.children) {
|
||||||
|
@ -336,19 +344,19 @@ export default {
|
||||||
let childPartialSelected = false;
|
let childPartialSelected = false;
|
||||||
|
|
||||||
for (let child of this.node.children) {
|
for (let child of this.node.children) {
|
||||||
if (_selectionKeys[child.key] && _selectionKeys[child.key].checked) checkedChildCount++;
|
if (_selectionKeys[this.nodeKey(child)] && _selectionKeys[this.nodeKey(child)].checked) checkedChildCount++;
|
||||||
else if (_selectionKeys[child.key] && _selectionKeys[child.key].partialChecked) childPartialSelected = true;
|
else if (_selectionKeys[this.nodeKey(child)] && _selectionKeys[this.nodeKey(child)].partialChecked) childPartialSelected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check && checkedChildCount === this.node.children.length) {
|
if (check && checkedChildCount === this.node.children.length) {
|
||||||
_selectionKeys[this.node.key] = { checked: true, partialChecked: false };
|
_selectionKeys[this.nodeKey(this.node)] = { checked: true, partialChecked: false };
|
||||||
} else {
|
} else {
|
||||||
if (!check) {
|
if (!check) {
|
||||||
delete _selectionKeys[this.node.key];
|
delete _selectionKeys[this.nodeKey(this.node)];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (childPartialSelected || (checkedChildCount > 0 && checkedChildCount !== this.node.children.length)) _selectionKeys[this.node.key] = { checked: false, partialChecked: true };
|
if (childPartialSelected || (checkedChildCount > 0 && checkedChildCount !== this.node.children.length)) _selectionKeys[this.nodeKey(this.node)] = { checked: false, partialChecked: true };
|
||||||
else _selectionKeys[this.node.key] = { checked: false, partialChecked: false };
|
else _selectionKeys[this.nodeKey(this.node)] = { checked: false, partialChecked: false };
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$emit('checkbox-change', {
|
this.$emit('checkbox-change', {
|
||||||
|
@ -364,19 +372,19 @@ export default {
|
||||||
let childPartialSelected = false;
|
let childPartialSelected = false;
|
||||||
|
|
||||||
for (let child of this.node.children) {
|
for (let child of this.node.children) {
|
||||||
if (_selectionKeys[child.key] && _selectionKeys[child.key].checked) checkedChildCount++;
|
if (_selectionKeys[this.nodeKey(child)] && _selectionKeys[this.nodeKey(child)].checked) checkedChildCount++;
|
||||||
else if (_selectionKeys[child.key] && _selectionKeys[child.key].partialChecked) childPartialSelected = true;
|
else if (_selectionKeys[this.nodeKey(child)] && _selectionKeys[this.nodeKey(child)].partialChecked) childPartialSelected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check && checkedChildCount === this.node.children.length) {
|
if (check && checkedChildCount === this.node.children.length) {
|
||||||
_selectionKeys[this.node.key] = { checked: true, partialChecked: false };
|
_selectionKeys[this.nodeKey(this.node)] = { checked: true, partialChecked: false };
|
||||||
} else {
|
} else {
|
||||||
if (!check) {
|
if (!check) {
|
||||||
delete _selectionKeys[this.node.key];
|
delete _selectionKeys[this.nodeKey(this.node)];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (childPartialSelected || (checkedChildCount > 0 && checkedChildCount !== this.node.children.length)) _selectionKeys[this.node.key] = { checked: false, partialChecked: true };
|
if (childPartialSelected || (checkedChildCount > 0 && checkedChildCount !== this.node.children.length)) _selectionKeys[this.nodeKey(this.node)] = { checked: false, partialChecked: true };
|
||||||
else _selectionKeys[this.node.key] = { checked: false, partialChecked: false };
|
else _selectionKeys[this.nodeKey(this.node)] = { checked: false, partialChecked: false };
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$emit('checkbox-change', {
|
this.$emit('checkbox-change', {
|
||||||
|
@ -402,19 +410,19 @@ export default {
|
||||||
return [this.node.styleClass, this.cx('row')];
|
return [this.node.styleClass, this.cx('row')];
|
||||||
},
|
},
|
||||||
expanded() {
|
expanded() {
|
||||||
return this.expandedKeys && this.expandedKeys[this.node.key] === true;
|
return this.expandedKeys && this.expandedKeys[this.nodeKey(this.node)] === true;
|
||||||
},
|
},
|
||||||
leaf() {
|
leaf() {
|
||||||
return this.node.leaf === false ? false : !(this.node.children && this.node.children.length);
|
return this.node.leaf === false ? false : !(this.node.children && this.node.children.length);
|
||||||
},
|
},
|
||||||
selected() {
|
selected() {
|
||||||
return this.selectionMode && this.selectionKeys ? this.selectionKeys[this.node.key] === true : false;
|
return this.selectionMode && this.selectionKeys ? this.selectionKeys[this.nodeKey(this.node)] === true : false;
|
||||||
},
|
},
|
||||||
checked() {
|
checked() {
|
||||||
return this.selectionKeys ? this.selectionKeys[this.node.key] && this.selectionKeys[this.node.key].checked : false;
|
return this.selectionKeys ? this.selectionKeys[this.nodeKey(this.node)] && this.selectionKeys[this.nodeKey(this.node)].checked : false;
|
||||||
},
|
},
|
||||||
partialChecked() {
|
partialChecked() {
|
||||||
return this.selectionKeys ? this.selectionKeys[this.node.key] && this.selectionKeys[this.node.key].partialChecked : false;
|
return this.selectionKeys ? this.selectionKeys[this.nodeKey(this.node)] && this.selectionKeys[this.nodeKey(this.node)].partialChecked : false;
|
||||||
},
|
},
|
||||||
getAriaSelected() {
|
getAriaSelected() {
|
||||||
return this.selectionMode === 'single' || this.selectionMode === 'multiple' ? this.selected : null;
|
return this.selectionMode === 'single' || this.selectionMode === 'multiple' ? this.selected : null;
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<DocSectionText v-bind="$attrs">
|
<DocSectionText v-bind="$attrs">
|
||||||
<p>Selection of multiple nodes via checkboxes is enabled by configuring <i>selectionMode</i> as <i>checkbox</i>.</p>
|
<p>Selection of multiple nodes via checkboxes is enabled by configuring <i>selectionMode</i> as <i>checkbox</i>.</p>
|
||||||
<p>In checkbox selection mode, value binding should be a key-value pair where key is the node key and value is an object that has <i>checked</i> and <i>partialChecked</i> properties to represent the checked state of a node.</p>
|
<p>
|
||||||
|
In checkbox selection mode, value binding should be a key-value pair where key (or the dataKey) is the node key and value is an object that has <i>checked</i> and <i>partialChecked</i> properties to represent the checked state of a node.
|
||||||
|
</p>
|
||||||
</DocSectionText>
|
</DocSectionText>
|
||||||
<DocSectionCode :code="introCode" hideToggleCode importCode hideCodeSandbox hideStackBlitz />
|
<DocSectionCode :code="introCode" hideToggleCode importCode hideCodeSandbox hideStackBlitz />
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
|
Loading…
Reference in New Issue