I have referred following code to drag and drop in the same container;
drag_over and drop function can not be called; please provide some alternative
Note: Using Chrome and FireFox browser.
function drag_start(event) {
var style = window.getComputedStyle(event.target, null);
event.dataTransfer.setData("text/plain",
(parseInt(style.getPropertyValue("left"), 10) - event.clientX) + ',' + (parseInt(style.getPropertyValue("top"), 10) - event.clientY));
}
function drag_over(event) {
event.preventDefault();
return false;
}
function drop(event) {
var offset = event.dataTransfer.getData("text/plain").split(',');
var dm = document.getElementById('drag_div');
dm.style.left = (event.clientX + parseInt(offset[0], 10)) + 'px';
dm.style.top = (event.clientY + parseInt(offset[1], 10)) + 'px';
event.preventDefault();
}
$(document).ready(function () {
var dm = document.getElementById('drag_div');
dm.addEventListener('dragstart', drag_start, false);
document.body.addEventListener('dragover', drag_over, false);
document.body.addEventListener('drop', drop, false);
});
Try this demo :
<!DOCTYPE HTML>
<html>
<head>
<style>
#div1 {
width: 350px;
height: 70px;
padding: 10px;
border: 1px solid #aaaaaa;
}
</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>
<p>Drag the W3Schools image into the rectangle:</p>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br>
<p id="drag1" draggable="true" ondragstart="drag(event)" width="336" height="69"> Drag me to the box </p>
</body>
</html>
Related
I have a code in which there is a dragitem1 and a dropitem1,
Dragitem1 can be dragged and dropped to Dropitem1,
My problem is on dropping the Dragitem1, i want the dragitem1 width to be 100% on dropped area(inside Dropitem1).
for this i used
assignedTabName[0].style.width = "100%";
but didnt give the expected result.
How to make dragitem1 with to 100% on dropped area(after dropping)?
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");
console.log(data);
assignedTabName = document.getElementById(data).className;
console.log(assignedTabName);
ev.target.appendChild(document.getElementById(data));
assignedTabName[0].style.width = "100%";
}
.dragitem1{
border:2px solid black;
width: calc(16.3% - 4px);
height:80%;
margin-left:0.5%;
margin-top:0.5%;
margin-right:0.5%;
background-color:#2ecc71;
}
.dropitem1{
border:2px solid black;
position:fixed;
width:23vw;
height:10vh;
left:30vw;
bottom:80vh;}
<div class="dragitem1" draggable="true" ondragstart="drag(event)" id="drag1">
<p id="p1">TEST</p>
</div>
<div class="dropitem1" ondrop="drop(event)" ondragover="allowDrop(event)" id="drop1">
</div>
This should be your code for function drop()
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
console.log(data);
assignedTabName = document.getElementById(data);
console.log(assignedTabName.className);
ev.target.appendChild(assignedTabName);
assignedTabName.style.width = "100%";
}
Change assignedTabName[0] by document.getElementById(data), you where trying to set a style to a string
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");
console.log(data);
assignedTabName = document.getElementById(data).className;
console.log(assignedTabName);
ev.target.appendChild(document.getElementById(data));
document.getElementById(data).style.width = "100%";
}
.dragitem1{
border:2px solid black;
width: calc(16.3% - 4px);
height:80%;
margin-left:0.5%;
margin-top:0.5%;
margin-right:0.5%;
background-color:#2ecc71;
}
.dropitem1{
border:2px solid black;
position:fixed;
width:23vw;
height:10vh;
left:30vw;
bottom:80vh;}
<div class="dragitem1" draggable="true" ondragstart="drag(event)" id="drag1">
<p id="p1">TEST</p>
</div>
<div class="dropitem1" ondrop="drop(event)" ondragover="allowDrop(event)" id="drop1">
</div>
You're accessing the first character of the class name with assignedTabName[0]. Get the element once and store it in a variable, check it exists then change the style and append it.
function drop(event) {
event.preventDefault();
const id = event.dataTransfer.getData("text");
const element = document.getElementById(id);
if (element) {
element.style.width = "100%";
event.target.appendChild(element);
assignedTabName = element.className;
}
}
I have 3 box with id div1, and a box with id drag1. The box drag1 can be dragged and dropped to any of box div1.
I want to know if there is a way that the div drag1 can be seen during the drag in javascript - like in jquery.
Is there any revert back possible because I don't want to completely change the function to jquery
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));
}
/*
$("#drag1").draggable({
revert: "valid",
drag: function (event, ui) {
$("#info").html("<font color=red>This square will go back to it`s original position once it`s dropped in target zone. </font>");
}
});
$("#div1").droppable({
drop: function (event, ui)
{
$(this).css("background-color", "lightgreen")
},
out: function (event, ui)
{
$(this).css("background-color", "")
}
});
});
*/
#div1 {
width:120px;
height: 100px;
padding: 10px;
border: 1px solid #aaaaaa;
float:left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<img id="drag1" src="https://picsum.photos/200/300/?random"
draggable="true" ondragstart="drag(event)" width="100" height="100" style="border:solid">
First, in HTML, you must have unique IDs for each element, so div1 cannot be the ID for all three.
This example of mine is poorly put together and it gives you something to start with. You didn't include in your post what would be needed to trigger a revert event. my example only reverts a Drag if it is dragged to a Drop that has revert class name.
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
var boxData = ev.target.getBoundingClientRect();
ev.dataTransfer.setData("original-position-top", boxData.top);
ev.dataTransfer.setData("original-position-left", boxData.left);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
if (ev.target.className == "revert") {
var el = document.getElementById(data);
el.style.position = "relative";
var startPosition = el.getBoundingClientRect();
startPosition = {
top: startPosition.top,
left: startPosition.left
};
var targetPosition = {
top: ev.dataTransfer.getData("original-position-top"),
left: ev.dataTransfer.getData("original-position-left")
};
console.log("Trigger Revert", el.id, startPosition, targetPosition);
function calcSteps(start, finish) {
var l = Math.abs(start.left - finish.left);
var t = Math.abs(start.top - finish.top);
return {
top: t,
left: l,
pick: (l > t ? "left" : "top")
};
}
var steps = calcSteps(startPosition, targetPosition);
console.log("Steps:", steps);
var a = setInterval(frame, 2);
function frame() {
var i = steps.pick;
console.log("Animate Frame:", steps[i]);
if (steps[i] <= 0) {
clearInterval(a);
} else {
if (startPosition.left + 1 > targetPosition.left) {
// Do nothing
} else {
startPosition.left++;
el.style.left = startPosition.left + "px";
}
if (startPosition.top + 1 > targetPosition.top) {
// Do nothing
} else {
startPosition.top++;
el.style.top = startPosition.top + "px";
}
console.log("Animate Frame:", steps[i], startPosition);
steps[i]--;
}
}
}
}
#div1,
#div2,
#div3 {
width: 120px;
height: 100px;
padding: 10px;
border: 1px solid #aaaaaa;
float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)" class="revert"></div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="div3" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<img id="drag1" src="https://picsum.photos/200/300/?random" draggable="true" ondragstart="drag(event)" width="100" height="100" style="border:solid">
Hope that helps.
I want to get the dataset-attributes "data-price" with two decimalnumbers of dragged div boxes via Javascript to sum them up.
Here my div box:
<div name="qty" id="black" data-price="21.1" draggable="true" ondragstart="drag(event)">
I tried to do it with this script
<script type="text/javascript">
function findTotal(){
var arr = document.querySelectorAll("se > div");
var tot=0;
for(var i=0;i<arr.length;i++){
if(parseInt(arr[i].dataset.price))
tot += parseInt(arr[i].dataset.price);
}
document.getElementById('total').value = tot;
}
</script>
but it only counts the data-prices of the non-dragged boxes.
<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>
What i'm doing wrong here?
You should really add the whole HTML code for us to see how you have set the elements with form/name/attributes. I wrote a simple example based on your code and it works just fine for me and it calculates only the elements that are dropped to the target element. Also for decimal numbers, use parseFloat and not parseInt:
function findTotal(){
var arr = document.querySelectorAll(".target > div");
var tot=0;
for(var i=0;i<arr.length;i++){
if(parseInt(arr[i].dataset.price))
tot += parseFloat(arr[i].dataset.price);
}
document.getElementById('total').textContent = tot;
}
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));
findTotal();
}
document.getElementById('reset').onclick = function() { window.location.reload(); }
#black {
background-color: black;
color:white;
}
#red {
background-color: red;
}
#yellow {
background-color: yellow;
}
#green {
background-color: green;
color:white;
}
.qty {
width:50px;
height:50px;
display: inline-block;
margin-right:5px;
margin-bottom:5px;
}
.target {
height:100px;
border:1px solid grey;
}
<button id="reset">Reset</button>
<hr>
<form>
<div class="qty" id="black" data-price="21.1" draggable="true" ondragstart="drag(event)">21.1</div>
<div class="qty" id="red" data-price="16.5" draggable="true" ondragstart="drag(event)">16.5</div>
<div class="qty" id="yellow" data-price="7.8" draggable="true" ondragstart="drag(event)">7.8</div>
<div class="qty" id="green" data-price="3.5" draggable="true" ondragstart="drag(event)">3.5</div>
<h3>Drop items here</h3>
<div class="target" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<h3>Total: </h3>
<div id="total"></div>
</form>
My example can also be found here: http://zikro.gr/dbg/html/jsdd/
I've been trying to get my drag and drop to work, can't figure out what's wrong with it.
I basically can't drop the images to the body image.
I tried JSLint/JSHint to clean my code but that didn't help me get it to work.
Can someone please help me?
<!DOCTYPE html>
<html>
<head>
<title>Drag and Drop</title>
<style>
div#OuterDiv {
border: 1px solid black;
position: relative;
width: 1000px;
height: 1000px;
background-color: gray;
color: white;
font: times new roman;
}
</style>
</head>
<body>
<script language="text/javascript">
'use strict';
var ie4 = ua.indexOf("MSIE 4.0");
var curElement;
window.onload = opening;
document.ondragstart = doDragStart;
document.onmousedown = doMouseDown;
document.onmousemove = doMouseMove;
document.onmouseup = new Function("curElement=null");
function opening() {
if (ie4Final) {
if (body.style.display === "none") {
OuterDiv.filters[0].Apply();
body.style.display = "";
OuterDiv.filters[0].Play();
}
} else {
if (betaVer >= 2) {
body.style.display = "";
}
}
}
function doMouseMove() {
var newleft = 0,
newTop = 0;
if ((event.button === 1) && (curElement !== null)) {
newleft = window.event.x - tx;
if (newleft < 0) {
newleft = 0;
if (newleft + curElement.width > document.all.OuterDiv.offsetWidth) newleft = document.all.OuterDiv.offsetWidth - curElement.offsetWidth;
curElement.style.pixelLeft = newleft;
newtop = event.clientY - document.all.OuterDiv.offsetTop - (curElement.offsetHeight / 2);
if (newtop < 0) {
newtop = 0;
if (newtop + curElement.height > document.all.OuterDiv.offsetHeight) newtop = window.event.y - ty;
curElement.style.pixelTop = newtop;
event.returnValue = false;
event.cancelBubble = true;
}
}
function doDragStart() {
if ("IMG" === event.srcElement.tagName) {
event.returnValue = false;
}
}
function doMouseDown() {
if ((event.button === 1) && (event.srcElement.tagName === "img")) {
tx = window.event.x - event.srcElement.style.pixelLeft;
ty = window.event.y - event.srcElement.style.pixelTop;
curElement = event.srcElement;
}
}
</script>
<script FOR="body" event="onMouseDown">
event.cancelBubble = true;
</script>
<div id="OuterDiv">
<h1><Center>Drag and Drop - potato head</center></h1>
<img ID="body" style="position:absolute;left:10;top:190;z-index:19;" src="BODY.GIF" />
<img ID="ear1" style="position:absolute;left:60;top:70;z-index:19;" src="EAR1.GIF" />
<img ID="ear2" style="position:absolute;left120;top:70;z-index:19;" src="EAR2.GIF">
<img ID="glasses4" style="position:absolute;left:120;top:70;z-index:19;" src="GLASSES4.GIF" />
<img ID="mouth1" style="position:absolute;left:290;top:70;z-index:19;" src="MOUTH1.GIF" />
<img ID="nose1" style="position:absolute;left:450;top:70;z-index:19;" src="NOSE1.GIF" />
<img ID="eyes4" style="position:absolute;left:510;top:70;z-index:19;" src="EYES4.GIF" />
</div>
</body>
</html>
You may try next code:
function ondrop(ev){
var FieldClone=document.getElementByID("textField").clone(true);
ev.target.appendChild(FieldClone);
}
<input type="text" id="textField" value="Drop me" name="" draggable="true">
<div id="sec_drop" ondrop="drop(event)"style="width: 500px;height: 370px;"ondragover="allowDrop(event)">
</div>
I tried swapping two elements inside div1 and div2 tag but only the first replace function executes properly the other element is not swapped
either one of the div is getting swapped at once but when i try to swap both at same time it doesn't happen please help me out
*
<head>
<style type="text/css">
#div1 {
width:350px;
height:70px;
padding:10px;
border:1px solid #aaaaaa;
}
#div2 {
width:350px;
height:70px;
padding:10px;
border:1px solid #aaaaaa;
}
</style>
<script>
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
var child = ev.target;
var parents = child.parentNode;
ev.dataTransfer.setData("child1", child.id);
ev.dataTransfer.setData("parent1", parents.id);
}
function drop(ev) {
ev.preventDefault();
var childid1 = ev.dataTransfer.getData("child1");
var parentid1 = ev.dataTransfer.getData("parent1");
var parent1 = document.getElementById(parentid1);
var c = ev.currentTarget.childNodes;
var childid2 = c[1].id;
parent1.replaceChild(c[1], document.getElementById(childid1));
var parent2 = ev.currentTarget;
parent2.removeChild(c[1]);
parent2.appendChild(document.getElementById(childid1));
}
</script>
</head>
<body>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<img id="drag1" src="img_logo.gif" draggable="true" ondragstart="drag(event)" width="336" height="69">
</div>
<br>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)">
<img id="drag2" src="img_logo.gif" draggable="true" ondragstart="drag(event)" width="236" height="49">
</div>
</body>
I think your fundamental flaw is that you do not cater for the fact that when you do your first replaceChild, the image you are inserting is removed from its parent so it is no longer there to replace with the second image.
I found your variable names somewhat confusing, and have rewritten your code in a simpler fashion as follows:
function allowDrop (ev) {
ev.preventDefault ();
}
function drag (ev) {
ev.dataTransfer.setData ("src", ev.target.id);
}
function drop (ev) {
ev.preventDefault ();
var src = document.getElementById (ev.dataTransfer.getData ("src"));
var srcParent = src.parentNode;
var tgt = ev.currentTarget.firstElementChild;
ev.currentTarget.replaceChild (src, tgt);
srcParent.appendChild (tgt);
}
You can test this code at jsFiddle