Created
June 7, 2018 08:48
-
-
Save CriptoCosmo/4cf701d8fef63511ce9cb9dc78febdb8 to your computer and use it in GitHub Desktop.
Drag and Drop list by riot.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html lang="ja"> | |
<head> | |
<meta charset="utf-8"> | |
<title>Drag and Drop on a list</title> | |
<style> | |
body,html { height: 100%; padding: 0; margin: 0; } | |
ul { | |
width: 100%; | |
height: 100%; | |
background: #ccc; | |
margin: 0; | |
} | |
li { | |
width: 200px; | |
padding: 3px 5px; | |
margin: 3px; | |
background: #cf4; | |
display: block; | |
-moz-user-select: none; | |
-khtml-user-select: none; | |
-webkit-user-select: none; | |
user-select: none; | |
/* Required to make elements draggable in old WebKit */ | |
-khtml-user-drag: element; | |
-webkit-user-drag: element; | |
} | |
.placeholder { | |
box-sizing: border-box; | |
background: #999; | |
} | |
</style> | |
</head> | |
<body> | |
<dnd-list></dnd-list> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/riot/2.6.4/riot+compiler.min.js"></script> | |
<script type="riot/tag"> | |
<dnd-list> | |
<ul class="seq" ondragover="{ ondragover }" ondrop="{ ondrop }"> | |
<li each="{ v in node.children }" class="seq-item" draggable="true" data-pzl-id="{ v.id }" ondragstart="{ ondragstart }" ondragend="{ ondragend }">{ v.label }</li> | |
</ul> | |
this.node = opts.node; | |
this.nodeId = null; // the ID of the currently dragged node. | |
this.on('mount', function() { | |
var placeholder = document.createElement('li'); | |
placeholder.className = 'placeholder seq-item'; | |
this.placeholder = placeholder; | |
}); | |
ondragstart(event) { | |
console.log("ondragstart"); | |
event.dataTransfer.setData('text', ''); // Allow dragging on Firefox. | |
this.nodeId = event.item.v.id; | |
this.dragged = event.target; | |
this.placeholder.style.height = this.dragged.getBoundingClientRect().height + "px"; | |
this.placeholder.style.width = this.dragged.getBoundingClientRect().width + "px"; | |
return true; | |
}; | |
ondragover(event) { | |
console.log("ondragover", event.clientX, event.clientY, event.target.dataset.pzlId); | |
event.dataTransfer.dropEffect = 'move'; | |
if (this.dragged.style.display != 'none') { | |
this.dragged.style.display = 'none'; | |
this.dragged.parentNode.insertBefore(this.placeholder, this.dragged); | |
} | |
var overElm = event.target; | |
if (overElm.classList.contains('seq-item')) { | |
var relY = event.clientY - overElm.offsetTop; | |
var middle = overElm.offsetHeight / 2; | |
var parent = overElm.parentNode; | |
if (relY < middle) { | |
parent.insertBefore(this.placeholder, overElm); // Insert the placeholder upside of `overElm' | |
} else { | |
parent.insertBefore(this.placeholder, overElm.nextElementSibling); // Insert the placeholder downside of `overElm' | |
} | |
} | |
// `this.dragged' is dragged over seq. | |
else if (overElm.classList.contains('seq')) { | |
const items = overElm.getElementsByClassName('seq-item'); | |
if (items.length == 0 || (items.length == 1 && pages[0] == this.dragged)) { | |
overElm.appendChild(this.placeholder); | |
} | |
} | |
return false; | |
}; | |
ondragend(event) { | |
console.log("ondropend"); | |
this.dragged.style.display = 'block'; | |
if (this.placeholder.parentNode) this.placeholder.parentNode.removeChild(this.placeholder); | |
return true; | |
}; | |
ondrop(event) { | |
console.log("ondrop"); | |
var i = Array.from(this.placeholder.parentNode.children) | |
.filter((child) => child != this.dragged && child.classList.contains('seq-item')) | |
.indexOf(this.placeholder); | |
if (i >= 0) { | |
this.moveNode(this.node, this.nodeId, i); | |
this.update(); | |
} | |
return false; | |
}; | |
removeNode(tree, nodeId) { | |
var i = tree.children.findIndex((node) => node.id == nodeId); | |
var node = tree.children[i]; // Backup the macthed node. | |
if (i >= 0) tree.children.splice(i, 1); // Remove the matched node. | |
return node; | |
} | |
moveNode(tree, nodeId, i) { | |
var node = this.removeNode(tree, nodeId); | |
tree.children.splice(i, 0, node); | |
} | |
</dnd-list> | |
</script> | |
<script> | |
riot.mount('dnd-list', | |
{ | |
node: { | |
type: "seq", | |
children: [ | |
{ id: 1, label: 'Element 01' }, | |
{ id: 2, label: 'Element 02' }, | |
{ id: 3, label: 'Element 03' } | |
] | |
} | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment