Author: | lukasolson |
---|---|
Views Total: | 7,848 views |
Official Page: | Go to website |
Last Update: | October 31, 2016 |
License: | MIT |
Preview:

Description:
A very simple pure JavaScript solution to move items between containers/boxes by drag’n’ drop.
How to use it:
Create a container for draggable items.
<div id="available_metrics_filter"> <ul id="available_metrics_list"> </ul> </div>
Create a container for droppable area.
<div id="selected_metrics"> <ul id="selected_metrics_list"> <li id="next_metric">Next Draggable</li> </ul> </div>
The Javascript to add items into the draggable container and enable the drag’n’drop functionality.
var droppables = new Array(); var itemBeingDragged = null; var mouseDownPoint = {x: 0, y: 0}; function onDocumentMouseMove(mouseMoveEvent) { var point = {x: mouseMoveEvent.pageX, y: mouseMoveEvent.pageY}; // Drag the draggable to this position itemBeingDragged.dragTo(point); // If there are any droppable elements at this position, notify them for (var i = 0; i < droppables.length; i++) { if (droppables[i].contains(point) && !droppables[i].isBeingDraggedOver) { droppables[i].onDragEnter(); } else if (!droppables[i].contains(point) && droppables[i].isBeingDraggedOver) { droppables[i].onDragExit(); } } } function onDocumentMouseUp(mouseUpEvent) { // If any droppable is being dragged over, accept the drop for (var i = 0; i < droppables.length; i++) { if (droppables[i].isBeingDraggedOver) { droppables[i].onDragDrop(itemBeingDragged); } } // Reset the position of the item being dragged and clear out the document event handlers itemBeingDragged.reset(mouseUpEvent); } var Draggable = function(elementId) { this.init(elementId); }; Draggable.prototype = { init: function(element) { if (typeof element === "string") element = document.getElementById(element); this.element = element; this.element.className += "draggable"; var self = this; this.element.onmousedown = function(mouseDownEvent) { this.style.zIndex = "1000"; itemBeingDragged = self; mouseDownPoint.x = mouseDownEvent.pageX; mouseDownPoint.y = mouseDownEvent.pageY; document.onmousemove = onDocumentMouseMove; document.onmouseup = onDocumentMouseUp; }; }, // Called when the mouse is moved (after having been pressed on this element) dragTo: function(point) { this.element.style.left = (point.x - mouseDownPoint.x) + "px"; this.element.style.top = (point.y - mouseDownPoint.y) + "px"; }, // Called when the mouse is lifted (after having been pressed on this element) reset: function() { this.element.style.zIndex = ""; this.element.style.left = ""; this.element.style.top = ""; itemBeingDragged = null; mouseDownPoint.x = 0; mouseDownPoint.y = 0; document.onmousemove = null; document.onmouseup = null; } }; // customDragDrop is a custom function which will be called when a Draggable is dropped // on this Droppable; it is passed the Draggable that was dropped var Droppable = function(element, customDragDrop) { this.init(element, customDragDrop); }; Droppable.prototype = { init: function(element, customDragDrop) { if (typeof element === "string") element = document.getElementById(element); this.element = element; this.isBeingDraggedOver = false; this.customDragDrop = customDragDrop; droppables.push(this); }, // Calculate the top-left coordinate of this element position: function() { var position = {x: this.element.offsetLeft, y: this.element.offsetTop}; var offsetParent = this.element.offsetParent; while (offsetParent) { position.x += offsetParent.offsetLeft; position.y += offsetParent.offsetTop; offsetParent = offsetParent.offsetParent; } return position; }, // Calculate whether the given coordinate falls within this element's boundaries contains: function(point) { var topLeft = this.position(); var bottomRight = { x: topLeft.x + this.element.offsetWidth, y: topLeft.y + this.element.offsetHeight }; return ( topLeft.x < point.x && topLeft.y < point.y && point.x < bottomRight.x && point.y < bottomRight.y ); }, // Called when an item is dragged into this element onDragEnter: function() { this.isBeingDraggedOver = true; this.element.className += "dragOver"; }, // Called when an item is dragged out of this element onDragExit: function() { this.isBeingDraggedOver = false; this.element.className = this.element.className.replace(/\bdragOver\b/, ""); }, // Called when an item is dropped on this element onDragDrop: function(draggable) { this.onDragExit(); this.customDragDrop(draggable); } }; window.onload = function() { // custom data var data = [ "These", "Words", "Can", "Be", "Dragged", "And", "Dropped", "Over", "On", "The", "Right", "Side", "Of", "The", "Screen" ]; var availableMetrics = document.getElementById("available_metrics_list"); for (var i = 0; i < data.length; i++) { var liElement = document.createElement("li"); liElement.appendChild(document.createTextNode(data[i])); availableMetrics.appendChild(liElement); var liElementDraggable = new Draggable(liElement); } var availableMetricsDroppable = new Droppable(availableMetrics, function(draggable) { if (this.element !== draggable.element.parentNode) { this.element.appendChild(draggable.element); } }); var selectedMetricsDroppable = new Droppable("next_metric", function(draggable) { if (this.element.parentNode !== draggable.element.parentNode) { this.element.parentNode.insertBefore(draggable.element, this.element); } }); new Droppable("remove_metric", function(draggable) { availableMetricsDroppable.onDragDrop(draggable); }); };
The sample CSS to style the containers.
#available_metrics_filter { margin: 5px; border: 1px solid gray; padding: 5px; background-color: rgb(230, 230, 230); } #available_metrics_list { padding: 0px; border: 1px solid gray; padding: 10px; background-color: white; } #available_metrics_list li { margin-top: -1px; border: 1px solid gray; padding: 5px; list-style-type: none; background-color: white; } #selected_metrics_list { margin: 5px; border: 1px solid gray; padding: 10px; background-color: white; } #selected_metrics_list li { margin-top: -1px; border: 1px solid gray; padding: 5px; list-style-type: none; background-color: white; } #selected_metrics_list li:last-child { border: 1px dotted gray; } #next_metric { color: gray; } #remove_metric { margin: 5px; border: 1px dotted gray; padding: 5px; color: gray; text-align: center; background-color: white; } .draggable { position: relative; cursor: default; } .dragOver { background-color: rgb(232, 232, 255) !important; }
Changelog:
10/31/2016
- Supports MS Edge