Skip to content

Instantly share code, notes, and snippets.

@CriptoCosmo
Created June 7, 2018 08:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CriptoCosmo/4cf701d8fef63511ce9cb9dc78febdb8 to your computer and use it in GitHub Desktop.
Save CriptoCosmo/4cf701d8fef63511ce9cb9dc78febdb8 to your computer and use it in GitHub Desktop.
Drag and Drop list by riot.js
<!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