I have been working on a project thet needs HTML5
drag & drop and I'm stuck atm with something that probably would be so easy to achieve but I can't seem to find the solution.
Basically I have some draggable elements and some drop areas. As it's alwasy easier to explain with a working example I have made this simple JSFIDDLE
Right now You can drag any element into any drop area or move them out as I need, but what I would like to achieve is to make the orange boxes to drop JUST in any of the green areas (and ignore the blue one... make it move back to original position if you drop it there) and the red box JUST into the blue one (ignoring the green ones).
Could anyone help me or hint me a way to work on this?
function DragOver(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));
}
var elemens = document.querySelectorAll('.draggable');
[].forEach.call(elemens, function(elem) {
elem.addEventListener('dragover', DragOver, false);
elem.addEventListener('drop', Drop, false);
});
#divContenedor {
width: 950px;
height: 500px;
}
#div1,
#div2,
#div3 {
width: 350px;
height: 70px;
border: 1px solid #aaaaaa;
background-color: green;
}
#div4 {
width: 350px;
height: 70px;
border: 1px solid #aaaaaa;
background-color: blue;
}
<p>
Drag&drop testing</p>
<div id="divContenedor" class="draggable" style="background-color: yellow; width: 100%; float: left; position: relative;">
<div id="drag1" draggable="true" ondragstart="Drag(event)" style="width: 336px; height: 69px; background-color: orange; cursor: move;">1</div>
<div id="drag2" draggable="true" ondragstart="Drag(event)" style="width: 336px; height: 69px; background-color: orange; cursor: move;">2</div>
<div id="drag3" draggable="true" ondragstart="Drag(event)" style="width: 336px; height: 69px; background-color: red; cursor: move;">3</div>
</div>
<div style="position: absolute; top: 100px; left: 500px;">
<div id="div1" class="draggable" ></div>
<br />
<div id="div2" class="draggable" ></div>
<br />
<div id="div3" class="draggable" ></div>
<br />
<div id="div4" class="draggable" ></div>
</div>
I have been working on a project thet needs HTML5
drag & drop and I'm stuck atm with something that probably would be so easy to achieve but I can't seem to find the solution.
Basically I have some draggable elements and some drop areas. As it's alwasy easier to explain with a working example I have made this simple JSFIDDLE
Right now You can drag any element into any drop area or move them out as I need, but what I would like to achieve is to make the orange boxes to drop JUST in any of the green areas (and ignore the blue one... make it move back to original position if you drop it there) and the red box JUST into the blue one (ignoring the green ones).
Could anyone help me or hint me a way to work on this?
function DragOver(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));
}
var elemens = document.querySelectorAll('.draggable');
[].forEach.call(elemens, function(elem) {
elem.addEventListener('dragover', DragOver, false);
elem.addEventListener('drop', Drop, false);
});
#divContenedor {
width: 950px;
height: 500px;
}
#div1,
#div2,
#div3 {
width: 350px;
height: 70px;
border: 1px solid #aaaaaa;
background-color: green;
}
#div4 {
width: 350px;
height: 70px;
border: 1px solid #aaaaaa;
background-color: blue;
}
<p>
Drag&drop testing</p>
<div id="divContenedor" class="draggable" style="background-color: yellow; width: 100%; float: left; position: relative;">
<div id="drag1" draggable="true" ondragstart="Drag(event)" style="width: 336px; height: 69px; background-color: orange; cursor: move;">1</div>
<div id="drag2" draggable="true" ondragstart="Drag(event)" style="width: 336px; height: 69px; background-color: orange; cursor: move;">2</div>
<div id="drag3" draggable="true" ondragstart="Drag(event)" style="width: 336px; height: 69px; background-color: red; cursor: move;">3</div>
</div>
<div style="position: absolute; top: 100px; left: 500px;">
<div id="div1" class="draggable" ></div>
<br />
<div id="div2" class="draggable" ></div>
<br />
<div id="div3" class="draggable" ></div>
<br />
<div id="div4" class="draggable" ></div>
</div>
UPDATE JSFIDDLE with @Amen solution.
Share Improve this question edited Dec 21, 2015 at 12:17 Alvaro Menéndez asked Dec 21, 2015 at 11:23 Alvaro MenéndezAlvaro Menéndez 9,0323 gold badges40 silver badges58 bronze badges2 Answers
Reset to default 7You can use data
attributes logic and do following 3 simple modifications to achieve that
1) add to draggable
elements attribute data-appendto="green"
or blue
2) add to div
elements where you dragable element should append data-boxtype="red"
or blue
3) in Drop(ev)
function you can check if your document.getElementById(data)
and ev.target
data attributes values are matching then allow drop. You can get elements data-attribute
with js .getAttribute('data-attribute')
function
if(ev.target.getAttribute('data-boxtype') ==
document.getElementById(data).getAttribute('data-appendto')){
ev.target.appendChild(document.getElementById(data));
}
Good answer Armen, but if you want to handle access on the dragover event, then add another attribute that says simply yes.
As you can see, I have 4 methods in my JavaScript module object that are all called from the drag and drop elements events.
Step 1. The OnDragStart event sets the stage by changing the data-ts-allowdrop attribute to "Yes" (its default is no), for all potential targets that match its drop element query. Assuming an element will accept more than 1 source, I perform a contains query to find the element and not an exact match
step 2. When dragged over the receiving element its DragOver Event will check its "data-ts-allowdrop" attribute to see if its been set to true or "Yes". If so, then it runs preventsDefault and the drop is allowed and handled by the OnDrop method which proceeds to turn off the "data-ts-allowdrop" attribute.
step 3. Also use the onEnd to set the "data-ts-allowdrop" to No in case the drag event is cancelled.
<div id="divName" draggable="true" ondragstart="tsjDragnDrop.setSource(event);" data-ts-drag-allow-source="admin" tabindex="1" ><span >Item to Drag</span><img alt="an icon" src="~/images/anImage.png" /></div>
<li ondragover="tsjDragnDrop.allowTarget(event);" ondragleave="tsjDragnDrop.onLeave(event)" ondrop="tsjDragnDrop.onDrop(event)" data-ts-drag-allow-target="admin" data-ts-allowdrop="No" >Drop Target in a list item</li>
var DraggnApi = {
allowTarget: function (event) {
var source = $(event.currentTarget).attr("data-ts-allowdrop");
$(event.currentTarget).addClass("ts-dragover");
if (source === "Yes") {
event.preventDefault();
}
},
onLeave: function (event) {
$(event.currentTarget).removeClass("ts-dragover");
},
onDrop: function (event) {
event.preventDefault();
var source = $(event.currentTarget).removeClass("ts-dragover");
$(event.currentTarget).attr("data-ts-allowdrop", "No");
},
onEnd: function (event) {
$(event.currentTarget).attr("data-ts-allowdrop", "No");
},
setSource: function(e)
{
e.dataTransfer.setData("text", "SomeText");
var source = $(event.currentTarget).attr("data-ts-drag-allow-source");
if ($("li[data-ts-drag-allow-target]").attr("data-ts-drag-allow-target").indexOf(source) > -1) {
$("li[data-ts-drag-allow-target*='" + source + "']").attr("data-ts-allowdrop", "Yes");
}
}
}