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!
@Bruce996 – REDIPS.drag is updated and version 4.6.17 is published. Please see example 18 Simple element animation. Two options “clone” and “overwrite” are added in move_object() method. Now is possible to move element, clone element and overwrite content in target cell.
@Ron – Yes, REDIPS.drag will work properly only if browser is switched to the strict mode. Otherwise undefined behaviour (like in your description) may occure. After you have posted comments about your case, I wrote a line about it in REDIPS.drag documentation – Appendix A to prevent similar mistakes in the future.
So, whole library is based on strict mode and unfortunately there is not a way to step back. This is must for a cross-browser compatibility. Quirks mode is not a standard and browsers interprete quirks mode on different way. My suggestion will be to add an effort and migrate HTML to the strict mode. From my experience, after triggering page to the strict mode some (not all) CSS styles will be broken and should be corrected. There should not be so much damage – hope I’m right …
@Bruno Jesus – Your comment makes sense. find_cell() should get cell index from last row and not from the first row. I also fixed code for lastInRow case:
Changes are applied in latest redips2.tar.gz package since 4.6.17 version. Thank you for contributing to REDIPS.drag library. Cheers!
Hi Darko,
thanks again for this amazing plugin.
I’m try to lock the first table header & some left colums and i’ve found this script:
http://www.matts411.com/post/super_tables/.
Do you think is possible to merge your Drag&Drop tool with the over linked tool?
Thanks in advice!!!
Alex
@Alex – Grid tool you mentioned will not work out of the box with the REDIPS.drag library. As I can see it uses z-index to set two layers. After I added DIV element it’s not displayed on the page beacuse it is sent to the back with z-index.
So it’s possible to tweak “Super tables” CSS to make it work with REDIPS.drag. On the other hand you may evaluate the time needed for tweaking Super tables and time needed to make fixed headers on your own way.
;)
Hi Darko,
thanks for the tip. ;)
Nice work on this library!
I am wondering if it is extensible to define specific tables. For example:
Two tables in the same drag container can exchange cell content, but is it possible to define the drag-and-drop parameters for each of those tables? For instance, how would I set drop_option = ‘single’ for one table and drop_option = ‘multiple’ for the other table in the same container/view?
Thank you very much!
Stan
@stan – Yes it’s possible to mix drop option with a little help of event handlers. In a moment when DIV element is moved, “drop option” can be set (depending on table source, DIV contanier or any other rule). Please see example 9 Single and shift mode where singe and shift modes are used. JS code is simple and easy to understand, so I hope it will be a good example to start.
Thank you for pointing this out – yes, I see how this is achieved now. It would be great to be able to initiate each tables’ parameters (where they are different than the set default) using an init function with arguments for each table instead of building that logic into the methods directly, but this solution will do the trick!
Do you have plans on extending the multi-select capabilities? For example:
– click item to select, and use shift-click and control-click to select additional items
– with drop_option as ‘single’, drag multi-selection into an empty cell and drop each item into its own cell following, skipping over cells already filled
Thanks again Darko, this script is incredibly flexible and very friendly to visual customizations!
Cheers,
Stan
@stan – I already have an example with multi select option. Please see example 12 Select and move more elements. Well, it’s not exactly what you asked but the example shows how to select several DIV elements and how to move them to the target cell of dropped DIV element. You can start from this example and build logic for many target cells. It’s a bit tricky to define several target cells especially in a case of single drop option. Script should pick only empty target cells.
Anyway, simple example for “multi-select and move” would be to have two tables with the same dimensions. DIV elements can be freely moved inside table but in moment of moving DIV element to the other table, selected DIV elements can be moved to the same cells in other table …
Please take a look to the example18 Simple element animation also, it might be helpful for your case.
Thanks for using REDIPS.drag library.
Cheers!
Thanks again for the quick reply Darko :)
Hi dbunic, great work!
I need to drop more DIV in a cell table, but I need to manage the order position of each one. I’ve found only the multiple_drop property that allow to put in the top or bottom of list, but nothing that put the DIV in a specified position.
It ‘a solution available that allows this?
Thanks in advance
@perritos – Yes you are right. Order of elements in a table cell can be defined only with multiple_drop option. Dropped DIV element will be placed to the top or to the bottom. There’s no option for placing DIV element to the middle or say to some exact position.
The main power of REDIPS.drag is simplicity in “dropping layout” creation. Tables are simple – TR/TD elements with applying styles can result with really different looks.
So, maybe you can use nested tables. Inside cell place another table if DIV order is important. This is just an idea (or workaround) that might help for your case.
Hi,
insanely awesome app! Wondering if someone can help me with clone and retaining property. For example I have:
on the CSS I have:
However when I drag this to the target cell, although it clone the text it did not retain the property (ie the yellow background goes away).
Probably a simple overlook by me but can someone help!
thanks in advance.
Alex
Hi thanks for the Greet script, however I found that in the exemple 23 concerning the save to database, the max length for elements is 3, even if you change the redips.code_length to another value it still always be 3.
So is there a solution to pass for exemple value like 10000 or any thigns that is bigger than 3 digits
Hi and thanks for this script. I think it will help me with a project. But I need help in understanding how I can save it to MySQL. How should the query be written?
Thanks,
Chris
Hi ,
I think i am at right place to fulfill my actual requirement, Can any solve my problem. Please see below list of points.
1. Initially am have the input fields on the left/right side. On drag and drop on any table the fields will be displayed and width and height of the fields will change some time I have to place the Rich Control also,
Can any please help me.
Great code!! I used it to develop a “Gantt Like” application, and so far so good. I added a left arrow and right arrow to each side of every drag, in order to grow or shrink each “task” (changing the TD’s rowspan dinamically). I am now working on allowing this same feature but using resizable from Jquery UI. Any ideas on this?
Thank you very much.
Great product just having a little problem, maybe I am missing something.
I have 2 tables and can drag and drop cell content within each one and also between them.
I am also able to drag and drop rows within each table, I can also drag and drop rows between tables.
My question is how can I switch off the dragging and dropping of rows between the tables while keeping this functionality in each.
Many thanks
I saved my database to the original position as well as a drag show in the first place