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;
}
}
Related
so I have a draggable HTML div element:
<div id="server" draggable="true" ondragstart="return dragStart(event)">Server</div>
and a target div:
<div id="target1" ondragenter="return dragEnter(event)" ondrop="return dragDrop(event)" ondragover="return dragOver(event)"></div>
if I drag the draggable into the target, then how do I get the value inside of the draggable if I only have the reference to the target that the draggable is in?
You might be looking to use the dataTransfer.setData method on the drag event and the datatransfer.getData method on the drop event. These methods will allow you to pass data between your elements.
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
var newText = ev.target.innerText;
newText = "I've been dropped!";
ev.dataTransfer.setData("text", ev.target.id);
ev.dataTransfer.setData("divData", newText);
console.log(ev.target); //available data
}
function drop(ev) {
var dragElemID = ev.dataTransfer.getData("text");
var dragElemData = ev.dataTransfer.getData("divData");
var draggedElem = document.getElementById(dragElemID)
ev.preventDefault();
ev.target.appendChild(draggedElem);
ev.target.children[0].innerText = dragElemData;
}
#div1{
border:1px solid;
width:100px;
height:150px;
}
#drag1{
background-color:lightblue;
width:100px;
height:100px;
}
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">Target Div</div>
<div id="drag1"draggable="true" ondragstart="drag(event)" width="336" height="69">Drop Div</div>
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 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>
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 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