Drag and drop table rows with JavaScript

More...

REDIPS.drag was initially built to drag and drop table content. After publishing first version of REDIPS.drag, I received a lot of questions about dragging table rows also. Now is possible to drag and drop table rows as well as table content. First column and contained DIV element in this demo is a row handler, so you can try to drag table rows.

Table 1
Drag
and
drop
table
rows
with
REDIPS
lib
Message line
Table 2
Drag
rows
and
table
drop
Message line

It is very easy to define a row handler. Actually, it is only needed to place DIV element to the column (first, last or any other) and to define class="drag row". This DIV element will become a row handler. When row dragging begins, source row will change color and content will become transparent. This way, source row as start point is visible and obvious. It is possible to return row to the start point - in this case, event.rowDroppedSource() will be fired. In a moment when row is dropped to the destination table, source row will be removed. How REDIPS.drag works? The trick is to clone a mini table from the source table and to remove all rows except selected row. It looks like a row, but it is a table with only one row - a mini table. New functionality also brings new event handlers:

  1. event.rowChanged
  2. event.rowClicked
  3. event.rowCloned
  4. event.rowDeleted
  5. event.rowDropped
  6. event.rowDroppedBefore
  7. event.rowDroppedSource
  8. event.rowMoved
  9. event.rowNotCloned
  10. event.rowNotMoved
  11. event.rowUndeleted

Each event handler has access to the obj and objOld objects. For example, event.RowClicked() sees only obj object and this is reference to the source row. event.rowMoved() is fired in a moment when dragging starts and in this case, obj is reference to the mini table (previously mentioned) while objOld is reference to the source table row.

REDIPS.drag has a new method: rowOpacity(el, opacity, color) to change color and opacity of the source row and mini table. This way it is only needed to call rowOpacity() method in event handlers to have row effects like in this demo. Here is code for event.rowMoved() used in this demo:

rd.event.rowMoved = function () {
    // set opacity for moved row
    // rd.obj is reference of cloned row (mini table)
    rd.rowOpacity(rd.obj, 85);
    // set opacity for source row and change source row background color
    // rd.objOld is reference of source row
    rd.rowOpacity(rd.objOld, 20, 'White');
    // display message
    msg.innerHTML = 'Moved';
};

REDIPS.drag takes care about background color of table cells and table rows. When dragging begins, color of each table cell is saved to the array and returned in a moment of dropping or highlighting current table row. Source code of REDIPS.drag library with examples can be download from "download icon" below post title. If you want to see more drag and drop examples based on REDIPS.drag, click on Drag and Drop category.

Happy dragging and dropping!

This entry was posted on April 6, 2011 and is filed under Drag and Drop, JavaScript

Related posts

165 Responses to Drag and drop table rows with JavaScript

  1. Kleber says:

    How to catch id that is being moved? Here is example:

    rd.event.moved = function () {
        msg.innerHTML = 'Moved';
        alert (id);
    }
    
  2. John says:

    if use table top level, drag container is under table, it does not work, how to make it work like the following html structure ? thanks lot.

    .here add drag and drop table row ..

  3. John says:

    if we use the structure: table - tr-td -div id="drag" -drag and drop rows here ......., ,the drag and drop lib did not work, if anybody know how to work around this issue ? thanks
    John

  4. dbunic says:

    @MikeF - Maybe your problem is related to the size of DIV#drag container. Please add the following style to the style.css file:

    #drag {
        border: 1px solid lime;
    }
    

    This will make DIV#drag visible. So, if DIV#drag doesn't wrap whole table then issues like you're describing may happen. Just set correct width/height to the drag region and dragging should work fine. This problem is mentioned Appendix A documentation. Or you can make drag container extensible with "display: table" style:

    #drag {
    	border: 1px solid lime;
    	display: table;
    }
    

    ... and your second question. You can block dropping DIV element to some table with droppedBefore(targetCell) method (input parameter is target cell). So, the trick is to climb from TD to TABLE in DOM (please see REDIPS.drag.findParent()) and if found table is not allowed, just return "false" from droppedBefore() event handler and DIV element will return to the source position. Hope this tip will be helpful for your case.

    @Kleber - Using alert() is not a good way because browser will stop current moving. Instead change innerHTML property of some HTML element (SPAN, DIV, TD ...) on the page. Here is sample code:

    rd.event.moved  = function () {
        var msg = document.getElementById('message');
        msg.innerHTML = rd.obj.id;
    };
    

    Actually, this example is not so shiny because "message" reference is set on each move event. Better approach is to set element reference once outside the handler.

    @John - REDIPS.drag lib is designed to allow nested tables. Please see example 13 - Nested tables with simple DIV elements (darker cells are more deep).

    Example 19: Groups and table rows shows how TR is moved between tables nested one level deeper.

    Hope this examples will give you some directions how to resolve your issues.
    Cheers!

  5. Vince says:

    How you can drag & drop from one table to another if the target table has no rows?

    I also made a double click on the row of source table to "fly" to the empty table, but that is possible only if there is at lest 1 row. Is ti possible to put a row in a empty table?

    This is the error that I get when I try to do that (I have Version 5.0.8) :
    TypeError: tables[i].rows[row] is undefined redips-drag-source.js:3763

    I see that your script is looking for at least 1 row. Is it possible in this case to create one dummy row put the one from the source table and delete the dummy one? If yes, how this could be done?

Leave a Reply

Your email address will not be published. Required fields are marked *

*

In case of posting HTML tags or JavaScript code please convert special characters to HTML entities.
Especially pay attention to convert "<" character to "&lt;" entity!