Rick n Truckee Rick n Truckee - 3 months ago 12
Javascript Question

replace image with drag drop

I've gotten help from several on this site developing a drag/drop educational game where students drag images into the proper order. I was able to accomplish my goals in a Winform with Visual Basic. Now I'm trying to do the same in html. Using the three functions below, I'm able to drag and drop an image from one div into another empty div. But it doesn't work if I attempt to drop an image into a div that already contains an image. I did see a response in StackOverflow about using this line "ev.target.removeChild(ev.target.childNodes[0]" in the drop function. But this just creates an error "Argument 1 of Node.removeChild is not an object." Thanks for your help.

<!DOCTYPE HTML>
<html>
<head>
<style>
#div1, #div2, #div3, #div4, #div5
{float:left; width:100px; height:35px; margin:10px;padding:10px;border:1px solid #0066ff;}
#btn1
{float:left; width: 120px; height: 40px; margin: 125px; }
</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.removeChild(ev.target.childNodes[0]); //This line created an error
ev.target.appendChild(document.getElementById(data));
}
</script>

</head>
<body>

<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"><img src='Images/grass(3).jpg' draggable="true" ondragstart="drag(event)" id="drag1" width="88" height="31"> </div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"><img src="Images/sun.jpg" draggable="true" ondragstart="drag(event)" id="drag2" width="88" height="31"> </div>
<div id="div3" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="div4" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="div5" ondrop="drop(event)" ondragover="allowDrop(event)"></div>

</body>
</html>

Answer

After a lot of trial and error plus internet searches, I finally came up with an answer to my own question. The essence of my question was that I could not drag and drop one image on to another. Typically the dragged image would disappear. What I really wanted to do was "swap" two images, and drop image A on to image B and then have image B show up where image A was.

I found a tutorial sample by Sue Smith at the following web site:

http://www.webdesign.org/how-to-create-an-html5-drag-and-drop-component.22289.html

In this sample she shows how to set up 6 divs, each with an inner div with a text string in each inner div (typically one word.) In her sample it was very easy to drag and "swap" one word with another. But if you put an image in the div, it would no longer work.

So what I did was create an ID for each inner div. Then I assigned a background image for each inner div as well as removed the text. After experimenting with Sue Smith's code, I was finally able to accomplish the replacing and swapping of inner divs (with their associated background picture.) The end result is that it looks as if you are just dragging, dropping and swapping images. This worked fine in both Chrome and Firefox. For some reason it did not work in IE ver 11. You can see the modified code below.

<!DOCTYPE HTML>
    <html> 
    <head>
         <style type="text/css">
         .mover {
             width:200px; height:170px; line-height:4em; margin:10px;                                                padding:5px; float:left; 
             border:1px dotted #333333; text-align:center;  
             } 
             #boxA{
                background-image: url(images/coyote.jpg)
             }
             #boxB{
                background-image: url(images/black_bear.jpg)
             }
             #boxC{
                background-image: url(images/grass.jpg)
             }
             #boxD{
                background-image: url(images/rabbits.jpg)
             }
             #boxE{
                background-image: url(images/sun.jpg)
              }
          </style>
          <script type="text/javascript">
               function dragWord(dragEvent){
                  dragEvent.dataTransfer.setData("Id",    dragEvent.target.id+"|"+dragEvent.target.parentNode.id);
                 }                   
               function dropWord(dropEvent){ 
                var dropData = dropEvent.dataTransfer.getData("Id");
                dropItems = dropData.split("|"); 
                var prevElem = document.getElementById(dropItems[1]); 
                prevElem.getElementsByTagName("div")[0].id =      dropEvent.target.id;              
                dropEvent.target.id = dropItems[0]; 
                dropEvent.preventDefault(); 
                } 
                </script> 
                </head> 
                <body> <div><em>Drag and drop the pictures in order to show      how energy moves through a food chain.</em></div> 
                    <div id="box1" ondragover="event.preventDefault()"      ondrop="dropWord(event)" > 
                    <div class="mover" id="boxA" draggable="true"      ondragstart="dragWord(event)" ></div> 
                    </div>
                    <div id="box2" ondragover="event.preventDefault()"     ondrop="dropWord(event)"> 
                    <div class="mover" id="boxB" draggable="true"      ondragstart="dragWord(event)"></div> 
                    </div>
                    <div id="box3" ondragover="event.preventDefault()"      ondrop="dropWord(event)"> 
                    <div class="mover" id="boxC" draggable="true"      ondragstart="dragWord(event)"></div> 
                    </div> 
                    <div id="box4" ondragover="event.preventDefault()"      ondrop="dropWord(event)"> 
                    <div class="mover" id="boxD" draggable="true"      ondragstart="dragWord(event)"></div> 
                    </div> 
                    <div id="box5" ondragover="event.preventDefault()"      ondrop="dropWord(event)"> 
                    <div class="mover" id="boxE" draggable="true"     ondragstart="dragWord(event)"></div> 
                    </div>                                      
            </body> 
            </html>