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!
@Ali – This library works only with table content not with table rows. Hopefully some day dragging functionality will include table rows. Anyway, maybe you can create one column wide table and design table content to look like table row … This is just a hint.
Hi,
Thanks for this great script. I am not a specialist in Javascript but I made it work. Now i would like to do something else for my application. My page has a table with 5 columns and 5 rows. I would the user to be able to drag and copy the value to any cell. RIght now it drags and paste and the old value is ‘lost’. Is it something possible ?
THnaks!!!
@romain – I suppose that “copy” means to clone DIV element. If so, you can define each element to clone itself. Cloning can be infinite or defined number of times. Whole idea of REDIPS.drag library is to move table content from one table cell to the another. DIV element can be moved / dragged or clone of DIV element. If you need further information, please don’t hesitate to ask.
I’m having some trouble with save_content() using multiple instances as per example 8. I want to call it so all tables are scanned on the page and posted, but when I have more than once instance, it only returns the one I most recently interacted with. My page is a series of table pairs, the first table in the pair has items that I want to drag to the second table in specific slots, then save to a database. I put some alerts into save_content() and it looks like the tables array is being reset every time I interact with a different pair of tables, so it’s basically only returning the last thing I touched.
@daveb – Yes, that was problem in prior version due to optimization of bringing working table to the array top. Anyway, please download and try latest REDIPS.drag package where this problem should disappear. Cheers!
Hi.
I have a quest. im creating a dynamic table in javascript. i included the div tag wit the class=’drag’. but its not draggable. does this library support for dynamicaly created tables? if so m i missin sometin? thanks. great library… :)
Hi. is there anyway to enable multiple cells be moved when only 1 cell is moved?
HI. sorry for so many quest. but i really like tis script n would like to implement it in my proj. but im stuck wit some probs. tats y i had come back here. sorry again.
another quest. cell movement is triggered on mousedown event rite? how bout if i wan to move a cell witout mouse click? for example when i move 1 of the cell, ill prompt a confirm ox to ask whether they wan to move the cell. if yes then all the other cell wit the same value wil be moved to cells next to moved cell. so how can i trigger tat? any example would be really helpfull. im still tryin alter it. but to no avail. cheers :) great script…
@Mohan – All tables should be inside DIV id=”drag”. After modifying table (add new row/column or even whole table) just call REDIPS.init() to scan changed or new table cells.
REDIPS.drag library supports dragging only one DIV element at a time. But if you mean to somehow select more then one DIV element and drop them all to the target cell then this might be possible. If so, it can be done with checkbox in DIV element. User can first check all DIV elements and after one element is dropped, custom function should collect checked DIV elements and relocate them to the destination table cell … REDIPS.drag contains “move_object” public method that can help moving DIV object from one table cell to another. Input parameters are source and destination table cell. Just peek to the redip-drag.js file and see source code of move_object().
So, inside myhandler_dropped() event handler you can put a custom code to collect all DIV elements with the same value (as you asked) and relocate them to the destination table cell. Inside myhandler_dropped() you can use previous_cell and target_cell properties as input parameters for REDIPS.drag.move_object().
Hope this tips will be useful and thank you for using my library.
thanks @dbunic. ill give it a try. cheers… n pls do keep the good work comin.. :)
Hi, first of all thanks for this awesome script.
I have a question: how can i save a cell position in my database. I generate dinamically a html table using a html form (so i have not predefined elements). I would like that when i drag an element from a cell to another cell (i use switch method) this new position could be saved in my databse. Thanks for your help and patience
@fede – If you are familiar with AJAX then there shouldn’t be a problem. REDIPS.drag library has 12 event hooks where you can place custom code. In your case you can use myhandler_dropped() event handler. So, this code will be executed after dropping DIV element to the table. Inside event handler you have access to the following public properties:
obj – (object) dragged object
obj_old – (object) previously moved object (before clicked or cloned)
source_cell – (object) source table cell (defined in onmousedown)
target_cell – (object) target table cell (defined in onmouseup)
There are actually more properties (please see source code) but they are not interesting for your example. Anyway after DIV element is dropped, inside myhandler_dropped() you can collect all needed informations and send AJAX request to save position. Of course, request handler will receive feedback of database interaction and that info can be displayed on user interface like “Position saved!”. This is similar case to the WordPress editor when adding new custom fields. You can find AJAX example on my site AJAX progress bar and customize functions for your need.
Hope this informations will help …
Cheers!
I just installed and tweaked your wonderful library at the website listed. I’m having a few problems however, and I don’t know where I’d begin looking. The page is a heavily heavily modified version of example03.
First issue is all the elements from the left div only drag to the right when the right pane is scrolled almost all of the way to the top left of the page. Considering the desired configuaration is rather large, this is very problematic. I noticed example 10 did not have this issue.
Second issue, despite being set to true, the ctrl to clone doesn’t work. I changed your id tags to be single character to reflect the filenames I’m using. I didn’t see how this would affect the cloning ability.
Third issue, my trash stopped working very early, but I think that’s fine since I just set overwrite to true as a workaround.
It would be nice to get rid of the top green line and the green boundary around the images, disabling .green was bad and they got larger and turned black. Setting border:0px has apparently no effect all.
I haven’t modified the Javascript at all, just the sql, php, html, div and css. You have provided excellent examples and documentation, I want to thank very very much for your excellent work. I’ll be happy to contribute my final result as an example for others to use if you are interested. The final results are viewable at http://www.archmageempires.com/maptest/ and http://www.archmageempires.com/maptest/flatmap.php When looking at the second link the strange offsets and weird shapes might make more sense!
I decreased the size of the cells, and now mysteriously I am able to drag anywhere on the table. I tried this same action under 6 different browsers on 3 computers and it didn’t work, but now it does. The CTRL to clone would still be a tremendous blessing. That didn’t work on IE7/8, Chrome (latest) or Firefox (latest). Sorry about double post, I lost internet during a storm and apparently the submit went through while the reply failed.
@Ian – Hi!. Your example is really impressive. I will try to help solving mentioned problems.
1) If you have problem with dragging, try to make DIV id=”drag” visible to be sure that tables are inside DIV.
#drag {
border: 2px solid lime;
}
DIV id=”drag” is region where browser is executing REDIPS.drag code. If table overflows of that region, dragging will not work.
2) to get rid of top green border just place
.green {
border: 0px;
}
3) You don’t need set “true” for autoscrollX and autoscrollY, so delete following lines:
REDIPS.drag.autoscrollX= true;
REDIPS.drag.autoscrollY= true;
4) REDIPS.drag.border is string and there should be quotes:
REDIPS.drag.border = ‘none’;
After you put quotes, CTRL key will start to clone elements. This line has influenced on line below.
You really pushed REDIPS.drag library to the limit and I’m glad it still works. If you have any further questions don’t hesitate to ask.
Kind regards
I am using the 1st example. Because I am not a javascript guru I am having a tough time figuring out which cell I am dragging. Where can I know the contents of the . In each cell I will have a name and ID and as I drop the cell I would like to know the ID of the cell I just moved. Can this be accomplished with an id=”…”?
Thanks,
Evaggelos
@Evaggelos – Yes, you have to assign ID for every DIV element you want to drag. Inside myhandler_dropped() event handler you can access ID of dropped element. Here is how:
Hi,
i am using Nested tables in my HTML page design,Plz help me how to configure the Javascript function to accept the nested table cells for drag functionality.
I have two tables, one without nested table working fine(able to do drag and drop with the table cells), another have nested table which i am not able to drag those cells.
Error while trying to drag the second table cells:
“Microsoft Jscript runtime error: ‘tables[…] offset’ is null or not an object”
Thanks in advance.
HI,
Great job, I’am using the second example and i would be pleased if you tell me : how can I drop any green or orange box in any place of my table, I’am not a professionnal in js and i need an urgent help to overcome that problem. thaks for all
@vaidhy – First you have to define DIV id=”drag”. In initialization phase, REDIPS.drag lib will search for tables inside drag area. Nested tables will be ignored. As I mentioned before, it’s hard to distinguish table as layout from table needed for REDIPS.drag library. Please try to avoid nested tables used for REDIPS.drag as much as you can.
@ARBINOS – Example 2 shows how to create “special” table cells. Orange cell accepts orange elements while green cells accepts green elements. This properties are defined with class names. If you need “clean” table, then remove “mark” from cells class name. “Mark” is special class name and is used for deny access to all DIV elements (exceptions are possible) or to allow access to every element with exceptions. Inside redips2.tar.gz you will find example 0 – simple and clean table without any additional actions.