Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

html5 drag and drop prevent drop unless div empty

I'm attempting to create a sort of visual interface for simple graphic creation. It consists of 10 image icons, and 5 boxes in which those icons can be placed. I want users to be able to pick which of the 10 icons they would like to display, and arrange the elements as they see fit using drag and drop. The 5 icons are also inside of a div in which the icons can be dropped, so that they can return the icon to the "home" row if they change their mind and wish to select another icon.

not unlike this simple tutorial, but with more divs and icons: http://www.w3schools.com/html/tryit.asp?filename=tryhtml5_draganddrop2

my script:

<script>
function allowDrop(ev)
{
ev.preventDefault();
}
function drag(ev)
{
ev.dataTransfer.setData("Text",ev.target.id);
//CSS CHANGES HERE FOR ON PICKUP
$( ".dragfive" ).css("border", "2px solid #ff9d00");
$( ".select5" ).css("border", "2px solid #ff9d00");
}
function drop(ev)
{
ev.preventDefault();
var data=ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
//CSS CHANGES HERE FOR ON DROP
$( ".dragfive" ).css("border", "2px solid transparent");
$( ".select5" ).css("border", "2px solid transparent");
}
</script>

my code is exactly the same as the tutorial, but I've added some nice CSS changes as the comments indicate - I made colorful borders appear to indicate to users where they can place the item. These become transparent once dropped. Works perfectly except...

  1. how can I prevent an icon from being dropped on top of another icon? (or rather, only allow dropping the icon into an empty div?)
  2. If I wished to create a second set of icons and replicate the process, how can I keep them and their allowed drop area separate? (so that the icons do not end up in unintended places)

thanks a bunch.

like image 718
cloudy Avatar asked Jan 31 '26 01:01

cloudy


2 Answers

use this, it has worked for my script... in order to prevent drop in div, which already has something in it like - image.

if (ev.target.hasChildNodes()) {
    ev.target.appendChild(document.getElementById(data));
}
like image 182
traveller Avatar answered Feb 01 '26 16:02

traveller


For #1, you need to make your drop function just a little bit more intelligent. Inside of it, check to make sure that there are no childNodes before appending the Child.

For #2, you need to make both drag and drop more intelligent. In drag, you need to look at the target and set some group information. In drop, you need to check that information to see if it matches appropriately.

I can show you what #1 should look like:

function drop(ev)
{
    ev.preventDefault();
    if (ev.target.hasChildNodes()) { return; }
    // ...all the rest as you had it

For #2, it will be a bit more complex, depending on how you want to define the second set of icons. Generally, it should make your code look something like this:

function drag(ev)
{
    ev.dataTransfer.setData("Text",ev.target.id);
    // I'm going to assume your group1 items will have "group1" in their id.  Set it up however you want.
    if (ev.target.id.indexOf("group1") != -1) {
        ev.dataTransfer.setData("Group", 1);
    } else {
        ev.dataTransfer.setData("Group", 2);
    }
    // ...all the rest as you had it
}

function drop(ev)
{
    ev.preventDefault();
    if (ev.target.hasChildNodes()) { return; }
    if (ev.target.id.indexOf("group1") != -1 && ev.dataTransfer.getData("Group") == 2 ||
        ev.target.id.indexOf("group2") != -1 && ev.dataTransfer.getData("Group") == 1) {
            return;
        }
    // ...all the rest as you had it
like image 28
Scott Mermelstein Avatar answered Feb 01 '26 14:02

Scott Mermelstein



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!