moveTreeViewItem
A helper function which moves a TreeView item in an immutable way.
class App extends React.Component {
dragClue;
state = { tree };
render() {
return (
<div>
<TreeView data={this.state.tree} draggable={true}
onItemDragOver={this.onItemDragOver} onItemDragEnd={this.onItemDragEnd} />
<TreeViewDragClue ref={dragClue => this.dragClue = dragClue} />
</div>
);
}
onItemDragOver = (event) => {
this.dragClue.show(event.pageY + 10, event.pageX, event.item.text, this.getClueClassName(event));
}
onItemDragEnd = (event) => {
this.dragClue.hide();
const eventAnalyzer = new TreeViewDragAnalyzer(event).init();
if (eventAnalyzer.isDropAllowed) {
const updatedTree = moveTreeViewItem(
event.itemHierarchicalIndex,
this.state.tree,
eventAnalyzer.getDropOperation(),
eventAnalyzer.destinationMeta.itemHierarchicalIndex,
);
this.setState({ tree: updatedTree });
}
}
getClueClassName(event) {
const eventAnalyzer = new TreeViewDragAnalyzer(event).init();
const itemIndex = eventAnalyzer.destinationMeta.itemHierarchicalIndex;
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.state.tree);
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';
}
}
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', expanded: true },
{ text: 'Sofas', expanded: true },
{ text: 'Occasional Furniture', expanded: true }]
}, {
text: 'Decor', expanded: true, items: [
{ text: 'Bed Linen', expanded: true },
{ text: 'Curtains & Blinds', expanded: true },
{ text: 'Carpets', expanded: true }]
}];
ReactDOM.render(<App />, document.querySelector('my-app'));
Parameters
sourceItemHierarchicalIndex
string
The hierarchical index of the item that will be moved.
sourceData
any[] | null | undefined
The tree which contains the item that will be moved.
operation
"before" | "after" | "child"
The specific move operation.
The available options are:
before
—Indicates that the source item will become the previous sibling of the target item.after
—Indicates that the source item will become the next sibling of the target item.child
—Indicates that the source item will become a child of the target item.
targetItemHierarchicalIndex
string
The hierarchical index of the item next to which the source item will be moved.
targetData?
any[] | null
The tree which contains the target item.
If the argument is skipped, then the move operation will be executed within the same tree.
Setting the sourceData
and targetData
arguments to the same tree is also supported.
Returns
any[] | { sourceData: any[]; targetData: any[]; }
- The updated copies of the
sourceData
andtargetData
input arguments. IftargetData
is not passed, then only the updated copy of thesourceData
will be returned.