1

I am trying to write a html page using html5's drag and drop. I have a table in which I want to drag and drop various text elements. There may be more than one element in each table cell. I then want to parse this table outputting the table row of each element. What I am finding is that if I drag an element into a table cell sometimes the element is inserted within an element in that cell but as an entry in the table.

So the original html of my table is

<thead>
        <tr>
            <td>id</td>
            <td>planet</td>
        </tr>
        </thead>
        <tbody>
                <tr>
                        <td>01</td>
                        <td ondrop="drop(event)" ondragover="allowDrop(event)">
                            <p draggable="true" ondragstart="drag(event)" id="sun">sun</p>
                        </td>
                </tr>
                <tr>
                        <td>02</td>
                        <td ondrop="drop(event)" ondragover="allowDrop(event)">
                            <p draggable="true" ondragstart="drag(event)" id="mercury">mercury</p>
                        </td>
                </tr>
                <tr>
                        <td>03</td>
                        <td ondrop="drop(event)" ondragover="allowDrop(event)">
                            <p draggable="true" ondragstart="drag(event)" id="mars">mars</p>
                        </td>
                </tr>
                <tr>
                        <td>04</td>
                        <td ondrop="drop(event)" ondragover="allowDrop(event)">
                            <p draggable="true" ondragstart="drag(event)" id="earth">earth</p>
                            <p draggable="true" ondragstart="drag(event)" id="moon">moon</p>
                        </td>
                </tr>
        </tbody>
</table>

And I use these script elements to move and output these items (linked to a button).

                    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));
                    }


                    function output()
                    {
                            var atable = document.getElementById("atable");
                            var rows = atable.rows.length;

                            for (var i = 1; i < rows; i++) {
                                    var cells = atable.rows.item(i).cells;
                                    var planets = cells.item(1).getElementsByTagName("p");
                                    for (var j=0; j < planets.length; j++) {
                                            console.log(i + " - " + planets[j].innerHTML);
                                    }
                            }    
                    }

If i run the output without dragging anything about it looks like this.

1 - sun
2 - mercury
3 - mars
4 - earth
4 - moon

If I then drag items on top of each other the output looks like this

1 - sun<p draggable="true" ondragstart="drag(event)" id="moon">moon</p>
1 - moon
2 - mercury
3 - mars
4 - earth

And the table looks like this

<tbody>
        <tr>
                <td>01</td>
                <td ondrop="drop(event)" ondragover="allowDrop(event)">
                    <p draggable="true" ondragstart="drag(event)" id="sun">sun<p draggable="true" ondragstart="drag(event)" id="moon">moon</p></p>
                </td>   
        </tr>
        <tr>
                <td>02</td>
                <td ondrop="drop(event)" ondragover="allowDrop(event)">
                    <p draggable="true" ondragstart="drag(event)" id="mercury">mercury</p>
                </td>   
        </tr>
        <tr>
                <td>03</td>
                <td ondrop="drop(event)" ondragover="allowDrop(event)">
                    <p draggable="true" ondragstart="drag(event)" id="mars">mars</p>
                </td>   
        </tr>
        <tr>
                <td>04</td>
                <td ondrop="drop(event)" ondragover="allowDrop(event)">
                    <p draggable="true" ondragstart="drag(event)" id="earth">earth</p>

                </td>   
        </tr>
    </tbody>

So the drag and drop has dropped the html into the sun paragraph. Anyone know how I can stop this happening? I have tried adding ondragover="return false;" and ondrop="return false;" to the p elements but to no success.

squilliam
  • 23
  • 1
  • 4
  • 1
    you are appending the html output (in text) to the element, that is why you're seeing what you're seeing. – zerohero Dec 06 '16 at 12:38
  • Thanks for the speedy response I tried changing the drag type to text/html but still get the same outcome. Is this what you meant? I can drag them apart and if I drag them carefully they wont merge. Is there a way to make the p elements not droppable. – squilliam Dec 06 '16 at 13:11
  • I found a solution. I changed my drop function as below `function drop(ev) {` ` if(ev.target.getAttribute('data-draggable') == 'target')` ' {' ' var data = ev.dataTransfer.getData("text/html");' ' ev.target.appendChild(document.getElementById(data));' ' ev.preventDefault();' ' }' ' }' and added a data-draggable="true" to the cell definition '' – squilliam Dec 06 '16 at 16:08

0 Answers0