Content of HTML table cells can be dragged to another cell or another table. It isn’t difficult to define onMouseMove handler and change top / left element styles to move the object. In case with tables, you will have to determine somehow target cell. Attaching onMouseOver handler on TD elements will not work, because browser doesn’t fire events to the elements below the dragged object.
Anyway, after taking care of the current scroll position and calculating TD positions, REDIPS.drag should work in recent major browsers like Google Chrome, Firefox, Safari, Internet Explorer, Opera and mobile devices as well. Click on image below, will open live demo where you can drag green, blue or orange bordered DIV elements, change properties (radio button and check-boxes) and click on “Save” button.
Download latest version redips2.tar.gz

REDIPS.drag example01
In this example “Save” button will scan table content, create query string and send to PHP page. Demo shows how to collect content and accept parameters on the server side. More about accepting parameters you can read at Reading multiple parameters in PHP. “Clone” elements (orange in this demo) will be duplicated first because of “redips-clone” keyword contained in class name. If you drop object on cell named “Trash”, object will be deleted from the table (with or without confirmation). Library has built in autoscroll and option to forbid landing to non empty cells or cells named with class “redips-mark”. Table can contain rowspan / colspan TDs and different background color for every cell.
Here are minimal steps to enable content dragging in table:
- put <script type=”text/javascript” src=”redips-drag-min.js”></script> to the head section
- initialize REDIPS.drag library: <body onload=”REDIPS.drag.init()”>
- place table(s) inside <div id=”redips-drag”> to enable content dragging
- place <div class=”redips-drag”>Hello World</div> to the table cell
Other features of REDIPS.drag library:
- methods and data structure are defined in namespace (easier integration with other JS frameworks)
- all JavaScript code is checked with ESLint
- REDIPS.drag documentation generated with JsDoc Toolkit
- drag and drop table rows
- movable DIV element can contain other HTML code (images, forms, tables …)
- forbidding or allowing TDs marked with class name “redips-mark”
- option to define exceptions and allow dropping certain DIV elements to the marked cell
- option to define single content cell on the table declared with “multiple” drop option
- cloning
- for unlimited cloning add “redips-clone” class name to the DIV object
<div class=”redips-drag redips-clone”>Hello World</div> - to limit cloning and transform last object to the ordinary movable object add ‘climit1_X’ class name
<div class=”redips-drag redips-clone climit1_4″>Hello World</div> - to limit cloning and transform last object to immovable object add ‘climit2_X’ class name
<div class=”redips-drag redips-clone climit2_4″>Hello World</div> - where X is integer and defines number of cloned elements (in previous examples, each climit will allow only 4 cloned elements)
- for unlimited cloning add “redips-clone” class name to the DIV object
- unlimited nested tables support
- dropping objects only to empty cells
- switch cell content
- switching cell content continuously
- overwrite TD content with dropped element
- shift table content
- table cell with “redips-trash” class name becomes trashcan
- enabled handlers to place custom code on events: changed, clicked, cloned, clonedDropped, clonedEnd1, clonedEnd2, dblClicked, deleted, dropped, droppedBefore, finish, moved, notCloned, notMoved, shiftOverflow, relocateBefore, relocateAfter, relocateEnd, rowChanged, rowClicked, rowCloned, rowDeleted, rowDropped, rowDroppedBefore, rowDroppedSource, rowMoved, rowNotCloned, rowNotMoved, rowUndeleted, switched and undeleted
- deleting cloned DIV if the cloned DIV is dragged outside of any table
- enabling / disabling dragging
- animation (move element/row to the destination cell/row)
- added support for touch devices (touchstart, touchmove, touchend)
How REDIPS.drag works?
Script will search for DIV elements (with class name “redips-drag”) inside tables closed in <div id=”redips-drag”> and attach onMouseDown event handler. When user clicks with left mouse button on DIV element, onMouseMove and onMouseUp handlers will be attached to the document level.
While dragging DIV element, script changes its “left” and “top” styles. This is function of the onMouseMove handler. When user releases left mouse button, onMouseUp event handler will unlink onMouseMove and onMouseUp event handlers. This way, browser will listen and process mousemove events only when DIV element is dragged.
As I mentioned, onMouseDown is defined on the elements you want to drag. Elements beneath the dragged object will not be able to catch onMouseOver event. Why? Because you are dragging object and that object only can catch the onMouseOver event.
So, to detect destination table cells, script calculates all cell coordinates (with scroll page offset) and store them to the array. Array is searched inside onMouseMove handler and after left mouse button is released, DIV will drop to the current (highlighted) table cell.
In redips2.tar.gz package you will find many examples including example of how to save/recall table using PHP and MySQL. Package also contains and redips-drag-min.js – a compressed version of REDIPS.drag library (compressed with Google Closure Compiler).
Happy dragging and dropping!
@brad – Here is JavaScript code to display element Id, target and source location. Code is placed within myhandler_dropped() event handler. Hope this will help!
Thanks Darko. Works perfectly
can you give me the code of pop up window which is comes on click to save button ??
@jems – No problem, here is “save” code (just double click on code box to select all and copy):
If I allow an element to be cloned thrice, and I have three tables, how do I ensure that each table has only one element ?
@Ankit Daftary – This can be accomplished with some JS code inside myhandler_dropped_before() event handler. You will have to test if element already exists inside current table and if this control statement is true, just return “false” from this event handler (cloned element will be deleted).
Hello,
How i restrict placement of cell out side table 1 same for table 2 ?
means i don’t want to place selected cell from table 1 to table2 . in-short drag and drop option only surroundings with same table.
@kiran – It’s possible to have two or more drag containers totally separated. Means that elements from first drag container are not be possible to drop to the second container and vice versa. Actually, inside redips2.tar.gz package example08 demonstrates separated containers in action.
Hello
If I have an Ajax postback anywhere else on the page, the drag and drop functionality is lost.
Any ideas??
@Jay – AJAX and REDIPS.drag should not have collision. Please see example16 (click on preview below post title) where content of DIV element (text + flower) is retrieved with AJAX. If you change content of drag area (tables) with postback then REDIPS.drag.init() should be called to initialize new tables layout.
Preface…learning as I go…not a ‘real’ developer
I played with this in HTML & its just what I need….but am trying to apply it in a ASP project & guess I dont know how to initialize….also, different in content vs div tags…..
Can you give some guidance, pls?
Shouldnt the jscript work in aspx?
@jltbdy – REDIPS.drag is a frontend tool and it should work with any server side technology. Regardless of how tables layout is prepared, REDIPS.drag lib should be initialized. During initialization process, tables inside drag region are scanned and saved to internal array. Any modificiation of tables number or order should be followed with calling REDIPS.drag.init() method. If you will have any further questions I will gladly help.
Cheers!
I am working on a project that is similar to example 9. I have a list of names in the right table. I want to be able to drag the names over to the left table and be able to rank the names in order by the users preference.
Why is it when I have drop_option set to switching for the left table, it is possible to get two items into the exact same cell? I would like to prevent that from happening, but don’t know how to prevent it.
Hi,
I am trying to integrate it with JQuery table grid, followed above integration steps. but when trying to drag as soon as I clicked I am getting e is null JS error.
Thanks
Osman
I love this….I was wondering how I could group an entire row has one div class and move that around. Is this doable?
okay… So i found example 15 and saw we could move the entire row. I got it working and it’s great. The only problem, I would like to keep the borders and bgcolors the same after the move. Is this an option?
@bruce – Example19 was made for as a rank list. Initially table is empty and items from the left table should be placed to the empty cells only. If you want to enable more then one element per table cell then you can define multiple drop option (instead of switching) in set_drop_option() function in script.js file.
@Osman – REDIPS.drag has its own namespace and there should not be collision issues with jQuery or any other JavaScript library. My guess is that problem is related to the initialization process. If you have online example to show, I will gladly try to see where is the problem.
@Mike Fernholz – Yes, you can turn off opacity settings of source row. Please see the commented line from script.js file:
Hi Darko,
it is a great work ! thanks alot.
I have a question. My scenario is : I have two rows. First row has a height 100px. And second row has a height 30px.
At the beginning, Dragdroppable div is in the first row. And its height is also 100px. When I drag and drop it into the second row, my second row is becoming also 100px. Is there a way to keep second row always 30px, and when I will drag&drop div into the second row, I want div to be also 30px (smaller ). Is it possible? and how can I do it?
thanks again,
Joerg.
Hello Darko,
On a single click on a DIV for dragging, is there a way to “CANCEL” the entire event within the “myhandler_clicked” function without any of the new DIV details being loaded..basically revert/restore back the last clicked?
My situation is this….
When a DIV has been dragged, I populate it’s outside associated details into an “info panel”. If they edit the details within the “info panel” and did not save it and the user should drag another DIV, I want to throw up a CONFIRM() box. If they click the “cancel” option…I want the entire drag process to be canceled with nothing being changed within your framework. If they click ok, then they can go back to doing the dragging they had intended and I clear out my tracking of any edits/changes made in the “info bar”.
I hope this makes sense.
Great work on this!!!!
Chris