how to adjust drag and drop functionality - javascript

I have tried to make drag and drop functionality between two lists. however, when i drag one element over another element, it doesn't push the element up or down. It instead go away and disappear.
It works only if I drag the item to the bottom of the list. that's why I need to be able to handle user misuse.
and here is my attempt
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: 100px;
height: auto;
margin: 10px;
padding: 10px;
border: 1px solid black;
}
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="https://static.thenounproject.com/png/1686943-200.png" draggable="true" ondragstart="drag(event)" id="drag1" width="88" height="88">
<img src="https://static.thenounproject.com/png/1686943-200.png" draggable="true" ondragstart="drag(event)" id="drag2" width="88" height="88">
<img src="https://static.thenounproject.com/png/1686943-200.png" draggable="true" ondragstart="drag(event)" id="drag3" width="88" height="88">
<img src="https://static.thenounproject.com/png/1686943-200.png" draggable="true" ondragstart="drag(event)" id="drag4" width="88" height="88">
</div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>

Related

In HTML, how can I stop images from vanishing when dragged over another image?

I'm trying to create a visual card counter. Basically images of cards that can be moved into different divisions.
I've started with code from https://www.w3schools.com/html/html5_draganddrop.asp
It works OK, but leaves me with one problem: If one image is dragged on top of another it disappears. Looking at the code, it seems to nest within the image it is dragged onto.
I've found several pages describing similar problems but not been able to get the proposed solutions working for me.
In short, I would like the dragged image to behave as if it had been dropped next to the static image; even if it is dropped on top by mistake.
Thanks in advance!
<!DOCTYPE HTML>
<html>
<head>
<style>
#div1 {
float: left;
width: 200px;
height: 335px;
margin: 10px;
padding: 10px;
border: 1px solid black;
background-color: aqua;
}
#div2, #div3 {
float: right;
width: 200px;
height: 335px;
margin: 10px;
padding: 10px;
border: 1px solid black;
background-color: rgba(255, 0, 0, 0.548);
}
</style>
<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.appendChild(document.getElementById(data));
}
</script>
</head>
<body>
<h2>Twilight Stuggle Card Tracker</h2>
<p>Drag the image back and forth between the two div elements.</p>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<h2>USA</h2>
<img src="imgeurope-scoring.jpg" draggable="true" ondragstart="drag(event)" id="drag1" width="90" height="126">
</div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="imgduck-and-cover.jpg" draggable="true" ondragstart="drag(event)" id="drag2" width="90" height="126">
</div>
<div id="div3" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="imgduckpix.GIF" draggable="true" ondragstart="drag(event)" id="drag3" width="190" height="28">
<img src="imgfive-year-plan.jpg" draggable="true" ondragstart="drag(event)" id="drag4" width="105" height="147">
</div>
</body>
</html>
When you drop an image directly over another image element, then ev.target will be that image. So go and check what element type you have in there, and if it is an image, go up to the parent element first.
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text"), target = ev.target;
if(target.nodeName == "IMG") {
target = target.parentNode;
}
target.appendChild(document.getElementById(data));
}

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));

How to place items in specified position in drop in javascript

I have five images in my code, I want to drop these such that it is dropped in the desired position(circular position) in the dropped area.
ie,
when the five images are dropped it should form a circle shape rather than a straight line
How to achieve this?
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 {
width: 350px;
height: 150px;
padding: 10px;
border: 1px solid #aaaaaa;
}
<p>how to position the dropped images in a circular position rather than in a straight line on drop:</p>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br>
<img id="drag1" src="https://picsum.photos/200/300" draggable="true" ondragstart="drag(event)" width="50" height="50">
<img id="drag2" src="https://picsum.photos/200/300?image=0" draggable="true" ondragstart="drag(event)" width="50" height="50">
<img id="drag3" src="https://picsum.photos/200/300/?gravity=east" draggable="true" ondragstart="drag(event)" width="50" height="50">
<img id="drag4" src="https://picsum.photos/200/300/?blur" draggable="true" ondragstart="drag(event)" width="50" height="50">
<img id="drag5" src="https://picsum.photos/200/300/?random" draggable="true" ondragstart="drag(event)" width="50" height="50">
Use nth-child() to #div1 img and set position to each image with top/left
also use position:absolute to img and position:relative; to #div
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 {
width: 350px;
height: 150px;
padding: 10px;
border: 1px solid #aaaaaa;
position:relative;
}
#div1 img{
position: absolute;
}
#div1 img:nth-child(1) {
left: 155px;
}
#div1 img:nth-child(2) {
top: 35px;
left:215px;
}
#div1 img:nth-child(3) {
top: 95px;
left: 185px;
}
#div1 img:nth-child(4) {
top: 95px;
left: 120px;
}
#div1 img:nth-child(5) {
top: 35px;
left:95px;
}
<p>how to position the dropped images in a circular postion rather than in a straight line on drop:</p>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br>
<img id="drag1" src="https://picsum.photos/200/300" draggable="true" ondragstart="drag(event)" width="50" height="50">
<img id="drag2" src="https://picsum.photos/200/300?image=0" draggable="true" ondragstart="drag(event)" width="50" height="50">
<img id="drag3" src="https://picsum.photos/200/300/?gravity=east" draggable="true" ondragstart="drag(event)" width="50" height="50">
<img id="drag4" src="https://picsum.photos/200/300/?blur" draggable="true" ondragstart="drag(event)" width="50" height="50">
<img id="drag5" src="https://picsum.photos/200/300/?random" draggable="true" ondragstart="drag(event)" width="50" height="50">

second and third drag not working in javascript

have two div box. box001, box002
When I drag and drop box002 to another div box001 it get deleted, and box002 elemenets and contents get deleted, When I drag second box002 to second box001 its not working.
how can i achieve this?
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");
alert(data);
var el = document.getElementById(data);
el.parentNode.removeChild(el);
document.getElementsByClassName('box001')[0].style.backgroundColor = 'initial';
document.getElementById('11').innerHTML = '';
var x=document.getElementById(data).id;
var y=document.getElementsByClassName('box001')[0];
}
.box001 {
float: left;
width: 50px;
height: 50px;
border: 1px solid black;
border-radius: 10%;
background-color: #ff0000;
}
.box002 {
width: 50px;
height: 50px;
margin: -50px;
top: 76px;
float: left;
position: absolute;
left: 217px;
}
<div class="box001" ondrop="drop(event)" ondragover="allowDrop(event)" id="10"><p id="11"> 8:30</p></div>
<div class="box001" ondrop="drop(event)" ondragover="allowDrop(event)" id="20" ><p id="12">12:25</p></div>
<div class="box001" ondrop="drop(event)" ondragover="allowDrop(event)" id="30" ><p>01:00</p></div>
<div class="box002" draggable="true" ondragstart="drag(event)" id="11">
<img src="https://picsum.photos/200/300" draggable="true" id="1" style="width:50px; height:50px; border-radius: 50%;" border="rounded"/>
</div>
<div class="box002" draggable="true" ondragstart="drag(event)" id="21">
<img src="https://picsum.photo/200/300" draggable="true" id="2" style="width:50px; height:50px; border-radius: 50%;" border="rounded"/>
</div>
<div class="box002" draggable="true" ondragstart="drag(event)" id="31">
<img src="https://picsum.photo/200/300" draggable="true" id="3" style="width:50px; height:50px; border-radius: 50%;" border="rounded"/>
</div>

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;
}

Categories

Resources