Drag and drop sorting on a web application? This thought is so far fetched several years ago - and now everybody is or can do that easily with jQuery. Looking at the tutorials and documentation in jQuery's website, it lays out a simple method to call to make our list to become sortable.
$(function() { $("#sortable").sortable(); $("#sortable").disableSelection(); });With our corresponding HTML:
<ul id=sortable> <li>one</li> <li>two</li> <li>three</li> <li>four</li> </ul>Here is a demo on how that works.
Now what if we are using TABLE instead of UL or OL??Easy - Use TBODY tag. So using the example above, let's convert the list into a table:
<table id=anothersortable> <tbody class=content> <tr><td>one</td></tr> <tr><td>two</td></tr> <tr><td>three</td></tr> <tr><td>four</td></tr> </tbody> </table>Then our jQuery to be as such:
$(function() { $("#anothersortable tbody.content").sortable(); $("#anothersortable tbody.content").disableSelection(); });Click for demo for the simple table.You can even make this having sub-sort - or with children sorting. Like this:
<table id=subsortsortable> <tbody class=content> <tr><td>one</td></tr> <tr><td>two</td></tr> <tr><td> <table><tbody class=subcontent> <tr><td>three.one</td></tr> <tr><td>three.two</td></tr> </tbody></table> </td></tr> <tr><td>four</td></tr> </tbody> </table>Adjust our jQuery to be as such:
$(function() { $("#subsortsortable tbody.content").sortable(); $("#subsortsortable tbody.content").disableSelection(); $("tbody.subcontent").sortable(); $("tbody.subcontent").disableSelection(); });Click for demo of this one. UPDATE: Viewer Coolboy in his comment below pointed out that viewing in IE7 may sometimes introduce unexpected behavior in the y axis. I can replicate the problem and have found a solution or a work around for it by using "handler". Using handler, you basically designating a "dragging" point, instead of using the whole row as to drag. So in using handler, our code changes a little bit in both HTML and javascript. Here is the updated HTML:
<table id=subsortsortable> <tbody class=content> <tr><td><label class="levelonehandle">X</label></td><td>one</td></tr> <tr><td><label class="levelonehandle">X</label></td><td>two</td></tr> <tr><td><label class="levelonehandle">X</label></td><td> <table><tbody class=subcontent> <tr><td><label class="leveltwohandle">X</label></td><td>three.one</td></tr> <tr><td><label class="leveltwohandle">X</label></td><td>three.two</td></tr> </tbody></table> </td></tr> <tr><td><label class="levelonehandle">X</label></td><td>four</td></tr> </tbody> </table>Then our javascript as such:
$(function() { $("#subsortsortable tbody.content").sortable({ handle: ".levelonehandle" }); $("#subsortsortable tbody.content").disableSelection(); $("tbody.subcontent").sortable({ handle: ".leveltwohandle" }); $("tbody.subcontent").disableSelection(); });
32 comments:
Nice post! I will definitely be using this technique. You should consider having a "live" example of some of this stuff, it helps to see this kind of thing in action.
Demos are added.
Thanks a lot! Supeperb post! :)
yaaah!!! nice post!!
it saved my time!!!!
Thank you!
The main issue with ui.sortables which i'm sure you have noticed is that it breaks really bad in IE when you start working with Nested Lists or Tables. I really really hope they can get that fixed because code-wise ui.sortables is really light weight and awesome!
This trick breaks if you put 2 or more td fields, on firefox and ie. Search on the web tablednd plugin. It solve the problem.
I have tried this with several TDs, it works pretty well for me, in IE, FF, Chrome.
Here is an example with 2 TDs - http://setiabud.googlepages.com/sortableSubTable_2.htm
Thank You very much!!! :) Where did You get this solution?
@Sergey: lots of trial and error.
thanks you very much... :D
Great post.
Having some problems with IE7. When you drag a row down the target y-coordinates gets way off.
:(
This only happens when using sortable in a table. Not when I'm using it with UL/LI.
Verified this on your, and some other guy's, demo-page.
@coolboy thanks! In my experience IE7 does have some quirks. You can work around this by adding a "handler".
I will update my post with this.
Hello
I would like to point that if you want more nesting (WORKS WITH UL! IE7/8) levels you just need to define unique LI handler for every UL you nest that fixes IE7/8 issue with braking while drag.
Not sure if I'm doing something wrong, but when I use a table like this, when I call .sortable('serialise') I get an empty string returned even when each tr has an id of the form "set_id".
@Grant: Are you sure that you put "serialize" instead of "serialise"?
Joe, I want to sort td's within a table of 2 X 2 layout. Your example sorts sort, how td's can be sorted.
@anonymous I am not sure I understand what you are saying/asking. Let me ask to clarify: you want to sort TDs within a TR or within a whole TABLE?
Nice example, i got it working too. However, the Serialize function returns an empty list. When I use a simple ul / li list it works fine.
@Johan The serialize is giving empty string because I did not put any ids in the sortable elements. Here is a quote from jquery's website about serialize method for sortable: If serialize returns an empty string, make sure the id attributes include an underscore. They must be in the form: "set_number" For example, a 3 element list with id attributes foo_1, foo_5, foo_2 will serialize to foo[]=1&foo[]=5&foo[]=2. You can use an underscore, equal sign or hyphen to separate the set and number. For example foo=1 or foo-1 or foo_1 all serialize to foo[]=1.
thats great!!!
thank you
doing this on a table worked like a charm, until IE9 came ...
@Tom - I am working on a solution. As a work around, you can use this metatag within your "head" element:
meta http-equiv="x-ua-compatible" content="IE=8"
to force render it using IE8 compatibility mode.
@Tom - upgrading your jQuery UI to the latest (mine is using 1.8.11) should fix the IE9 problem.
Nice post! Works great!
great post.
i forgot the underscode (_) in the ID-attribute, so the serialize()-method just responsed with a undefined values.
now everythingworkds fine :-)
Thanks
Thank you, this saved me a lot time and hassle :)
This works pretty good, but now, i need to safe it in a cookie, can you tell me how it works? Thanks
David -
If you already have a method to handle the sortable event, you can add/edit the cookie inside it.
Here is a crude example:
$(function() {
$("#subsortsortable tbody.content").sortable({
handle: ".levelonehandle",
create: function (event, ui) {
var co = document.cookie.split(';');
for(var i = 0;
i < co.length; i++) {
var c = co[i];
while (c.charAt(0)==' ')
c = c.substring(1,c.length);
if (c.indexOf("sort=") == 0)
sortOrder = c.substring("sort=".length, c.length);
}
// display sortables appropriately based on saved sort order
}
update: function (event, ui) {
document.cookie = "sort=" + ($(this).sortable("toArray"));
}
});
});
Very good!
Very good, helped me a lot.
Very nice.... Thank uu..!!!!!!
Post a Comment