How to prevent dragging(moving) element outside droppable div? (Vanila JS only) - javascript

function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
if (ev.target.id === "div1") {
console.log("Running Stop Drop");
document.getElementById("img1").setAttribute("draggable", false);
}
}
// shuffle
function shuffle() {
var container = document.getElementById("images");
var elementsArray = Array.prototype.slice.call(container.getElementsByClassName('grid-item'));
elementsArray.forEach(function (element) {
container.removeChild(element);
})
shuffleArray(elementsArray);
elementsArray.forEach(function (element) {
container.appendChild(element);
})
}
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
body {
background:#6b6b69;
color:white;
}
.info {
position:relative;
font-family:Arial;
margin:10px;
text-align:center;
border-radius:5px;
font-size:15px;
}
#title {
font-size:20px;
}
#rest2 {
font-size:13px;
}
#text div {
position:relative;
height: 200px;
width: 200px;
border: 1px dashed gray;
display: inline-block;
margin: 0;
}
#text {
display: grid;
grid-template-columns: auto auto;
width: 0%;
}
#images { display: grid;
grid-template-columns: auto auto;
width: 0%
}
img {
border: #6b6b69 2px solid;
height: 200px;
width: 200px;
}
#drag4,
#drag5,
#drag6,
#drag7,
#drag8,
#drag9,
#drag10,
#drag11,
#drag12 {
height: 200px;
width: 200px;
display: inline-block;
}
#drag4 {
background: linear-gradient(to bottom right, orange, orange, yellow);
}
#drag5 {
background: linear-gradient(to right, red, orange);
}
#drag6 {
background: linear-gradient(red, orange);
}
#drag7 {
background: linear-gradient(to bottom right, red, red, orange);
}
#drag8 {
background:yellow;
}
#drag9 {
background: linear-gradient(orange, yellow);
}
#drag10 {
background: linear-gradient(to right, orange, yellow);
}
#drag11 {
background: linear-gradient(red, orange);
}
#drag12 {
background: linear-gradient(to right, red,orange);
}
.puzzle{display: inline-block;}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body>
<div class="info">
<div id="title">PUZZLE</div>
<div id="rest">Drag and drop the colored pieces on the puzzle below. (better images are on their way) </div>
<div id="rest2">You can put multiple pieces in the same area but you can't interchange them, only the last one you
put will be accessible.</div>
</div>
<div class="puzzle">
<div style="float:left;" id="images">
<img class="grid-item" id="img1" src="img/puzz1.jpg" alt="" draggable="true" ondragstart="drag(event)">
<img class="grid-item" id="img2" src="img/puzz2.jpg" alt="" draggable="true" ondragstart="drag(event)">
<img class="grid-item" id="img3" src="img/puzz3.jpg" alt="" draggable="true" ondragstart="drag(event)">
<img class="grid-item" id="img4" src="img/puzz4.jpg" alt="" draggable="true" ondragstart="drag(event)">
</div>
<div style="float: right" id="text">
<div class="grid-item2" id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="grid-item2" id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="grid-item2" id="div3" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="grid-item2" id="div4" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
</div>
</div><br><br>
<button onclick="shuffle()">
START
</button>
<div class="info">
<p>Congratulations if you finished!<p>
</div>
<script src="dragdrop3.js"></script>
</body>
</html>
I am building kind of a puzzle game with a drag and drop elements, I have 4 draggable images on the left and 4 empty divs on the right, similar drag and drop event to this w3Shchool example I posted here.
My question is how to prevent image to leave div2 on the right once it is dropped inside? I want it to be permanent, not draggable just locked once is dropped.
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
<!DOCTYPE HTML>
<html>
<head>
<style>
#div1, #div2 {
float: left;
width: 100px;
height: 35px;
margin: 10px;
padding: 10px;
border: 1px solid black;
}
</style>
</head>
<body>
<h2>Drag and Drop</h2>
<p>Drag the image back and forth between the two div elements.</p>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="img_w3slogo.gif" draggable="true" ondragstart="drag(event)" id="drag1" width="88" height="31">
</div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
</body>
</html>

Here is a very crude way of doing it (IMO), but it works.
Explanation: ondrop complete I make the img element un-dropable.
document.getElementById("drag1").setAttribute("draggable", false);
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
if(ev.target.id === "div2"){
console.log("Running Stop Drop");
document.getElementById("drag1").setAttribute("draggable", false);
}
}
<!DOCTYPE HTML>
<html>
<head>
<style>
#div1, #div2 {
float: left;
width: 100px;
height: 35px;
margin: 10px;
padding: 10px;
border: 1px solid black;
}
</style>
</head>
<body>
<h2>Drag and Drop</h2>
<p>Drag the image back and forth between the two div elements.</p>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="img_w3slogo.gif" draggable="true" ondragstart="drag(event)" id="drag1" width="88" height="31">
</div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
</body>
</html>

Related

How to drop a div between two divs using plain JavaScript (no JQuery)

I use the below code to drag items (left) to the drop items (right). Once dragged to the right, they can be dragged back to the left.
I'm using
document.getElementById(dropID).appendChild(document.getElementById(dragID))
to drag them back, so they always are added as the last div.
Is there any way to drag the item to the left, positioned between other divs that are already in the left? instead of always added to the end?
Also this would allow to sort the items in the left by just dragging them between them, is this easy without using jquery? thanks!
<!DOCTYPE HTML>
<html>
<head>
<style>
.dragAndDropContainer {
display: flex ;
justify-content: space-around;
font-family: Helvetica,Arial,Lucida,sans-serif ;
}
.dragItems {
display: flex ;
flex-direction: column;
justify-content: space-evenly;
text-align: center;
flex-grow: 1;
border: 1px solid black;
}
.dragItem {
margin: 10px;
padding: 10px;
border: 1px solid white;
background-color: rgb(52,118,177);
color: white;
font-weight: bold;
}
.dragItem:hover {
background: rgb(117, 168, 255);
}
.dropItems {
display: flex ;
flex-direction: column;
justify-content: space-evenly;
text-align: center;
flex-grow: 1;
}
.dropItem {
margin: 10px;
padding: 10px;
border: 3px solid rgb(160, 160, 160);
background-color: rgb(190, 190, 190);
color: black;
font-weight: bold;
}
.dropItem:hover {
color: white;
background: rgb(73, 86, 92);
}
</style>
<script>
// source based on: https://www.w3schools.com/html/html5_draganddrop.asp
function allowDrop(ev) {
var dropID = ev.currentTarget.id;
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("dragEventID", ev.currentTarget.id);
}
function drop(ev) {
ev.preventDefault();
var dragID = ev.dataTransfer.getData("dragEventID");
var dropID = ev.currentTarget.id;
var dropClass = ev.currentTarget.getAttribute("class");
var maximumDragItemsPerDropArea = 1 ;
if (dropClass=="dragItems") {
document.getElementById(dropID).appendChild(document.getElementById(dragID));
}
else if (dropClass = "dropItems") {
if (document.getElementById(dropID).childElementCount < maximumDragItemsPerDropArea) {
document.getElementById(dropID).appendChild(document.getElementById(dragID));
} else {
console.log("maximum "+ maximumDragItemsPerDropArea) ;
console.log(document.getElementById(dropID).children) ;
// alert("max");
}
}
}
</script>
</head>
<body>
<div id="dragAndDropContainer" class="dragAndDropContainer">
<div id="dragItems" class="dragItems" ondrop="drop(event)" draggable="false" ondragover="allowDrop(event)">
<div id="dmDragItemID1" class="dragItem" draggable="true" ondragstart="drag(event)" > Drag item 1 </div>
<div id="dmDragItemID2" class="dragItem" draggable="true" ondragstart="drag(event)" > Drag item 2 </div>
<div id="dmDragItemID3" class="dragItem" draggable="true" ondragstart="drag(event)" > Drag item 3 </div>
</div>
<div id="dropItems" class="dropItems">
<div id="dmDropItemID1" class="dropItem" ondrop="drop(event)" draggable="false" ondragover="allowDrop(event)">Drop item 1</div>
<div id="dmDropItemID2" class="dropItem" ondrop="drop(event)" draggable="false" ondragover="allowDrop(event)">Drop item 2</div>
<div id="dmDropItemID3" class="dropItem" ondrop="drop(event)" draggable="false" ondragover="allowDrop(event)">Drop item 3</div>
<div id="dmDropItemID4" class="dropItem" ondrop="drop(event)" draggable="false" ondragover="allowDrop(event)">Drop item 4</div>
</div>
</div>
</body>
</html>
You can use the ChildNode.before() method to insert your element right before any other target:
https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/before
Also, this assignment you have in the condition check looks like it's a mistake:
else if (dropClass = "dropItems") {
OK I got it working, thanks to this link:
https://codepen.io/fitri/pen/VbrZQm
This is the code:
<html>
<head>
<style>
.dragAndDropContainer {
display: flex ;
justify-content: space-around;
font-family: Helvetica,Arial,Lucida,sans-serif ;
font-size: 11px;
}
.dragItems {
display: flex ;
flex-direction: column;
text-align: center;
flex-grow: 1;
border: 1px solid rgb(160, 160, 160);
}
.dragItem {
margin: 0px;
padding: 5px;
border: 1px solid white;
background-color: rgb(52,118,177);
color: white;
}
.dragItem:hover {
background: rgb(117, 168, 255);
}
.dropItems {
display: flex ;
flex-direction: column;
justify-content: space-evenly;
text-align: center;
flex-grow: 1;
}
.dropItem {
margin: 0px;
padding: 5px;
border: 1px solid white;
background-color: rgb(190, 190, 190);
color: black;
font-weight: bold;
}
.dropItem:hover {
color: white;
background: rgb(73, 86, 92);
}
</style>
<script>
/*
Resources:
https://www.w3schools.com/html/html5_draganddrop.asp
https://codepen.io/fitri/pen/VbrZQm
*/
function allowDrop(ev) {
var dropID = ev.currentTarget.id;
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("dragEventID", ev.currentTarget.id);
}
function drop(ev) {
ev.preventDefault();
var dragID = ev.dataTransfer.getData("dragEventID");
var dropID = ev.currentTarget.id;
var dropClass = ev.currentTarget.getAttribute("class");
var maximumDragItemsPerDropArea = 1 ;
if (dropClass == "dragItems") {
elementDropPoint = document.elementFromPoint(event.clientX, event.clientY);
// If drop area is the drag items container div, we add the dragged div to the end
if (elementDropPoint.className == "dragItems") {
document.getElementById(dropID).appendChild(document.getElementById(dragID));
}
// If drop area is between two drag item divs, we add the dragged div in the drop area, after the existing drag div
if (elementDropPoint.className == "dragItem") {
elementDropPoint.after(document.getElementById(dragID));
}
}
if (dropClass == "dropItem") {
if (document.getElementById(dropID).childElementCount < maximumDragItemsPerDropArea) {
document.getElementById(dropID).appendChild(document.getElementById(dragID));
} else {
console.log("maximum "+ maximumDragItemsPerDropArea) ;
console.log(document.getElementById(dropID).children) ;
// alert("max");
}
}
}
</script>
</head>
<body>
<div id="dragAndDropContainer" class="dragAndDropContainer">
<div id="dragItems" class="dragItems" ondrop="drop(event)" draggable="false" ondragover="allowDrop(event)">
<div id="dmDragItemID1" class="dragItem" draggable="true" ondragstart="drag(event)" > FileNotes021.png </div>
<div id="dmDragItemID2" class="dragItem" draggable="true" ondragstart="drag(event)" > FileNotes025.png </div>
<div id="dmDragItemID3" class="dragItem" draggable="true" ondragstart="drag(event)" > FileNotes019.png </div>
<div id="dmDragItemID4" class="dragItem" draggable="true" ondragstart="drag(event)" > FileNotes015.png </div>
</div>
<div id="dropItems" class="dropItems">
<div id="dmDropItemID1" class="dropItem" ondrop="drop(event)" draggable="false" ondragover="allowDrop(event)">Song 1</div>
<div id="dmDropItemID2" class="dropItem" ondrop="drop(event)" draggable="false" ondragover="allowDrop(event)">Song 2</div>
<div id="dmDropItemID3" class="dropItem" ondrop="drop(event)" draggable="false" ondragover="allowDrop(event)">Song 3</div>
<div id="dmDropItemID4" class="dropItem" ondrop="drop(event)" draggable="false" ondragover="allowDrop(event)">Song 4</div>
<div id="dmDropItemID5" class="dropItem" ondrop="drop(event)" draggable="false" ondragover="allowDrop(event)">Song 5</div>
<div id="dmDropItemID6" class="dropItem" ondrop="drop(event)" draggable="false" ondragover="allowDrop(event)">Song 6</div>
</div>
</div>
</body>
</html>

Unable to load saved position of dropped item from local storage using javascript

I am new to programming; this is my very first question on Stake-overflow.
I want to save the position of the dropped div in local storage and retrieve this position when I refresh the page.
Here is what I have achieved so far using Javascript:
1) I can store the position of dropped div in local storage (by calling a function on enddrop event.)
2) I can retrieve the stored position (by calling a function on onload event)
What I want:
1) I want to position the dropped div according to retrieved position (position left and top from local storage.)
Here is my code:
HTML
<!DOCTYPE HTML>
<html>
<head>
</head>
<body onload="get_pos(event)">
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div style="margin-left:50px;" id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div style="margin-left:100px;" id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div draggable="true" ondragstart="drag(event)" ondragend="set_pos(event);get_pos(event);" id="drag1">
pTop: <span id="pt"></span> <br>
pLeft: <span id="pl"></span>
<span style="margin-left:80px;">Drag Me!</span>
</div>
</body>
</html>
CSS
#div1 {
width: 300px;
height: 70px;
padding: 10px;
margin: 20px;
border: 1px solid #aaaaaa;
}
#drag1 {
width: 250px;
height: 60px;
padding: 5px;
background: lightgray;
border: 1px solid #aaaaaa;
}
Javascript:
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
function set_pos(e) {
var div = document.getElementById("drag1");
var rect = div.getBoundingClientRect();
x = rect.left;
y = rect.top;
// Store
localStorage.setItem("pTop", y);
localStorage.setItem("pLeft", x);
}
function get_pos(e) {
var a = localStorage.getItem("pTop");
var b = localStorage.getItem("pLeft");
document.getElementById("drag1").style.top = a+"px";
document.getElementById("drag1").style.left = b+"px";
document.getElementById("pt").innerHTML = a+"px";
document.getElementById("pl").innerHTML = b+"px";
}
Any help would be appreciated!
I have made it dynamic, you can now drag divs, images, I took care about the order of the dragged elements. now you can modifie it to store in your server instead of the client. happy coding :)
<!DOCTYPE HTML>
<html lang="en-us">
<head>
<title>Retrieve drag position</title>
<meta charset="utf-8">
<style>
* {
box-sizing: border-box;
}
.drop_box {
width: 100px;
height: 120px;
margin: 10px;
padding: 5px;
border: 1px solid black;
}
img, .dragged_box {
width: 90px;
height: 30px;
}
.red {
background-color: red;
}
.blue {
background-color: blue;
}
.green {
background-color: green;
}
</style>
</head>
<body onload="retrieve()">
<div class="dragged_box red" draggable="true" ondragstart="drag(event)" id="drag_div1"></div>
<div class="dragged_box blue" draggable="true" ondragstart="drag(event)" id="drag_div2"></div>
<div class="dragged_box green" draggable="true" ondragstart="drag(event)" id="drag_div3"></div>
<img src="https://img.icons8.com/color/48/000000/bungalow.png" draggable="true" ondragstart="drag(event)" id="drag_img1">
<img src="https://img.icons8.com/ios-filled/50/000000/bungalow.png" draggable="true" ondragstart="drag(event)" id="drag_img2">
<img src="https://img.icons8.com/ios/50/000000/bungalow.png" draggable="true" ondragstart="drag(event)" id="drag_img3">
<div class="drop_box" id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="drop_box" id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="drop_box" id="div3" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="drop_box" id="div4" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<script>
var draggedImages = {
draggedIds: [],
droppedIds: []
}
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var id = ev.dataTransfer.getData("text");
if(draggedImages.draggedIds.indexOf(id) === -1) {
draggedImages.draggedIds.push(id);
draggedImages.droppedIds.push(ev.target.id);
}else {
var ind = draggedImages.draggedIds.indexOf(id);
// to keep the order of images
draggedImages.draggedIds.splice(ind, 1);
draggedImages.droppedIds.splice(ind, 1);
draggedImages.draggedIds.push(id);
draggedImages.droppedIds.push(ev.target.id);
}
localStorage["draggedImages"] = JSON.stringify(draggedImages);
ev.target.appendChild(document.getElementById(id));
}
function retrieve() {
if(localStorage["draggedImages"]) {
draggedImages = JSON.parse(localStorage["draggedImages"]);
draggedImages.draggedIds.forEach(function(draggedId, ind) {
document.getElementById(draggedImages.droppedIds[ind]).appendChild(document.getElementById(draggedId));
});
}
}
</script>
</body>
</html>

Breaks span in drag & drop

Tell me please. If you drag a span specifically to another span and not to a free space, some kind of merging occurs (see gif).
How to fix this error?
Thank you in advance.
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
#div1,
#div2 {
float: left;
width: 100%;
height: 100%;
margin: 10px;
padding: 10px;
display: inline-block;
}
.drop {
width:100px;
height:50px;
display:block;
border:1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div style="background:#fafafa;width:100%;height:440px;padding-top:10px;">
<div style="text-align:center;width:49%;height: 100%;display:inline-block;border-right:1px solid #e0e0e0;">
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<span class="drop" draggable="true" ondragstart="drag(event)" id="drag1" data-orderID="1">SPAN 1</span>
</div>
</div>
<div style="text-align:center;width:49%;height: 100%;display:inline-block;">
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)">
<span class="drop" draggable="true" ondragstart="drag(event)" id="drag2" data-orderID="2">SPAN 2</span>
</div>
</div>
</div>
If you don't want the drop inside the span, you can prevent the drop from that node. <span class="drop" ondrop="event.stopPropagation();" That makes sure your handler on the containing div doesn't get called.
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
#div1,
#div2 {
float: left;
width: 100%;
height: 100%;
margin: 10px;
padding: 10px;
display: inline-block;
}
.drop {
width:100px;
height:50px;
display:block;
border:1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div style="background:#fafafa;width:100%;height:440px;padding-top:10px;">
<div style="text-align:center;width:49%;height: 100%;display:inline-block;border-right:1px solid #e0e0e0;">
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<span class="drop" draggable="true" ondragstart="drag(event)" id="drag1" data-orderID="1">SPAN 1</span>
</div>
</div>
<div style="text-align:center;width:49%;height: 100%;display:inline-block;">
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)">
<span class="drop" ondrop="event.stopPropagation();" draggable="true" ondragstart="drag(event)" id="drag2" data-orderID="2">SPAN 2</span>
</div>
</div>
</div>
Your drop event is triggered on the span not on the containing div.
So the dragged element is appended to the span it's dragged onto.
You can prevent this by altering the line
ev.target.appendChild(document.getElementById(data));
to
ev.target.closest('div').appendChild(document.getElementById(data));

Drag a div or image into textarea and put a value inside it

I'd like to put a value inside textarea by allowing user to drag a div or image into it.
Here is roughly what my html looks like.
img {
width: 100px;
}
.emote {
position:relative;
background-color:rgba(45,45,45, 0.3);
margin: 20px 0px;
}
.emote .emoteTitle {
position:absolute;
top:50%;
margin-left: 50px;
}
<div class="emote">
<img src="https://images.duckduckgo.com/iu/?u=http%3A%2F%2Ficons.iconarchive.com%2Ficons%2Fpaomedia%2Fsmall-n-flat%2F512%2Fcat-icon.png&f=1" alt="emote1" title="emote1" class="emoteImage">
<span class="emoteTitle">emote1</span>
</div>
<div class="emote">
<img src="https://images.duckduckgo.com/iu/?u=http%3A%2F%2Fes.seaicons.com%2Fwp-content%2Fuploads%2F2015%2F06%2Fsign-check-icon.png&f=1" alt="emote2" title="emote2" class="emoteImage">
<span class="emoteTitle">emote2</span>
</div>
<textarea></textarea>
Fiddle link
So when user drags a div.emote or the image onto text area i want it to put either emote1 or emote2 into it.
What would be the best way to make this work?
Here is a snippet that builds on yours.
When you drop the image on the textarea, its alt text will be added at the cursor position.
You can easily change this to put any value you want, just replace the second argument on .setData('text', emoteImage.alt)
For reference:
https://developer.mozilla.org/en-US/docs/Web/Events/dragstart
https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer
document.querySelectorAll('.emoteImage').forEach((emoteImage) => {
emoteImage.addEventListener('dragstart', (event) => {
event.dataTransfer.setData('text', emoteImage.alt);
event.effectAllowed = "copy";
});
});
img {
width: 100px;
}
.emote {
position:relative;
background-color:rgba(45,45,45, 0.3);
margin: 20px 0px;
}
.emote .emoteTitle {
position:absolute;
top:50%;
margin-left: 50px;
}
<div class="emote">
<img src="https://images.duckduckgo.com/iu/?u=http%3A%2F%2Ficons.iconarchive.com%2Ficons%2Fpaomedia%2Fsmall-n-flat%2F512%2Fcat-icon.png&f=1" alt="emote1" title="emote1" class="emoteImage">
<span class="emoteTitle">emote1</span>
</div>
<div class="emote">
<img src="https://images.duckduckgo.com/iu/?u=http%3A%2F%2Fes.seaicons.com%2Fwp-content%2Fuploads%2F2015%2F06%2Fsign-check-icon.png&f=1" alt="emote2" title="emote2" class="emoteImage">
<span class="emoteTitle">emote2</span>
</div>
<textarea></textarea>
I modified last example from: https://www.w3schools.com/html/html5_draganddrop.asp
This is just a quick template, but I hope you'll know how to modify it further
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.innerHTML = document.getElementById(data).dataset.value;
}
#div1, #div2 {
float: left;
width: 100px;
height: 35px;
margin: 10px;
padding: 10px;
border: 1px solid black;
}
<h2>Drag and Drop</h2>
<p>Drag the image back and forth between the two div elements.</p>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="img_w3slogo.gif" draggable="true" ondragstart="drag(event)" data-value="img1" id="drag1" width="88" height="31">
</div>
<textarea id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></textarea>
Based on answer from NoOorZ24 here is the final draft.
JsFiddle link: JsFiddle
HTML
<div id="div1" class="emote">
<img src="https://images.duckduckgo.com/iu/?u=http%3A%2F%2Ficons.iconarchive.com%2Ficons%2Fpaomedia%2Fsmall-n-flat%2F512%2Fcat-icon.png&f=1" draggable="true" ondragstart="drag(event)" alt="emote1" title="emote2" class="emoteImage" data-value="img1" id="drag1"
width="88" height="31">
<span class="emoteTitle">emote1</span>
</div>
<div id="div2" class="emote">
<img src="https://images.duckduckgo.com/iu/?u=http%3A%2F%2Fes.seaicons.com%2Fwp-content%2Fuploads%2F2015%2F06%2Fsign-check-icon.png&f=1" draggable="true" ondragstart="drag(event)" alt="emote2" title="emote2" class="emoteImage" data-value="img2" id="drag2"
width="88" height="31">
<span class="emoteTitle">emote2</span>
</div>
<textarea id="div3" ondrop="drop(event)" ondragover="allowDrop(event)"></textarea>
Script
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.innerHTML = document.getElementById(data).dataset.value;
}

drag-drop to multiple elemnts issue

I'm trying to implement a drag-drop scenario.
A problem that I'm having is that I need to drop an element on an outer div but the event fires on the inner div.
Here is a codepen to demonstrate my problem:
http://codepen.io/anon/pen/KdvboR
<html>
<head>
<style>
.dropDiv {
height: 100px;
width: 200px;
border: 1px solid black;
}
.innerDiv {
height: 100px;
width: 100px;
border-right: 1px solid black;
}
.drag {
border: 1px solid green;
}
.drop {
border: 1px solid red;
}
</style>
</head>
<body>
<span id="text" draggable="true" ondragstart="drag(event)" ondragend="dragend(event)" class="">Drag Text</span>
<br>
<br>
To Here:
<div class="dropDiv" ondrop="drop(event)" ondragenter="dragenter(event)" ondragleave="dragleave(event)" ondragover="allowDrop(event)">
<div class="innerDiv"></div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script>
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
$(ev.target).addClass('drag');
ev.dataTransfer.setData('text', ev.target.id);
}
function dragenter(ev) {
$(ev.target).addClass('drop');
}
function dragleave(ev) {
$(ev.target).removeClass('drop');
}
function dragend(ev) {
$(ev.target).removeClass('drag');
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData('text');
ev.target.appendChild(document.getElementById(data));
$(ev.target).removeClass('drop');
}
</script>
</body>
</html>
I need that whenever the dragged element is in the outer div the border will be red. but when the mouse is over the inner div, only the inner div's border is red.
Any suggestions?
Thanks.
Go through this example
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery UI Droppable - Default functionality</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">
<style>
#draggable { width: 100px; height: 100px; padding: 0.5em; float: left; margin: 10px 10px 10px 0; }
#droppable { width: 150px; height: 150px; padding: 0.5em; float: left; margin: 10px; }
</style>
<script>
$(function() {
$( "#draggable" ).draggable();
$( "#droppable" ).droppable({
drop: function( event, ui ) {
$( this )
.addClass( "ui-state-highlight" )
.find( "p" )
.html( "Dropped!" );
}
});
});
</script>
</head>
<body>
<div id="draggable" class="ui-widget-content">
<p>Drag me to my target</p>
</div>
<div id="droppable" class="ui-widget-header">
<p>Drop here</p>
</div>
</body>
</html>
You are only one div on your container. remove container and try
<div class="innerDiv" ondrop="drop(event)" ondragenter="dragenter(event)" ondragleave="dragleave(event)" ondragover="allowDrop(event)"></div>
<div class="innerDiv" ondrop="drop(event)" ondragenter="dragenter(event)" ondragleave="dragleave(event)" ondragover="allowDrop(event)"></div>
.innerDiv {
height: 100px;
width: 100px;
border: 1px solid;
float:left;
}
Thanks everybody,
eventually, I solved it by checking if the event coords are in the outer div.

Categories

Resources