Drag and drop table rows with JavaScript

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.


REDIPS.drag example15

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!

178 thoughts on “Drag and drop table rows with JavaScript”

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

    rd.event.moved = function () {
        msg.innerHTML = 'Moved';
        alert (id);
    }
    
  2. 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. 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. @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. 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?

  6. @Vince – If table is empty it should contain “so called” empty row. Please take a look example20 or here in page try to move all rows from first to second table. At the end, table will have one “empty” row that can’t be moved. I think that example20 is a good start point for your project.

  7. One question, how to get one Cell of the row which is moved?
    I need to move rows and I need to identify which row is moved by the first cell…?

  8. I found your wonderful script and it has truly been very helpful. I have one problem though. I need to be able to reload the whole table with new values. Once I have done this, I no longer have the drag controls available. I made a jsfiddle (http://jsfiddle.net/betsyjsg/7kykbuac/) example. When I run the script initially, the table rows can be moved around without issue. But if I update the table with new values, the drag controls are lost. Is there any way to do this?

  9. First of all thank you for creating these libraries. It has been such an amazing learning experience. My question is regarding the drop element. If each of these elements are coming from a mysql database using php, how can I get it to update the mysql database on drop. It would be of great help if you could suggest me some starting point for this. I would really appreciate your input on this.

  10. How can i change the ‘drag row’ selector? I use bootstrap, and class ‘row’ is heavily used and can not be used as the drag selector class!

    Thanks!

  11. Hello, very great work!
    I would know if it possible have this structure: and drag and drop rows between tables? Because I have problem to drag and drop in the area not visible initial! I see in you example you move on single table scrollable, is it possible my case?
    Thanks
    Alice

  12. Oh my God, this is the most great work, what i ever seen. Thank you so much, your example01 has solved all my problems, what i had with ugly drag and drop in jQuery UI.

  13. Hello I appreciate so much the redips drag n drop and I am trying to apply thatto a project ofmines.
    Everithing good but a little (big!!!) problem: a row is dragged perfectly until you set the “minwidth” property or if you write some text in a cell of the second column..
    any idea?
    Thank you
    Eurasio

  14. REDIPS.drag library has built in auto-scroll for cases when table height is bigger than visible browser area. Auto-scroll should work for dragging DIV elements inside table and for dragging rows in table or between two tables.

  15. Is there any way to differentiate between a user dropping a row directly onto another row, and a user dropping a row between two rows? Thank you!

  16. Hi Katherine,
    row will be placed between 2 rows and colored border shows exact location where row will be dropped. So there is no difference how user drags row or what is current position in the moment when left mouse button is released – colored border between two rows highlights dropping position.

Leave a Comment