Drag and Drop table content with JavaScript

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 destination cell. Attaching onMouseOver handler on TD elements will not work, because browser doesn’t fire events to the elements beneath 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 Version 5.2.4 redips2.tar.gz


REDIPS.drag example01

“Save” button will scan table content, create query string and send to the 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 the 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:

  • functions and data structure are defined in namespace (easier integration with other JS frameworks)
  • JSLint: No problems found in redips-drag-source.js (tough one, huh)
  • 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)
  • 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 (167KB) package you will find 28 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!

1,108 thoughts on “Drag and Drop table content with JavaScript

  1. Hi Darko , your advice was very useful. It was just what I wanted ! Best regards, Lubo

  2. @Jas – Please try to set example03 (AJAX version) where every drag-n-drop or delete is saved to database. If you have MySQL/PHP skills then preparing local Web server should be simple and easy. All instructions are written in readme.txt files.

    @Lubo – I’m glad that it fixed the problem.

    Cheers!

  3. OMG… Absolutely stellar library and examples. I have a request/question… I am trying to build a webpage where I have elements with an employees image, their name and title. How can I have all three elements in one single box that is draggable. When I try and build it, the image can be dragged separately, but I need the entire div treated as one element and draggable.

    Thanks in Advance!
    Cheers,
    JeffreyJ

  4. @JeffreyJ – All HTML code placed inside DIV should behave as one drag-able element. Please try to modify example01 and instead of:

    <div id="d8" class="redips-drag t1">
    <img id="smile_img" src="icon_smile.gif"/>
    </div>
    

    … place the following code:

    <div id="d8" class="redips-drag t1">
    <img id="smile_img" src="icon_smile.gif"/>
    <br/>
    Some text
    </div>
    

    Smile image and text written in the line below should move together.

  5. Excuse me. I have a problem.
    I what to drag images which i use bootstrap img-responsive on it.
    When I drag the image , it lose it responsive size and back to original size .
    i want to ask for how to solve this problem.

    Thanks .

  6. Hi, would like to check with you..

    For example 24
    1. Why the dragged item become “Error”?
    2. How can i add a col too?
    3. How to delete the dragged item if i accidentally drag something i dont want into the table?

    For example 1
    1. When i try to modified the table, i realize that the table 3 is a must, im trying to combine table 3 and 1, so the “Trash” button can go with table 1. but the program messed up and drag and drop does not works anymore. Is there anyway i can do so?

    Last but not least, you did mentioned this “initialize REDIPS.drag library: ” in your post.
    can i know where exactly this should be initialized? As i cannt find in your index.html code.

  7. Hi, is i possible to revert the performed drag operation after the backround ajax failed?

    Couldn’t find it in the docs.

  8. It’s possible to return “false” from event.droppedBefore() and in this case, dropped DIV element will be returned to source location.

    Cheers

Leave a Comment