Selection for Organization Chart

pull/41/head
cagataycivici 2019-07-28 15:40:53 +03:00
parent aec2b01cc4
commit 16738f09dc
3 changed files with 99 additions and 23 deletions

View File

@ -1,6 +1,8 @@
<template> <template>
<div class="p-organizationchart p-component"> <div class="p-organizationchart p-component">
<OrganizationChartNode :node="value" :templates="$scopedSlots" @node-toggle="onNodeToggle" :collapsedKeys="d_collapsedKeys" :collapsible="collapsible" /> <OrganizationChartNode :node="value" :templates="$scopedSlots"
@node-toggle="onNodeToggle" :collapsedKeys="d_collapsedKeys" :collapsible="collapsible"
@node-click="onNodeClick" :selectionMode="selectionMode" :selectionKeys="selectionKeys" />
</div> </div>
</template> </template>
@ -13,6 +15,14 @@ export default {
type: null, type: null,
default: null default: null
}, },
selectionKeys: {
type: null,
default: null
},
selectionMode: {
type: String,
default: null
},
collapsible: { collapsible: {
type: Boolean, type: Boolean,
default: false default: false
@ -33,11 +43,39 @@ export default {
} }
}, },
methods: { methods: {
onNodeToggle(key) { onNodeClick(node) {
if (this.d_collapsedKeys[key]) const key = node.key;
if (this.selectionMode) {
let _selectionKeys = this.selectionKeys ? {...this.selectionKeys} : {};
if (_selectionKeys[key]) {
delete _selectionKeys[key];
this.$emit('node-unselect', node);
}
else {
if (this.selectionMode === 'single') {
_selectionKeys = {};
}
_selectionKeys[key] = true;
this.$emit('node-select', node);
}
this.$emit('update:selectionKeys', _selectionKeys);
}
},
onNodeToggle(node) {
const key = node.key;
if (this.d_collapsedKeys[key]) {
delete this.d_collapsedKeys[key]; delete this.d_collapsedKeys[key];
else this.$emit('node-expand', node);
}
else {
this.d_collapsedKeys[key] = true; this.d_collapsedKeys[key] = true;
this.$emit('node-collapse', node);
}
this.d_collapsedKeys = {...this.d_collapsedKeys}; this.d_collapsedKeys = {...this.d_collapsedKeys};
this.$emit('update:collapsedKeys', this.d_collapsedKeys); this.$emit('update:collapsedKeys', this.d_collapsedKeys);

View File

@ -31,7 +31,8 @@
</tr> </tr>
<tr :style="childStyle" class="p-organizationchart-nodes"> <tr :style="childStyle" class="p-organizationchart-nodes">
<td v-for="child of node.children" :key="child.key" colspan="2"> <td v-for="child of node.children" :key="child.key" colspan="2">
<sub-node :node="child" :templates="templates" :collapsedKeys="collapsedKeys" @node-toggle="onChildNodeToggle" :collapsible="collapsible" /> <sub-node :node="child" :templates="templates" :collapsedKeys="collapsedKeys" @node-toggle="onChildNodeToggle" :collapsible="collapsible"
:selectionMode="selectionMode" :selectionKeys="selectionKeys" @node-click="onChildNodeClick" />
</td> </td>
</tr> </tr>
</tbody> </tbody>
@ -39,6 +40,8 @@
</template> </template>
<script> <script>
import DomHandler from '../utils/DomHandler';
const OrganizationChartNodeTemplate = { const OrganizationChartNodeTemplate = {
functional: true, functional: true,
props: { props: {
@ -66,14 +69,6 @@ export default {
type: null, type: null,
default: null default: null
}, },
selected: {
type: Boolean,
default: false
},
selectable: {
type: Boolean,
default: false
},
templates: { templates: {
type: null, type: null,
default: null default: null
@ -85,17 +80,34 @@ export default {
collapsedKeys: { collapsedKeys: {
type: null, type: null,
default: null default: null
},
selectionKeys: {
type: null,
default: null
},
selectionMode: {
type: String,
default: null
} }
}, },
methods: { methods: {
onNodeClick() { onNodeClick(event) {
if (DomHandler.hasClass(event.target, 'p-node-toggler') || DomHandler.hasClass(event.target, 'p-node-toggler-icon')) {
return;
}
if (this.selectionMode) {
this.$emit('node-click', this.node);
}
},
onChildNodeClick(node) {
this.$emit('node-click', node);
}, },
toggleNode() { toggleNode() {
this.$emit('node-toggle', this.node.key); this.$emit('node-toggle', this.node);
}, },
onChildNodeToggle(key) { onChildNodeToggle(node) {
this.$emit('node-toggle', key); this.$emit('node-toggle', node);
} }
}, },
computed: { computed: {
@ -115,6 +127,12 @@ export default {
}, },
expanded() { expanded() {
return this.collapsedKeys[this.node.key] === undefined; return this.collapsedKeys[this.node.key] === undefined;
},
selectable() {
return this.selectionMode && this.node.selectable !== false;
},
selected() {
return this.selectable && this.selectionKeys && this.selectionKeys[this.node.key] === true;
} }
}, },
components: { components: {

View File

@ -10,7 +10,8 @@
<div class="content-section implementation"> <div class="content-section implementation">
<h3 class="first">Advanced</h3> <h3 class="first">Advanced</h3>
<p>Hierarchical data with zero configuration.</p> <p>Hierarchical data with zero configuration.</p>
<OrganizationChart :value="data1" :collapsible="true" class="company"> <OrganizationChart :value="data1" :collapsible="true" class="company" selectionMode="single" :selectionKeys.sync="selection"
@node-select="onNodeSelect" @node-unselect="onNodeUnselect" @node-collapse="onNodeCollapse" @node-expand="onNodeExpand">
<template #person="slotProps"> <template #person="slotProps">
<div class="node-header ui-corner-top">{{slotProps.node.data.label}}</div> <div class="node-header ui-corner-top">{{slotProps.node.data.label}}</div>
<div class="node-content"> <div class="node-content">
@ -55,11 +56,13 @@ export default {
children:[{ children:[{
key: '0_0_0', key: '0_0_0',
data: {label: 'Tax'}, data: {label: 'Tax'},
selectable: false,
styleClass: 'department-cfo' styleClass: 'department-cfo'
}, },
{ {
key: '0_0_1', key: '0_0_1',
data: {label: 'Legal'}, data: {label: 'Legal'},
selectable: false,
styleClass: 'department-cfo' styleClass: 'department-cfo'
}], }],
}, },
@ -71,6 +74,7 @@ export default {
children:[{ children:[{
key: '0_1_0', key: '0_1_0',
data: {label: 'Operations'}, data: {label: 'Operations'},
selectable: false,
styleClass: 'department-coo' styleClass: 'department-coo'
}] }]
}, },
@ -82,31 +86,37 @@ export default {
children:[{ children:[{
key: '0_2_0', key: '0_2_0',
data: {label: 'Development'}, data: {label: 'Development'},
selectable: false,
styleClass: 'department-cto', styleClass: 'department-cto',
children:[{ children:[{
key: '0_2_0_0', key: '0_2_0_0',
data: {label: 'Analysis'}, data: {label: 'Analysis'},
selectable: false,
styleClass: 'department-cto' styleClass: 'department-cto'
}, },
{ {
key: '0_2_0_1', key: '0_2_0_1',
data: {label: 'Front End'}, data: {label: 'Front End'},
selectable: false,
styleClass: 'department-cto' styleClass: 'department-cto'
}, },
{ {
key: '0_2_0_2', key: '0_2_0_2',
data: {label: 'Back End'}, data: {label: 'Back End'},
selectable: false,
styleClass: 'department-cto' styleClass: 'department-cto'
}] }]
}, },
{ {
key: '0_2_1', key: '0_2_1',
data: {label: 'QA'}, data: {label: 'QA'},
selectable: false,
styleClass: 'department-cto' styleClass: 'department-cto'
}, },
{ {
key: '0_2_2', key: '0_2_2',
data: {label: 'R&D'}, data: {label: 'R&D'},
selectable: false,
styleClass: 'department-cto' styleClass: 'department-cto'
}] }]
} }
@ -146,7 +156,21 @@ export default {
} }
] ]
}, },
selection: [] selection: {}
}
},
methods: {
onNodeSelect(node) {
this.$toast.add({severity:'success', summary: 'Node Selected', detail: node.data.label, life: 3000});
},
onNodeUnselect(node) {
this.$toast.add({severity:'success', summary: 'Node Unselected', detail: node.data.label, life: 3000});
},
onNodeExpand(node) {
this.$toast.add({severity:'success', summary: 'Node Expanded', detail: node.data.label, life: 3000});
},
onNodeCollapse(node) {
this.$toast.add({severity:'success', summary: 'Node Collapsed', detail: node.data.label, life: 3000});
} }
}, },
components: { components: {
@ -195,10 +219,6 @@ export default {
color: #ffffff; color: #ffffff;
} }
.p-organizationchart .p-highlight {
background-color: orange;
}
.p-person .p-node-toggler { .p-person .p-node-toggler {
color: #495ebb !important; color: #495ebb !important;
} }