Table Drag and Drop JQuery plugin




I’ve been using JQuery for a while now and really agree with its tag line that it’s the “The Write Less, Do More, JavaScript Library”. We’ve also got this code for dragging and dropping table rows that has proved very popular, so it seemed natural to combine the two and wrap up the table drag and drop as a JQuery plugin.

Why have another plugin?

Dragging and dropping rows within a table can’t be handled by general purpose drag and drop utilities for a number of reasons, not least because you need to move the whole row, not just the cell that receives the mouse events. Re-parenting the row also requires specific code. Sadly also, effects like fadeIn and fadeOut don’t work well with table rows on all browsers, so we have to go for simpler effects.

What does it do?

This TableDnD plugin allows the user to reorder rows within a table, for example if they represent an ordered list (tasks by priority for example). Individual rows can be marked as non-draggable and/or non-droppable (so other rows can’t be dropped onto them). Rows can have as many cells as necessary and the cells can contain form elements.

How do I use it?

  1. Download Download jQuery (version 1.2 or above), then the TableDnD plugin from GitHub (current version 0.6).
  2. Reference both scripts in your HTML page in the normal way.
  3. In true jQuery style, the typical way to initialise the tabes is in the $(document).ready function. Use a selector to select your table and then call tableDnD(). You can optionally specify a set of properties (described below).
1 One some text
2 Two some text
3 Three some text
4 Four some text
5 Five some text
6 Six some text

The HTML for the table is very straight forward (no Javascript, pure HTML):

<table id="table-1" cellspacing="0" cellpadding="2">
    <tr id="1"><td>1</td><td>One</td><td>some text</td></tr>
    <tr id="2"><td>2</td><td>Two</td><td>some text</td></tr>
    <tr id="3"><td>3</td><td>Three</td><td>some text</td></tr>
    <tr id="4"><td>4</td><td>Four</td><td>some text</td></tr>
    <tr id="5"><td>5</td><td>Five</td><td>some text</td></tr>
    <tr id="6"><td>6</td><td>Six</td><td>some text</td></tr>
</table>

To add in the “draggability” all we need to do is add a line to the $(document).ready(...) function
as follows:

<script type="text/javascript">
$(document).ready(function() {
    // Initialise the table
    $("#table-1").tableDnD();
});
</script>

In the example above we’re not setting any parameters at all so we get the default settings. There are a number
of parameters you can set in order to control the look and feel of the table and also to add custom behaviour
on drag or on drop. The parameters are specified as a map in the usual way and are described below:

onDragStyle
This is the style that is assigned to the row during drag. There are limitations to the styles that can be
associated with a row (such as you can’t assign a border—well you can, but it won’t be
displayed). (So instead consider using onDragClass.) The CSS style to apply is specified as
a map (as used in the jQuery css(...) function).
onDropStyle
This is the style that is assigned to the row when it is dropped. As for onDragStyle, there are limitations
to what you can do. Also this replaces the original style, so again consider using onDragClass which
is simply added and then removed on drop.
onDragClass
This class is added for the duration of the drag and then removed when the row is dropped. It is more
flexible than using onDragStyle since it can be inherited by the row cells and other content. The default
is class is tDnD_whileDrag. So to use the default, simply customise this CSS class in your
stylesheet.
onDrop
Pass a function that will be called when the row is dropped. The function takes 2 parameters: the table
and the row that was dropped. You can work out the new order of the rows by using
table.tBodies[0].rows.
onDragStart
Pass a function that will be called when the user starts dragging. The function takes 2 parameters: the
table and the row which the user has started to drag.
scrollAmount
This is the number of pixels to scroll if the user moves the mouse cursor to the top or bottom of the
window. The page should automatically scroll up or down as appropriate (tested in IE6, IE7, Safari, FF2,
FF3 beta)

This second table has has an onDrop function applied as well as an onDragClass. The javascript to set this up is
as follows:

$(document).ready(function() {

	// Initialise the first table (as before)
	$("#table-1").tableDnD();

	// Make a nice striped effect on the table
	$("#table-2 tr:even').addClass('alt')");

	// Initialise the second table specifying a dragClass and an onDrop function that will display an alert
	$("#table-2").tableDnD({
	    onDragClass: "myDragClass",
	    onDrop: function(table, row) {
            var rows = table.tBodies[0].rows;
            var debugStr = "Row dropped was "+row.id+". New order: ";
            for (var i=0; i<rows.length; i++) {
                debugStr += rows[i].id+" ";
            }
	        $(#debugArea).html(debugStr);
	    },
		onDragStart: function(table, row) {
			$(#debugArea).html("Started dragging row "+row.id);
		}
	});
});
 
1 One
2 Two
3 Three
4 Four
5 Five
6 Six
7 Seven
8 Eight
9 Nine
10 Ten
11 Eleven
12 Twelve
13 Thirteen
14 Fourteen

What to do afterwards?

Generally once the user has dropped a row, you need to inform the server of the new order. To do this, we’ve
added a method called serialise(). It takes no parameters but knows the current table from the
context. The method returns a string of the form tableId[]=rowId1&tableId[]=rowId2&tableId[]=rowId3...
You can then use this as part of an Ajax load.

This third table demonstrates calling the serialise function inside onDrop (as shown below). It also
demonstrates the “nodrop” class on row 3 and “nodrag” class on row 5, so you can’t pick up row 5 and
you can’t drop any row on row 3 (but you can drag it).

    $('#table-3').tableDnD({
        onDrop: function(table, row) {
            alert($.tableDnD.serialize());
        }
    });

Ajax result

Drag and drop in this table to test out serialise and using JQuery.load()

1 One
2 Two
3 Three (Can’t drop on this row)
4 Four
5 Five (Can’t drag this row)
6 Six

This table has multiple TBODYs. The functionality isn’t quite working properly. You can only drag the rows inside their
own TBODY, you can’t drag them outside it. Now this might or might not be what you want, but unfortunately if you then drop a row outside its TBODY you get a Javascript error because inserting after a sibling doesn’t work. This will be fixed in the next version. The header rows all have the classes “nodrop” and “nodrag” so that they can’t be dragged or dropped on.

H1 H2 H3
4.1 One
4.2 Two
4.3 Three
4.4 Four
4.5 Five
4.6 Six
H1 H2 H3
5.1 One
5.2 Two
5.3 Three
5.4 Four
5.5 Five
5.6 Six
H1 H2 H3
6.1 One
6.2 Two
6.3 Three
6.4 Four
6.5 Five
6.6 Six

The following table demonstrates the use of the default regular expression. The rows have IDs of the
form table5-row-1, table5-row-2, etc., but the regular expression is /[^\-]*$/ (this is the same
as used in the NestedSortable plugin for consistency).
This removes everything before and including the last hyphen, so the serialised string just has 1, 2, 3 etc.
You can replace the regular expression by setting the serializeRegexp option, you can also just set it
to null to stop this behaviour.

    $('#table-5').tableDnD({
        onDrop: function(table, row) {
            alert($('#table-5').tableDnDSerialize());
        },
        dragHandle: "dragHandle"
    });
  1 One some text
  2 Two some text
  3 Three some text
  4 Four some text
  5 Five some text
  6 Six some text

In fact you will notice that I have also set the dragHandle on this table. This has two effects: firstly only
the cell with the drag handle class is draggable and secondly it doesn’t automatically add the cursor: move
style to the row (or the drag handle cell), so you are responsible for setting up the style as you see fit.

Here I’ve actually added an extra effect which adds a background image to the first cell in the row whenever
you enter it using the jQuery hover function as follows:

    $("#table-5 tr").hover(function() {
          $(this.cells[0]).addClass('showDragHandle');
    }, function() {
          $(this.cells[0]).removeClass('showDragHandle');
    });

This provides a better visualisation of what you can do to the row and where you need to go to drag it (I hope).

Version History

0.2 2008-02-20 First public release
0.3 2008-02-27 Added onDragStart option
Made the scroll amount configurable (default is 5 as before)
0.4 2008-03-28 Fixed the scrollAmount so that if you set this to zero then it switches off this functionality
Fixed the auto-scrolling in IE6 thanks to Phil
Changed the NoDrop attribute to the class “nodrop” (so any row with this class won’t allow dropping)
Changed the NoDrag attribute to the class “nodrag” (so any row with this class can’t be dragged)
Added support for multiple TBODYs–though it’s still not perfect
Added onAllowDrop to allow the developer to customise this behaviour
Added a serialize() method to return the order of the rows in a form suitable for POSTing back to the server
0.5 2008-07-11 Now supports having a column as a drag handle (specify a class for the dragHandle option when configuring).

Improved the serialize method to use a default (but also settable in the options) regular expression for generating the serialized string. The default is /[^\-]*$/ which will remove everything before a final hyphen, so item-s1 becomes s1.

Added $(‘…’).tableDnDUpdate() to cause the table to update its rows so the drag and drop functionality works if, for example, you’ve added a row.

Added $(‘…’).tableDnDSerialize() which allows you to serialize a table from any javascript code.

Removed remaining $ and replaced with jQuery so that it should work with Prototype and Scriptaculous

Tags: , , ,

727 Responses to “Table Drag and Drop JQuery plugin”

  1. unleashed says:

    I apologize if this has been covered in the previous 6xx comments but I didn’t see it.
    Is there a way to make it autoscroll a DIV (that the table is in with overflow) rather than the window?
    Thanks!

  2. unleashed says:

    Please ignore the comment above – I did manage to find in previous comments that it had been covered and a solution posted.

    Got another question though :)

    I am creating my table via javascript (html strings) so the table that I to be DnD isn’t there on document load. The pure js solution for the Table Drag and Drop works fine for this but I can’t get this jquery approach to – no errors, the table just isn’t drag and drop. Any ideas? I need to call the $(“#table-1″).tableDnD(); portion in the js code behind.

    • Chaubey says:

      Hi Unleashed,

      Could you please let us know the solution you have implemented for
      Is there a way to make it autoscroll a DIV (that the table is in with overflow) rather than the window?

      Thanks in Advance…

  3. masoud says:

    :D hooooorrraaa
    i discoverd the Problem
    tableDnD will be work by all version of jquery by a little changes :D
    jquery 1.4 has problem with load Command. that`s enough to change with a ajax Command
    Change this:
    $(‘#AjaxResult’).load(“index.php?”+$.tableDnD.serialize());
    to:
    $.ajax({
    type: “GET”,
    url: “index.php?”+$.tableDnD.serialize()
    })

  4. Kyle says:

    This plugin is absolutely excellent. Integration was literally a single line of code. It does exactly what I needed. Thank you!

  5. barat says:

    Nice plugin – that’s what i’m looking for :)
    For Node was not found” code: “8″ when over just add nodrag and nodrop class for in ;)

    I made one improvement – mousemoveCallback option

    In lines ~96-105 (doesn’t mather where – just another option on list) just add an option:

    mousemoveCallback: function(){},

    Then in line ~230 or lower (it must be UNDER var config = jQuery.tableDnD.currentTable.tableDnDConfig;) add:
    //callback
    config.mousemoveCallback.call(this);

    Now I can use script for numering rows, and refresh it each time when I move a row :)

  6. Wil says:

    I ran into an issue that I’ve seen posted on, and worked it out. After initialization, adding rows to the drag and drop table caused my application to crash. I encapsulated the initialization code in a function, and called that whenever a new row was added to the table – this wasn’t the problem. The problem was that my table did not have a ‘tbody’ section. I was adding the new row to the table element, but when I looked at the resulting html, I saw that the table contained a tbody element that must have been automatically added, and then added the new row outside that section. So, to fix the issue, I added a tbody section to my table and appended the new row to the tbody section. Then the dynamically added rows worked great.

  7. Artem says:

    Is it possible to implement with the help of this plug-dragging multiple rows?
    For example, the user selects the necessary line (clicked on the checkboxes) and then drags them.

  8. Kaboozy says:

    Hello, i don’t know if semeone can help, I’m adding row dynamically and remove them too, but after I add one the new row wont move in the table.
    Do I have to reset the plugin or myabe add the new culom

  9. Kaboozy says:

    i didnt mean column but row, sorry

  10. Tamar Cohen says:

    TableDnD does not respect nodrag / nodrop when resorting dropped items

    Situation: I have a table with n rows, some of which are “locked”. Rows which are locked should not be draggable nor should they allow drops. I have set class=”nodrag nodrop” and added onAllowDrop: function(draggee, droppee){

    return (!isLocked(droppee.id));

    },

    to tableDnD().

    If my locked items are something like this:

    1 a
    2 b
    3 c LOCKED
    4 d
    5 e

    when I go to drag for example row 4 to row 2, the “shuffling down” action will change the contents of row 3 so I will get:

    1 a
    2 d
    3 b LOCKED
    4 c
    5 e

    so as you see row 3 is changed via the “shuffling down”, which seems to be caused from the mousemove method, by the parentNode.insertBefore method: if (movingDown && jQuery.tableDnD.dragObject != currentRow) {

    jQuery.tableDnD.dragObject.parentNode.insertBefore(jQuery.tableDnD.dragObject, currentRow.nextSibling);

    } else if (! movingDown && jQuery.tableDnD.dragObject != currentRow) {

    jQuery.tableDnD.dragObject.parentNode.insertBefore(jQuery.tableDnD.dragObject, currentRow);

    }

    This does not take into account the nodrag/nodrop “locked” state of various table rows.

    • Raymond Sugel Sr says:

      Was wondering if you ever found a solution to this. I have a similar situation. I’m using the tableDnD in a quiz interaction (match definitions to terms). Once the user sorts the list of definitions and submits it for validation, I want to dynamically lock correct responses and only allow them to interact with incorrect responses on their next attempt. I’ve tried doing a .addClass of “no drag no drop” to the correct responses and then calling tableDnDUpdate, but that’s not working at all.

  11. Naresh says:

    I am getting the javascript erro as it is not able to recoznise the method in the js file tableDnD. I am working on windows.

  12. Ryan says:

    If you only care about the order for submission to a script, update a hidden element in the form and process upon submission server-side:

    $("#dragtable").tableDnD({
        onDrop: function(table, row) {
            var orderStr;
            var rows = table.tBodies[0].rows;
            for (var i=0; i<rows.length; i++) {
                    orderStr += rows[i].id+",";
                }
            $('#order').val(orderStr);
           }
      });
    

    Then you just drop a hidden element in and it will put the csv order list in its value:

    <input type='hidden' name='order' id='order' value=''>

  13. D says:

    I have implemented drag and drop feature in jquery in my prototyping development,It’s working fine but now I’m developing java project.If I drag and drop any row and change its position (say 1st and 2nd row if I interchange) and need to save the position as well as data of updated interchanged row in database,can it be possible?please reply ….

    • D says:

      JSP – make an ajax call that would post the current sequence of the rows based on the primary key (id)

      Servlet – write a method that would update the sequence in the db

      sqlquery – from tablename where active ORDER BY sequence asc

      • DenisH says:

        HI @D,

        I haven’t got the different examples you’re asking for, but you can indeed use Ajax to tell the server the new result.

        Here’s the code I use for Table 3 above that does the serialising to an Alert and also to the PHP server:

            $('#table-3').tableDnD({
                onDrop: function(table, row) {
                    alert("Result of $.tableDnD.serialise() is "+$.tableDnD.serialize());
                    $('#AjaxResult').load("/articles/ajaxTest.php?"+$.tableDnD.serialize());
                }
            });
        

        Here’s the PHP snippet that parses the serialised version of the table

        <?php
        $result = $_REQUEST["table-3"];
        foreach($result as $value) {
        	echo "$value<br/>";
        }
        ?>
        

        Once you’ve got the data server-side, it’s easy to store it away in a database or whatever.

  14. D says:

    Thanks for the plugin …. today i worked with this plugin. i have a header row in my table and im able to drag my row to the top above the header, how can i stop that .. from going above the header

    • DenisH says:

      Hi again, D, you can use TBODYs to demarcate where you want to allow dragging. So for example in table 4, there are multiple tbodys and you can only drag within the “home” tbody. This is how the HTML looks:

      <table id="table-4" cellspacing="0" cellpadding="2">
          <tbody>
              <tr id="4.0" class="nodrop nodrag"><th>H1</th><th>H2</th><th>H3</th></tr>
              <tr id="4.1"><td>4.1</td><td>One</td><td></td></tr>
              <tr id="4.2"><td>4.2</td><td>Two</td><td></td></tr>
          </tbody>
          <tbody>
              <tr id="5.0" class="nodrop nodrag"><th>H1</th><th>H2</th><th>H3</th></tr>
              <tr id="5.1"><td>5.1</td><td>One</td><td></td></tr>
              <tr id="5.2"><td>5.2</td><td>Two</td><td></td></tr>
              <tr id="5.3"><td>5.3</td><td>Three</td><td></td></tr>
          </tbody>
      </table>
      
      • DenisH says:

        This also works:

        <table id="table-4" cellspacing="0" cellpadding="2">
            <thead>
                <tr id="4.0" class="nodrop nodrag"><th>H1</th><th>H2</th></tr>
            </thead>
            <tbody>
                <tr id="4.1"><td>4.1</td><td>One</td></tr>
                <tr id="4.2"><td>4.2</td><td>Two</td></tr>
            </tbody>
        </table>
        
        • D says:

          works now .. thanks !!!

        • alejandro says:

          Thanks for the plugin!

          I have dynamically created the same format as you listed, (thead with one header row, tbody with data rows) and marked the header row with nodrag and nodrop, but I get an (invalid argument fwiw) error when dragging a row onto the header row. (using jquery 1.4 and DnD 0.5)

          My aim is to prevent rows from being dragged above the header row..

  15. JM says:

    Great Script !!! Here is the challenge I face: In some cases the default order of a table is correct without dragging and dropping. How can I serialize and assign a value to a hidden
    field if there is no onDrop event to trigger the serialization ? An onSubmit would be great !!!
    thx.

  16. jagadeesh says:

    great plugin and great support. worked with this plugin and saved that order in database. please provide db code also to save sorted order. it will be helpful for others.i have done that in java. thanks for plugin

  17. Alexasndr says:

    Hi, please tell me how i can submit this:
    $(document).ready(function() {
    $(“table”).tableDnD();
    $(‘table’).tableDnD({
    onDrop: function(table, row) {
    alert($(‘table’).tableDnDSerialize());
    },
    dragHandle: “dragHandle”
    });

    });

    1Onesome text
    2Twosome text
    3Threesome text
    4Foursome text
    5Fivesome text
    6Sixsome text

    —————————–

    Thank you.

  18. Alexasndr says:

    $(document).ready(function() {
    $("table").tableDnD();
    $('table').tableDnD({
    onDrop: function(table, row) {
    alert($('table').tableDnDSerialize());
    },
    dragHandle: "dragHandle"
    });

    });

    1Onesome text
    2Twosome text
    3Threesome text
    4Foursome text
    5Fivesome text
    6Sixsome text

  19. Eric says:

    Is there a way to make scrollAmount work for a table that is in a div that scrolls when the height of the div is greater than 300px?

    Thanks! :)

  20. JonoB says:

    Really awesome, thank you! One request that I have: is it possible to show a placeholder for the row being dragged? Like http://jqueryui.com/demos/sortable/#placeholder

  21. Steve J says:

    Great script, but I think I might have found a bug. When a drag handle is defined, the onDrop method receives a cell object, instead of a row. I think line 135 needs to be:config.onDragStart(table, this.parentNode);

  22. Steve J says:

    One other thing… if I dynamically add a row to the table, how do I make the new row sortable?

    • Steve J says:

      Never mind… $(“#my_table”).tableDnDUpdate(); takes care of new rows. As for my “Bug” report – returning a “cell” object might be intentional in case there are multiple drag handles. I didn’t see it in the documentation though.

  23. Sat says:

    Hi,

    Wanted to know how to move rows between 2 tables. Any help is greatly appreciated.

  24. mahantesh says:

    is it any option to drag n drop between cells in table

  25. nathanh says:

    I’d like to temporarily disable all the table rows draggability until my .php is finished running. Any ideas?

    I’ve tried using jQuery to change the class of the rows to nodrag when a row is dropped and then remove that class after the php is finished but it had no effect.

  26. scrupply says:

    How would I post this data to the database? I am using PHP and MySQL. I can pull the data from the database and display it in the table, but I cannot figure out how to post it back to the database with the updates. Any help would be great. Thank you for this, the drag and drop work really well.

  27. MIchaleKing says:

    How to it work with IE ? Thank

  28. James Moberg says:

    To block user interaction while updating via ajax, you could use BlockUI:
    http://jquery.malsup.com/block/

  29. Dirk2099 says:

    I keep getting this error:

    TypeError: Cannot call method ‘makeDraggable’ of undefined [http://blahblah/scripts/jquery.tablednd_0_5.js:

    Any help would be appreciated. thank you

  30. Rolle says:

    Thanks for this plug-in! Woks great! Especially thanks also to the comments made by people…you should do a FAQ or something of the comments questions/answers. :-)

  31. hakkatil says:

    Thank you. It works great. Saved lots of time.

  32. Andrew says:

    Great plugin. I have a question though. I’m trying to implement this with Richfaces 3.3.1 and it works with my datatable. However, if I load the page and one of the cells in the datatable has a h:graphicImage with a4j:support. When I click on this image, the java code on the server is executed and the datatable is rerendered, but the row drag and drop functionality no longer works.

  33. Edd says:

    ENABLE AND DISABLE THE PLUGIN (A SOLUTION)

    Hi. I’m pretty new to jQuery so I’m almost sure this is a very very messy solution, but it works – at least in my case it does. Hope it helps!

    jQuery.tableDnD = {
    
        // previous code  ...
    
        /* ADD THIS (don't forget the ',' after the previous function */
        removeDraggable: function(table) {
            var config = table.tableDnDConfig;
    		if (table.tableDnDConfig.dragHandle) {
    			var cells = jQuery("td."+table.tableDnDConfig.dragHandle, table);
    			cells.each(function() {
    				jQuery(this).addClass("resetable nodrag nodrop");
    			})
    		} else {
    	        var rows = jQuery("tr", table);
    	        rows.each(function() {
    				var row = jQuery(this);
    				row.addClass("resetable nodrag nodrop"); // added the 'resetable' class so that the code does not break the 'nodrag nodrop' on the original code - ex: if you initiate your table with some 'nodrag' rows ( see the clearTable() function )
    				row.mousedown(function(ev){
    					return false;
    				}).css("cursor", "");
    			});
    		}
    	},
    
    	detachPlugin: function(){
    		 var result = "";
            this.each(function() {
    			// this is now bound to each matching table
    			result += jQuery.tableDnD.removeDraggable(this);
    		});
            return result;
    	},
    
    	clearTable: function(table){
    		var rows = jQuery("tr", table); // get all the rows as a wrapped set
    	        rows.each(function() {
    				// Iterate through each row, the row is bound to "this"
    				var row = jQuery(this);
    				if (row.hasClass("resetable")) {
    	                row.removeClass("resetable nodrag nodrop");
    				}
    			});
    	},
    
    	clearTables: function(){
    		var result = "";
            this.each(function() {
    			// this is now bound to each matching table
    			result += jQuery.tableDnD.clearTable(this);
    		});
            return result;
    	}
    }
    
    jQuery.fn.extend(
    	{
    		tableDnD : jQuery.tableDnD.build,
    		tableDnDUpdate : jQuery.tableDnD.updateTables,
    		tableDnDSerialize: jQuery.tableDnD.serializeTables,
    
                    /* ADD THIS */
                    removeTableDnD: jQuery.tableDnD.detachPlugin,
    		clearTableDnD: jQuery.tableDnD.clearTables
    	}
    );
    
    ** HTML ******************************************************
    
    var update = function(){
    	var order = $('#list').tableDnDSerialize() + '&action=updateRecordsListings';
    	$.post("updateTableOrder.php", order, function(theResponse){
    		$("#responseDiv").html(theResponse);
    		disableSorting();
    	});
    	return false;
    }
    
    var enableSorting = function(){
    	$("#list").clearTableDnD();
    	$("#list").tableDnD();
    }
    
    var disableSorting = function(){
        $('#list').removeTableDnD();
    	$("#list").tableDnDUpdate();
    }
    
  34. Tom says:

    For some reason this plugin break when I specify a dragHandle value.
    It works fine without it, but it kinda makes it annoying to use as I have checkboxes in rows and they’re kinda fiddly to click when the entire row can be dragged – sometimes you end up reordering rows instead of clicking the checkbox…

    The error I get is “htmlfile: Invalid argument” on this line:
    jQuery.tableDnD.dragObject.parentNode.insertBefore(jQuery.tableDnD.dragObject, currentRow);

  35. Dmitry Dzygin says:

    Thanks, got it working in no time

  36. Harsh says:

    Great plugin! I have a question though..when you drop a row how do you know the id of the row on which the row is being dropped. eg, I’m dropping
    row 10 on to row 3. How do I know it’s row 3 ? Is there any property I can use? Thanks!

  37. jp says:

    Is there a way to persist the table row order so that if a round trip to and from the server occurs, the row order is preserved?

    Is that the purpose of tableDnD.serialize( )? If so, how do I use that to preserve row order?

    Thanks in advance.

    JP

  38. Atinux says:

    Thanks a lot !
    It works perfectly :)

    Great work !!!

  39. Zesha says:

    AWESOME !.. Thank you soo much, A nice plugin.

  40. Chico says:

    Hello, you made a great plugin.

    but, not everyone likes to use method GET, im one of them. hahaha.

    so, if possible i wanna share a simple function that i build to put the items order in array.

    toObject: function (){
    		var ret = {}; //Object that will contain all elements
    		$(this).find('tr').each(function(key, value){ // jQuery each, that will find all trs inside a table and get the id and position
    			ret[key] = value.id; //Array Key will contain the id of tr     LIKE    ret[0] = 22;
    		});
    		return ret; //Return the Object
    	}
    

    and one more PHP function that help you to update your MySQL table with the new order.

    $cases = '';  // this string will contain the ID and POSITION
    $ids = '';     // this string will contain all IDs
    foreach($_POST['neworder'] as $k => $v){ // Foreach to get all entries
    	$cases .= ' WHEN ' . $v . ' THEN ' . $k; //Concat String with the case
    	$ids .= $v . ', ';                                  //Concat String with the ID
    }
    //build QUERY
    $query = ('UPDATE conceitos SET ordem = CASE cd_conceito' . $cases . ' END WHERE cd_conceito IN (' . substr($ids, 0, -2) . ')');
    
    // i use the PHP Substr FUNCTION, to remove the last espace and comma, because it will give a mysql error.
    

    I Hope help somebody.

    Thanks in advanced.

  41. Ruben says:

    I’m having problems with a form that’s inside the table. When i move a row, the input fields on that row cannot be found by PHP while processing the form…

    How do i solve that?

  42. Erti-Chris Eelmaa says:

    Has anyone ideas? Ive used TinyMCE, jQuery and this table drag plugin, however I cant get it to work.

    See source here => http://codepad.org/riSBwIjA
    what happens if I drag one TinyMCE from one cell to another, the ‘IFrame’ element of TinyMCE disappears, eg the content disappears.

  43. AndrewS says:

    Great script!

  44. Drz says:

    Is there a way to include a delay when the button is pressed before starting the drag? It seems that the onDrop event fires all the time for me even if I just click a row and not move anything.

    Thanks.

    • TommyHot says:

      I made a workaround for this:

      $(document).ready(function(){
      	var data1 = '';
      	// Initialise the table
      	$("#product-table").tableDnD({
      		onDragClass: "dragged",
      		onDragStart: function(table, row) {
      			data1 = $.tableDnD.serialize();
      		},
      		onDrop: function(table, row) {
      			var data2 = $.tableDnD.serialize();
      
      			if(data1 != data2)
      			{
      				$.post('discount/position', data1, function(data) {
      				});
      			}
              },
          });
      });
      

      See the data1, data2 variables.. I’m serializing data, when I start dragging a row and serialize data when dropping a row. Then I just compare those 2 variables and if they don’t match I know position of table row has changed.

  45. Vic says:

    would someone kindly show me an example of using the method $ (“table”). tableDnDUpdate (); with PivotTables generated by querying a database. thanks

  46. Can the author of this article or anybody who has a copy please send me an email of the “PHP Source” above? I can’t seem to see it. Much thanks!

  47. Anton says:

    By the way, if you have a header row and you don’t want items to drop on this row, but still preserve the style of your header, then use this with your existing class (in my case its ‘HeaderStyle’):
    in ASP.NET: e.Row.CssClass = “nodrop HeaderStyle”
    in html: class=”nodrop HeaderStyle”

    Again, great plugin! Thanks.

  48. Sara says:

    This plug-in is fantastic. However, I added one thing. It may have been addressed earlier in the comments, but I noticed some javascript errors if your mouse drifts on the header row when you drop a row into the first position. I handled this by wrapping the offending line (line #275) in a try/catch.

    try {
    jQuery.tableDnD.dragObject.parentNode.insertBefore(jQuery.tableDnD.dragObject, currentRow);
    }
    catch (e) {

    }

  49. Jim says:

    This is awesome, the level of collaboration around the use of the jQuery libraries never ceases to amaze me!!
    I have one follow up question, has anyone come with with a solution that allows drag / drop and server update for a paginated list of elements?
    My requirement is to have a fairly large list, maybe up to 500 elements, that can be drag and drop reordered, but sorted across pages.
    So for example, I might want to pick item number 10 on page 1, and drop it in position 125 on page 6.
    Also, has anyone ever modified the drag/drop/server update to support both dnd as well as forced re-positioning (by typing in a position number)?
    For example, on line 8, I type 4, and this element moves to 4 and everything else moves down?

Leave a Reply