Premium
The drag-and-drop functionality enables the user to move the TreeView items by dragging and dropping them within a single tree or across multiple trees.
BasicsTo implement dragging and dropping in the TreeView:
draggable
property to true
.drag
events.To facilitate the event handling, the TreeView provides the following utilities:
moveTreeViewItem
function—A helper function which moves a TreeView item in an immutable way.TreeViewDragAnalyzer
class—An API for analyzing the drag
events of the TreeView.TreeViewDragClue
component—A component which renders a clue when an item is dragged.The following example demonstrates how to:
expanded
and selected
item fields by using the processTreeViewItems
function.The following example demonstrates how to:
expanded
and selected
item fields.class App extends React.Component {
treeView1Guid;
treeView2Guid;
dragClue;
dragOverCnt = 0;
isDragDrop = false;
state = { tree, tree2 };
render() {
return (
<div>
<TreeView
data={this.state.tree}
draggable={true}
onItemDragOver={this.onItemDragOver}
onItemDragEnd={this.onItemDragEnd}
ref={(treeView) => (this.treeView1Guid = treeView && treeView.guid)}
expandIcons={true}
onExpandChange={this.onExpandChange}
onItemClick={this.onItemClick}
/>
<TreeView
data={this.state.tree2}
draggable={true}
onItemDragOver={this.onItemDragOver}
onItemDragEnd={this.onItemDragEnd}
ref={(treeView) => (this.treeView2Guid = treeView && treeView.guid)}
expandIcons={true}
onExpandChange={this.onExpandChange}
onItemClick={this.onItemClick}
/>
<TreeViewDragClue ref={(dragClue) => (this.dragClue = dragClue)} />
</div>
);
}
onItemDragOver = (event) => {
this.dragOverCnt++;
this.dragClue.show(event.pageY + 10, event.pageX, event.item.text, this.getClueClassName(event));
};
onItemDragEnd = (event) => {
this.isDragDrop = this.dragOverCnt > 0;
this.dragOverCnt = 0;
this.dragClue.hide();
const eventAnalyzer = new TreeViewDragAnalyzer(event).init();
if (eventAnalyzer.isDropAllowed) {
const { sourceData, targetData } = moveTreeViewItem(
event.itemHierarchicalIndex,
this.resolveData(event.target.guid),
eventAnalyzer.getDropOperation(),
eventAnalyzer.destinationMeta.itemHierarchicalIndex,
this.resolveData(eventAnalyzer.destinationMeta.treeViewGuid)
);
this.setState({
[this.resolveDataKey(event.target.guid)]: sourceData,
[this.resolveDataKey(eventAnalyzer.destinationMeta.treeViewGuid)]: targetData
});
}
};
onItemClick = (event) => {
if (!this.isDragDrop) {
event.item.selected = !event.item.selected;
this.forceUpdate();
}
};
onExpandChange = (event) => {
event.item.expanded = !event.item.expanded;
this.forceUpdate();
};
getClueClassName(event) {
const eventAnalyzer = new TreeViewDragAnalyzer(event).init();
const { itemHierarchicalIndex: itemIndex, treeViewGuid } = eventAnalyzer.destinationMeta;
if (eventAnalyzer.isDropAllowed) {
switch (eventAnalyzer.getDropOperation()) {
case 'child':
return 'k-i-plus';
case 'before':
return itemIndex === '0' || itemIndex.endsWith(`${SEPARATOR}0`)
? 'k-i-insert-up'
: 'k-i-insert-middle';
case 'after':
const siblings = getSiblings(itemIndex, this.resolveData(treeViewGuid));
const lastIndex = Number(itemIndex.split(SEPARATOR).pop());
return lastIndex < siblings.length - 1 ? 'k-i-insert-middle' : 'k-i-insert-down';
default:
break;
}
}
return 'k-i-cancel';
}
resolveData(treeViewGuid) {
return treeViewGuid === this.treeView1Guid ? this.state.tree : this.state.tree2;
}
resolveDataKey(treeViewGuid) {
return treeViewGuid === this.treeView1Guid ? 'tree' : 'tree2';
}
}
function getSiblings(itemIndex, data) {
let result = data;
const indices = itemIndex.split(SEPARATOR).map((index) => Number(index));
for (let i = 0; i < indices.length - 1; i++) {
result = result[indices[i]].items;
}
return result;
}
const SEPARATOR = '_';
const tree = [
{
text: 'Furniture',
expanded: true,
items: [{ text: 'Tables & Chairs' }, { text: 'Sofas' }, { text: 'Occasional Furniture' }]
},
{
text: 'Decor',
expanded: true,
items: [{ text: 'Bed Linen' }, { text: 'Curtains & Blinds' }, { text: 'Carpets' }]
}
];
const tree2 = [
{
text: 'Storage',
expanded: true,
items: [{ text: 'Wall Shelving' }, { text: 'Floor Shelving' }, { text: 'Kids Storage' }]
},
{
text: 'Lights',
expanded: true,
items: [{ text: 'Ceiling' }, { text: 'Table' }, { text: 'Floor' }]
}
];
ReactDOM.render(<App />, document.querySelector('my-app'));
Suggested Links
moveTreeViewItem
TreeViewDragAnalyzer
TreeViewDragClue
TreeViewDragClueProps
onItemDragOver
onItemDragEnd
processTreeViewItems
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4