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!
Thanks for this awesome work ! Help me out a lot for a project. Maybe I’ll have some questions afterwards :)
Hi ! As announced, I have some questions :) I experience a strange problem with my table which have 13 columns. It works like a charm on my windows 7 with chrome. I can drag and drop from any cell. But on my ipad, I can only drag and drop on the 6 first columns. When I move an element over the 7 last column, there is no highlight of the cells and I cannot drop my elements. Did you already hear about a problem of this kind ? Thanks in advance.
@Amull – Maybe the problem is related to drag container. Please make drag container visible with following CSS style:
If drag container ends at 7th column in case of iPad, then it will not be possible to drop DIV element to column 8, 9, 10 … So, the fix is to expand drag container (if it has fixed width, height) or to make it self expandable with:
Hope this will solve your problem.
Problem solved :) Thanks again for your excellent work !
how to recall in example 24. thanks.
@Amull – I’m glad your problem is solved! ;)
@Marcelo – When you click on “Save” button on example24 demo, it will display JSON result. Instead of displaying, you should point output from save function to your server side script to accept information and save to database. Once you will have saving to database working, you can modify index page to be generated with PHP, ASPX, JSP … The principle is the same as is in example03. Please peek to example03/index.php to see how HTML table is created with PHP code.
It’s great work.
I have a question – Can I move/copy content from one table to another ?
Sorry, I mean can we do post-back after drag & drop action to update data in Database ?
@phuc – Yes you can. REDIPS.drag lib has many event handlers where you can place custom JS code (like saving to database). All event handlers are described in documentation. Example3 School timetable is demo with option to save table content to database. Just download redips2.tar.gz package to see complete source. Inside example03 directory you will find directory named “ajax”. There is placed modification to save each DIV element after dropping to table. Before “playing” with this demo, you will have to create two MySQL tables – all instructions are in docs/readme.txt file.
Thanks so much, dbunic.
Hi, it’s me again (sorry to disturb you). I have another question. I would like to drag 2 cells at the same time. I have 2 similar div side by side in 2 cells. I would like to drag those 2 divs at the same time when I’am dragging one of them. Is it possible or maybe do you have an example already made ?
THX a lot !
@Amull – Unfortunately, REDIPS.drag library doesn’t have option to drag two DIV elements at the same time. However, it’s possible to move other DIV element after first one is dropped to the table. Please see example12 Select and move more elements. In script.js file you will see event.dropped() handler and REDIPS.moveObject() method. In short, after DIV element is dropped to the table, code will search for other checked DIV elements and with moveObject() they will be moved to the destination cell. Hope this example will be helpful for your case.
Thx, I use moveObject in droppedBefore and it does the trick !! Thx a lot again :)
Hi dbunic,
I have been using your library for a few months now and while most things have been very easy I am having problems when dragging cells within a table when the table extends horizontally outside of the screen size. In these cases the cells which are initially visible on the screen behave perfectly. Any to the right of them remain draggable but the cells do not highlight for dropping and the bahaviour becomes unpredictable, often it is not possible to drop the cells anywhere other than their original location or on one of the initially visible cells. I assume this is to do with calculating the scroll position but I was wondering if you had encountered this, and even found the way around it.
Today I updated from 4.7.3 to the latest version in the hope that it would help but the same behaviour continues.
I fixed this using examples 4 and 5, it now works perfectly.
@dbunic – fantastic job with the drag and drop, very easy to implement. I have a question, can I have multiple <div id=”drag”> on one page. The reason I ask, is I am combining the drag and drop table with a tab control (using twitter bootstrap). Where one table is related to one tab and the other table is related to another tab. every <div> has a unique id. It works beautifully for the first tab and then when I go to the second tab the table draws correctly, when I hover over a div I get the crosshairs cursor, but when I try to drag it just selects the cells.
Any help would be greatly appreciated!
@Cat – I’m glad your problem is solved.
@Al – Yes, page can contain several drag containers – but they will act as totally separated (means, that DIV elements from first drag container can not be dropped to the second or vice verse). Please see example08 “Tables in separated containers” on preview page (link is below post title).
Great Work.Thanks a lot.Searching for something like this for quite a while and got it here.Just one query…how would go about, if you were to change the database entries of subjects placing, instantly in database just after dragging and dropping and not by clicking the submit button of SAVE.(in example 3-time table).
@ankit – In example03/ajax folder you will find scripts to modify save logic. In readme.txt file is described simple change procedure. Anyway, after changing few lines, example03 will save each DIV element drop via AJAX. Cheers!
@dbunic – If I add anything to the end of the id=drag div the table becomes “un dragable” does something need to change in the css or the js? I can send you access to the link for you to take a look if you like.
Thanks,
Al