Checkbox Selection for TreeTable
parent
0ef6de80a3
commit
9656540538
|
@ -36,8 +36,8 @@
|
|||
<tbody class="p-treetable-tbody">
|
||||
<template v-if="!empty">
|
||||
<TTRow v-for="node of dataToRender" :key="node.key" :columns="columns" :node="node" :level="0"
|
||||
:expandedKeys="d_expandedKeys" @node-toggle="onNodeToggle" @node-click="onNodeClick"
|
||||
:selectionMode="selectionMode" :selectionKeys="selectionKeys"></TTRow>
|
||||
:expandedKeys="d_expandedKeys" @node-toggle="onNodeToggle"
|
||||
:selectionMode="selectionMode" :selectionKeys="selectionKeys" @node-click="onNodeClick" @checkbox-change="onCheckboxChange"></TTRow>
|
||||
</template>
|
||||
<tr v-else class="p-treetable-emptymessage">
|
||||
<td :colspan="columns.length">
|
||||
|
@ -232,7 +232,7 @@ export default {
|
|||
this.$emit('update:expandedKeys', this.d_expandedKeys);
|
||||
},
|
||||
onNodeClick(event) {
|
||||
if (this.selectionMode != null && event.node.selectable !== false) {
|
||||
if (this.rowSelectionMode && event.node.selectable !== false) {
|
||||
const metaSelection = event.nodeTouched ? false : this.metaKeySelection;
|
||||
const _selectionKeys = metaSelection ? this.handleSelectionWithMetaKey(event) : this.handleSelectionWithoutMetaKey(event);
|
||||
|
||||
|
@ -304,6 +304,14 @@ export default {
|
|||
|
||||
return _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);
|
||||
},
|
||||
isSingleSelectionMode() {
|
||||
return this.selectionMode === 'single';
|
||||
},
|
||||
|
@ -595,7 +603,7 @@ export default {
|
|||
computed: {
|
||||
containerClass() {
|
||||
return ['p-treetable p-component', {
|
||||
'p-treetable-hoverable-rows': (this.rowHover || this.selectionMode),
|
||||
'p-treetable-hoverable-rows': (this.rowHover || this.rowSelectionMode),
|
||||
'p-treetable-auto-layout': this.autoLayout
|
||||
}];
|
||||
},
|
||||
|
@ -673,6 +681,15 @@ export default {
|
|||
paginatorBottom() {
|
||||
return this.paginator && (this.paginatorPosition !== 'top' || this.paginatorPosition === 'both');
|
||||
},
|
||||
singleSelectionMode() {
|
||||
return this.selectionMode && this.selectionMode === 'single';
|
||||
},
|
||||
multipleSelectionMode() {
|
||||
return this.selectionMode && this.selectionMode === 'multiple';
|
||||
},
|
||||
rowSelectionMode() {
|
||||
return this.singleSelectionMode || this.multipleSelectionMode;
|
||||
},
|
||||
totalRecordsLength() {
|
||||
if (this.lazy) {
|
||||
return this.totalRecords;
|
||||
|
|
|
@ -4,6 +4,14 @@
|
|||
<span class="p-treetable-toggler p-unselectable-text" @click="toggle" v-if="col.expander" :style="togglerStyle">
|
||||
<i :class="togglerIcon"></i>
|
||||
</span>
|
||||
<div class="p-checkbox p-treetable-checkbox p-component" @click="toggleCheckbox" v-if="checkboxSelectionMode">
|
||||
<div class="p-hidden-accessible">
|
||||
<input type="checkbox" />
|
||||
</div>
|
||||
<div :class="checkboxClass">
|
||||
<span :class="checkboxIcon"></span>
|
||||
</div>
|
||||
</div>
|
||||
<TTColumnSlot :data="node" :column="col" type="body" v-if="col.$scopedSlots.body" />
|
||||
<template v-else>{{resolveFieldData(node.data, col.field)}}</template>
|
||||
</td>
|
||||
|
@ -22,6 +30,10 @@ export default {
|
|||
type: null,
|
||||
default: null
|
||||
},
|
||||
parentNode: {
|
||||
type: null,
|
||||
default: null
|
||||
},
|
||||
columns: {
|
||||
type: null,
|
||||
default: null
|
||||
|
@ -52,34 +64,82 @@ export default {
|
|||
this.$emit('node-toggle', this.node);
|
||||
},
|
||||
onClick(event) {
|
||||
if (DomHandler.hasClass(event.target, 'p-treetable-toggler') || DomHandler.hasClass(event.target, 'p-treetable-toggler-icon')) {
|
||||
let targetNode = event.target.nodeName;
|
||||
if (targetNode === 'INPUT' || targetNode === 'BUTTON' || targetNode === 'A' || DomHandler.hasClass(event.target, 'p-clickable')
|
||||
|| DomHandler.hasClass(event.target, 'p-treetable-toggler') || DomHandler.hasClass(event.target.parentElement, 'p-treetable-toggler')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isCheckboxSelectionMode()) {
|
||||
this.toggleCheckbox();
|
||||
}
|
||||
else {
|
||||
this.$emit('node-click', {
|
||||
this.$emit('node-click', {
|
||||
originalEvent: event,
|
||||
nodeTouched: this.nodeTouched,
|
||||
node: this.node
|
||||
});
|
||||
}
|
||||
|
||||
this.nodeTouched = false;
|
||||
},
|
||||
isCheckboxSelectionMode() {
|
||||
return this.selectionMode === 'checkbox';
|
||||
},
|
||||
toggleCheckbox() {
|
||||
|
||||
},
|
||||
onTouchEnd() {
|
||||
this.nodeTouched = true;
|
||||
},
|
||||
onKeyDown(event) {
|
||||
//todo
|
||||
},
|
||||
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
|
||||
});
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -111,6 +171,21 @@ export default {
|
|||
},
|
||||
childLevel() {
|
||||
return this.level + 1;
|
||||
},
|
||||
checkboxSelectionMode() {
|
||||
return this.selectionMode === 'checkbox';
|
||||
},
|
||||
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}];
|
||||
},
|
||||
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;
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
|
|
@ -34,7 +34,8 @@ const TreeTableRowLoader = {
|
|||
props: context.props,
|
||||
on: {
|
||||
'node-toggle': context.listeners['node-toggle'],
|
||||
'node-click': context.listeners['node-click']
|
||||
'node-click': context.listeners['node-click'],
|
||||
'checkbox-change': context.listeners['checkbox-change']
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -46,13 +47,47 @@ const TreeTableRowLoader = {
|
|||
for (let childNode of node.children) {
|
||||
let childNodeProps = {...context.props};
|
||||
childNodeProps.node = childNode;
|
||||
childNodeProps.parentNode = node;
|
||||
childNodeProps.level = context.props.level + 1;
|
||||
|
||||
let childNodeElement = createElement(TreeTableRowLoader, {
|
||||
props: childNodeProps,
|
||||
on: {
|
||||
'node-toggle': context.listeners['node-toggle'],
|
||||
'node-click': context.listeners['node-click']
|
||||
'node-click': context.listeners['node-click'],
|
||||
'checkbox-change': (event) => {
|
||||
let check = event.check;
|
||||
let _selectionKeys = {...event.selectionKeys};
|
||||
let checkedChildCount = 0;
|
||||
let childPartialSelected = false;
|
||||
|
||||
for(let child of 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 === node.children.length) {
|
||||
_selectionKeys[node.key] = {checked: true, partialChecked: false};
|
||||
}
|
||||
else {
|
||||
if (!check) {
|
||||
delete _selectionKeys[node.key];
|
||||
}
|
||||
|
||||
if(childPartialSelected || (checkedChildCount > 0 && checkedChildCount !== node.children.length))
|
||||
_selectionKeys[node.key] = {checked: false, partialChecked: true};
|
||||
else
|
||||
_selectionKeys[node.key] = {checked: false, partialChecked: false};
|
||||
}
|
||||
|
||||
context.listeners['checkbox-change']({
|
||||
node: event.node,
|
||||
check: event.check,
|
||||
selectionKeys: _selectionKeys
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue