Version 0.2 of ToolMan DHTML Released
A new version, version 0.2, of the ToolMan DHTML Library has been released. You can try out the examples (Drag & Drop Sorting, Edit in Place) and download it here.
Here are the Top 5 Reasons to be Excited about Version 0.2:
IE support. Most examples have been verified to work properly in IE6.
Rewritten from scratch; designed for reuse. The new library is more modular, better packaged, and less likely to have name collisions with your code and other 3rd party libraries.
It’s free! Permission granted for personal and commercial use via the liberal MIT license.
Improved quality. Cleaner, less duplicated code. Where possible, library modules have unit tests written using Selenium.
This is only version 0.2. It just gets better from here.
it seems to me that this version is significantly slower when handling large lists (250+ items) than the last version. anybody else using this code on large lists?
First of all, thank you for your work. This library is fantastic.
I’ve been experimenting with the combination of drag/drop lists and edit-in-place content, and the only problem I have is not being able to register further drag handlers from the API. This is because _dragsortFactory.makeListSortable() does not keep any references alive to the group object it creates. Would it make sense to attach the group object to the list items themselves before exiting? I’m imagining something like:
item.dragSort = dragSort;
inserted into dragsort.js, after line 40. This would allow you to add additional handlers from within the helper functions you can pass makeListSortable.
If I’m missing something, and there are alternative ways to add handlers, please let me know. And thanks again.
Ori,
I’ve been taking a short break from my DHTML library, but will resume working on it soon. This most recent release focused on IE support, refactoring the API to be cleaner and more easily reused. I will take a look at performance this next go round. If you have the time and inclination, it would really help out if you could post some more context e.g. browser and browser version, OS, and computer hardware. Also, your list of 250+ items, what are the approximate dimensions of these items? Is this a vertical, horizontal, or floated/wrapped list?
Ameketa,
Good suggestion. As a workaround, the drag library does keep a reference to the group in the element that is the drag handle. From drag.js:
By default, sortable list items are their own handle, so in effect you have what you are looking for if you don’t set the handle. Otherwise, you can find the draggroup if you get ahold of the handle element.
It makes sense for both the group element and the handle element to always have references to their drag group. I’ll make it so.
hey, i’m french so i apologize for my bad english…
i’ve tried to use your fantastic drag & drop librairy, which works very good, but i’d like to use it to reorder a list generated from a database. i just want to know when (after which function) have i to call my page who save the new order in the database ? (i don’t want to call it each time the “li” element is touch by the mouse, just after a drag & drop, because the “li” element contains a few links which can be pressed without any drag & drop)
can you help me please ?
Heibao,
The drag library allows you to add listeners for drag events:
There are 4 types of drag events you can listen for:
When an item is clicked, at a minimum
draginitanddragendwill fire. If you move the mouse after amousedownthendragstartwill fire a single time followed bydragmovefiring for for everymousemoveevent. However, if you specify a drag threshold thendragstartanddragmovewon’t fire until the threshold has been reached. For instance,group.setThreshhold(5)creates a threshold of 5 pixels; after amousedownthe mouse must be moved a distance of 5 before the item will begin to move and a ‘dragstart’ is fired.Given this information, I recommend the following:
dragstartlistener function on the drag groupdragendlistener function on the drag groupOption 1: In the
dragstartlistener, set a flag indicating that dragging has really begun. In thedragendlistener, store the list to the database if the flag has been set and reset the flag.Option 2: In the
dragstartlistener, save the current order of the list. In thedragendlistener, get the new order of the list and if different store the list to the database.Hi, first off, let me say that your library is absolutely awesome. I’m using it for a few different things right now but what I’d like to know is if there’s a way to “un-drag” an element, that is, to turn off the ability to drag it. This ability would be most appreciated, and keep up the good work.
Astrobot,
There’s nothing explicit in the library to turn off dragging on an element. I’ll add that to my list of TODOs. In the meantime, you can try this workaround:
To make it draggable once again you could either call
register(...)directly or callgroup.setHandle(group.handle)whichever you prefer.Thanks! Just what I needed!
first of all: awesome work!!!
i just played a bit with your script, but what i really miss, is the ability to work with nested lists. it would be fantastic, if it is possible to move an item to a child list of a child list or the other way up. of course, it should not be possible to move a complete list to one of its children, instead move the whole sub-list at once.
any tips to accomplish this?
Kevin, thank you for the compliment. Currently the library doesn’t support sorting of nested lists. Along with dragging between separate lists it is a feature I intend to add. Sorry, no ETA on that, though.
If you want to get your hands dirty, you could try building upon Ben Levy’s example of dragging between two lists which he built off of version 0.1 of my library.
nice piece of code, exactly what i was looking for. So, straight to the point: i had some nasty errors trying to integrate sortable list in my web application, just try to add this simple code to see what happens:
i’m not a javascript programmer, however, after some “alert debugging” i found where the problem was; in drag.js there are 2 loops:
just changing this in
sorry, but the previous post is messed up … just changing this in
solved the problem. many thanks for your code (it saved me a lot of time) and please forgive my poor english.
First of all, nice work! In Firefox (at least under Linux) the “always editable” example doesn’t work anymore, because the input elements don’t get focused when clicked. This is caused by the the mousedown handler in
drag.jsline 72. Removing the line fixes the problem.Another thing I noticed is the reference to a global variable called dragsort in
dragsort.jsline 26. In your examples this variable is defined outside the library, e.g.var dragsort = ToolMan.dragsort();if the user calls it different the library doesn’t work.you can add
just before
Felix, thanks for pointing that out. Makoomba, thanks for posting the fix. I’ve added the fix to my development version and it will be included in my next release.
Felix, regarding your first point, you suggest removing the following line from
drag.js:At least in Safari, without this line the browser thinks you’re also trying to select text and so it highlights any text you drag over. Justin Rhoades had a similar problem as you and submitted this workaround/fix:
> 1)removed from setHandle function: > “handle.onmousedown = function() { return false }” > > 2)added to dragInit function: > “ToolMan.events().register(document, ‘mousedown’, group.drag) > document.onmousedown = function() { return false }” > > 3)added to dragEnd function: > ToolMan.events().register(document, ‘mousedown’, group.drag) > document.onmousedown = function() { return true }
I haven’t tried this myself, but it should work. I plan to also incorporate this into the next release of my library.
Very nice. I’ve created a bookmarklet to manage Netflix queues using this library. It’s worked pretty well. I have noticed the text selection issue but it’s not a big issue for me. I also consolidated all the library files into one file to simplify inclusion.
Netflix Queue Manager
Tim, your work and that of others is commendable, but leaves me wanting (to inspire or hopefully pitch in) more..
To wit, can anyone point me to any forums discussing or already proving the combination of such DHTML pioneering with AJAX etc (presuming comparable stds that W3C may recommend) to create non-applet browser-based portal content management apps? If they’re likely rare or sequestered in proprietary secrecy, anyone care to speculate when such innovations will emerge in open-source, creative commons, or other open-license efforts??
Ah, the pursuit of killer apps..
é¿è \~/
Thanks for a nice and free library! I encountered a problem when sorting a (html) table. If I sort
TR-tags, it all works as expected. But withTBODY-tags, both IE and Opera fails (of course Firefox works great!), but they seem to fail for different reasons. IE does not set theoffsetParentattribute correct for this theTBODY-tag, a workable workaround is using theparentNodeinstead. Opera does not set theoffsetTop/offsetLeft/offsetHeight/offsetWidthattributes for this tag, so you have to use it’s first children instead. I’ve altered thetopLeftOffsetandbottomRightOffsetfunctions in coordinates.js according to this (I’ve also removed the creation of a _ToolManCoordinate object in each loop iteration). Here’s the modified functions:I’ve verified that it works on Firefox, IE6, Opera8, Camino, and Safari. This is just an ungly workaround, I don’t expect this to be part of the official version…
Hi, i am new to css2 and xhtml I am workig on a project that requires me to have a Rectangular grid(3 column by 4 rows) of pictures to be displayed.With a feature for user able to drag a picture and drop in other cotnainer.That cotnainer is also a recagular grid.(Same size) Though i tried to play around with the examples given. In rectangular one i am able to drag and drop in same grid(as given in example) and as i am new to css2 and java script.Can any one help me. Though the examples provided are good in list but when i played around with css2 to make a grid of two column i made a mess. Help required
Hello,
First of all your work is really terrific and makes users life much easier indeed! Poeple love this!
I have incorporated this into a page where an user can see and manage all of the photos in his account. Sometimes there can be a few hundred of these and some people have been requesting for two tings that I wonder whether you may possibly have an idea on how I could implement…
When you have a page with about 200 thumbnails and you wish to bring one of those at the bottom to the top area you have to drag it a little then scroll the page up then drag again and so on. Is it possible to enable auto scroll so that when you are dragging a thumb up the page will scroll with you?
Is it possible to drag and drop several thumbs at the same time, like if you could crtl+click on three or four and select them all???
The first one is something that is requested very often. Any tips/ help you may have would be very much appreciated!
Thank you again, Andrea
Tomas, thank you very much for the code submission. Often I start with an “ugly workaround” and then clean it up, so your code will come in handy.
vikasjain, currently my library only officially supports the dragging of list items. Check out this blog entry of examples of people who took my library and extended it to drag between lists.
Andie, I plan to support both of the features you describe. Of the two, auto scrolling is a high priority.
I’m sorry but there is a lot to read, but is this script able to be posted over PHP? I mean, is it set so that whatever you edit it will stay like that? I want to work on a page where only administrators can edit the layout, while visitors and regulars members can only see the changes. I want it so that it gets saves on the page and throught the internet so others can see the changes.
Hi Tim,
I can’t seem to rearrange the order. I am trying it while logged in, on a mac OS X computer in Internet Explorer. The cross mark shows up, and the images can be dragged but then nothing happens when I release the mouse.
Are there any issues with the Mac?
thanks! Webfreakin
IE on a Mac isn’t supported. Only Safari and Firefox are supported on OS X.
Hi Tim,
Thanks for your reply. Do you plan a fix for IE on the Mac in the near future?
Thanks, Webfreakin
hi
Great work thanks! I’ve been messing/hacking around with the slider demo here:
http://www.folio11.co.uk/jstechdemo/
I’ve got the code to add/delete slides and fixed the problem of the label not following the slide if its being edited.
I’m no javascript guru - so I’ve probably done this in a really ugly way, but maybe you can take a look at the code and incorporate some of it ?
I think the main points was that I added an id to each of the li elements, eg id=”slide1″ and added ids to each of the text and field elements (eg id=”page1Edit” and id=”page1View”)
then in dragsort.js I addded
after
grr url should be
this
I’ve found what may be a bug, or perhaps is just intended functionality that I found surprising.
if you have a list inside of a list and have set DnD to use a Handle on the main list, the inside list becomes draggable independent of the main list.
For Example:
That ordered list will now be draggable, independent of the main list. Since I can’t have textareas or text input boxes inside of a droppable section without a lot of hacking around, that poses a problem. I’m going to go ahead and take a look at the JavaScript and see if I can find anything, but do you have any suggestions as to good places to look or possible causes?
I’ve confirmed that this is only a problem in Firefox, IE 6 doesn’t allow the textboxes to drag and instead the click jumps you into the text input field like it should.
More fleshed-out example is at http://zillasmash.com/dnd/test.htm
haha, not sure what happened to the example code. Let’s try this again:
Well, so much for example html.
Just check out the page I linked.
Can this instead of using List tags, can it be done with regular tables..? like being able to drag tables into place, intead of lists into place?
Hi Tim, I’m sure I’m not the only one that is hoping for a v0.3 of your amazign library… Any chance of a sneaky peeky?
Cheers, Ulrich
I am basing a news portal interface on this script and i whipped up this quick prototype
It adds minimize/maximize to the windows and saves the state in a cookie too. Bit of a hack right now but it’s just to get an idea.
The next thing i want to add is animating the list items so when you pick one up the rest slide up to fill the gap. I can’t seem to find the place where the actual moving is done though. Would this be a at all possible or does the built in list ordering prevent the use of pixel by pixel animation to the new location…?
Friendly bug report here: I’ve noticed that IE6 on XP doesn’t support handles when trying to use this code in the Slide Show example:
It complains ‘factory is null or not an object’
I’m going to investigate today, but wanted to report my findings first. I’ll post again with any developments. (BTW - excellent work on the lib!)
Good news: the problem with assigning the handle reference was IE DOM quirks-related. In the findHandle function, a different approach is needed:
This works in IE6 and FF. Other browsers can probably be detected and supported pretty easily.
Sorry - having trouble with the wordpress formmatting. Code is…
</fingers crossed>
I hate blogspam, but desparately want to share my findings. Hence try #3. Sorry about the mess, toolman taylor.
function findHandle(item) { var children = item.getElementsByTagName("div") for (var i = 0; i = 0) return child } return item }Hi,
I am trying to do the following and wonder if it is possible to do in the next version. If not, would there be anyone willing to work with me to figure it out?
I have two lists. List A and List B. - I would like to drag from List A to List B - I would like to drag items from List B within List B, but not outside of List B. (i.e. List B can only drag within itself)
This next request is a bit trickier..
I would like to create a master list which always has a constant number of objects. An example would be a “Top 10″ list. This list would initially contain 10 slots which are all empty.
I would like to create a data list which has all available choices that could go into the master list. The data list could easily contain a few hundred items.
I would like to be able to drag items from the data list into the master list. When an item is dragged from the data list to the master list, it is added into the master list wherever it is dropped. So if I drag an item from the data list to the 6th position in the master list, it will overwrite the value in the 6th position in the master list. If a value already exists in the 6th position of the master list, it would be nice if it could be returned to the data list before it gets overwritten(so it doesn’t get lost in space).
Lastly, the master list would be sortable within itself. I could move something from position 6 to position 3. (Exactly how it does the sorting now in v0.2 - I just want to make sure this feature would still be available)
I would like to have a static number of objects in List B. This means that any drags from List A will overwrite an existing object in List B. So if I drop an item from List A into the 5th item in List B, the 5th item in List B gets overwritten by the item dragged from List A. The 5th item that got overwritten, would be sent to List A.
Is it possible to make a 1-way drag and drop.
ListA could be dropped into ListB, but ListB could not drop into ListA?
Is it also possible to have a set number of objects in ListB? If a user drags from ListA into ListB, it will overwrite the object in ListB that it drops over?
Thank you,
John
I apologize, I had some extra text in the previous post and I cannot edit it to remove it. Here is what I should have posted:
Hi,
I am trying to do the following and wonder if it is possible to do in the next version. If not, would there be anyone willing to work with me to figure it out?
I have two lists. List A and List B. - I would like to drag from List A to List B - I would like to drag items from List B within List B, but not outside of List B. (i.e. List B can only drag within itself)
This next request is a bit trickier..
I would like to create a master list which always has a constant number of objects. An example would be a “Top 10″ list. This list would initially contain 10 slots which are all empty.
I would like to create a data list which has all available choices that could go into the master list. The data list could easily contain a few hundred items.
I would like to be able to drag items from the data list into the master list. When an item is dragged from the data list to the master list, it is added into the master list wherever it is dropped. So if I drag an item from the data list to the 6th position in the master list, it will overwrite the value in the 6th position in the master list. If a value already exists in the 6th position of the master list, it would be nice if it could be returned to the data list before it gets overwritten(so it doesn’t get lost in space).
Lastly, the master list would be sortable within itself. I could move something from position 6 to position 3. (Exactly how it does the sorting now in v0.2 - I just want to make sure this feature would still be available)
Thank you,
John
I have a draggable unordered list, containing 100% width “A” tags, a la List-a-matic.
The code works fine in Opera and IE, but in Firefox, the mouseups after a drag are passed onto the link, meaning that there is no time to save the new list order before the page changes.
Is there any way to force Firefox to ignore the mouse clicks when they are caused by a drag? Note, the links still need to work with a standard click!
Hi, I’ve tried to remove the background: #eee; from your example of dragging.html, and in IE when I drag it, it changes the text to something like bold.
Anyone has the same problem?
Also if you try to remove the style: background-color: #eee;
in your example “dragging.html” you can see whats happen just in Internet Explorer.
Weird…
any solution?
I solved it commenting the opacity functions.
Thanks for an excellent script. But I noticed a problem with MSIE6 (don’t know about other versions of MSIE): When the lists being sorted are part of a nested tree, it has an impact on the performance. The deeper inside the hierarchy they are nested, the slower the performance…
I could upload an example if this is not a known problem, or not reproducable.
It’s not exhibiting this behaviour in firefox.
I have checkboxes that are draggable but when they are checked on or off and then dragged, their state is lost right when the item is inserted before or after. Anyone have a solution for this? Thanks!
Has anyone figured out if it is possible to sort table rows with multiple columns?
I also get the “factory is null or not an object in” IE6 on dragEnd. Why is that? I do not think I’ve changed anything from your examples at all… manxomfoe’s solution seems strange.
Hey Tim,
Wonderful code library! Thanks for putting it together. I do have an issue though - I’m encountering the “factory is null or not an object” error as well and was wondering if you’ve come up with a solution yet. The earlier posting by manxomfoe does not make any sense.
Thanks in advance….
Tim,
This stuff is great. I have one quetion for you & the others here. I have a sortable list. I’ve written js code to add a new LI (using cloneNode & then changing the id & other parts of that LI). The problem I have is that when I try to drag the new I created, it moves the original LI that I cloned. If I run dragsort.makeListSortable(document.getElementById(”moveablelist”), verticalOnly, saveOrder); AFTER the new LI is created, it works fine. If that function runs at page load & then after the new LI is created, I get: ‘factory is null or not an object’ when I try to drop any LI.
Any suggestions?
Thanks, Duncan
Hi there,
First of all, thank you so much for such a great script. I’m trying to fit it to my needs, and I’m having a problem : I’m trying to delete an element of my list and in doing so, I lose the possibility to move the items… (I’m using Firefox). When I delete my element (a link next to it) it launches an xmlhttprequest that updates my sql database and reads again this database to provide the code for the new updated list. I then display the new list using innerHTML. As far as displaying the list is concerned, there’s no problem, but I simply lose (as I said) the ability to drag the items around. I have to refresh my page for the drag option to come back. I have no idea what to do. If anyone can help, thanks !!
PS : As I’ve read in earlier posts, I’ve tried to call the dragsort.makeListSortable function at different places, but it doesn’t seem to work…
I have a question referring back to this post: http://blog.tool-man.org/toolman-dhtml-02-released/16#comment-32
Can someone explain how to unregister the drag a little more clearly to me, I’m not sure what the group is. Or an example would be perfect, thanks!
fretoune,
I don’t know if this would help, but one solution i have found is instead of reading the information back from the database and using innerHTML, you can always just hide the element that you deleted. Therefore it doesn’t show on the page after deleting. Works well for me, but I suppose it depends on how you are implementing it.
I’ve just started looked at this - seems very comprehensive.
I was hoping to produce a sortable list inside a draggable box. I just tried combining parts from the respective example pages, but when I put a list inside a draggable box, it was no longer sortable (although the box it was in could move around the page happily).
I can’t believe this isn’t possible using this library.
Any guidance to get me going would be much appreciated.
Thanks a lot. Will
In regard to this comment: http://blog.tool-man.org/toolman-dhtml-02-released/16#comment-49
Does anyone have an example on how to sort tables?
Regards/Kombat
To J and Tedward:
Sorry my commments were so cryptic. Having terrible difficulty w/ Wordpress code blocks. The problem is with the findHandle function as it’s used in the examplees. It’s not finding the children elemments that have a class of “handle”. I’ll try to insert the function here (with a bunch of carrots inserted)
> function findHandle(item) { > var children = item.getElementsByTagName(”div”) > for (var i = 0; i var child = children[i]; > if (child.attributes[’class’]) { > if (child.attributes[’class’].specified == false) continue > if (child.attributes[’class’].value.indexOf(”handle”) >= 0) return child > } > } > return item > }
Me again…
… When I say sort I don’t mean anything like this[1], but something more like this[2] (but drag n’ drop).
So maybe I should refrase the question, does anyone know how to re-order a table?
[1] - http://www.mattkruse.com/javascript/sorttable/ [2] - http://surfmind.com/lab/table_reorder.cfm
/Kombat
To manxomfoe, First off Thanks for the above comment! I think I spent about 4 hours on trying to fix this before seeing your post. For some reason the code didn’t quite come through so if you will excuse me for reposting a cleaned up version that I know works (on ie6).
function findHandle(item) { var children = item.getElementsByTagName(”div”) for (var i = 0; i = 0) { return child } } } return item }
argh… I didn’t read the formatting tips on code like I should have. let’s try this again function findHandle(item) { var children = item.getElementsByTagName(”div”) for (var i = 0; i = 0) { return child } } } return item }
! last time:
I notice that the two list drag-and-drop code works well when the lists are styled tables ala FireWorks8.
http://www.markireland.com.au
(but what is going on in FireFox?)
Hello all, i’m trying to implement a basic autoscroll function. I’ve written the code below which seems to do what i want. If a draggable element is moved into the top 50 or bottom 50 pixels the page scrolls.
where drag_started is set from the ‘dragstart’ and cleared at ‘dragend’ from the registered library triggers.
The only problem is the position of the element that is being dragged is not updated while the window is scrolling. I guess because the position is only refreshed when the mouse is moved and not when scrolling the window i.e. the cursor is not moving relative to the window even though the page is scrolling. A quick movement of the mouse will refresh the position of the element to under the cursor. I was wondering if there was any way of forcing the position of the element to be updated, which i could then put in the scrolling functions. I’ve tried forcing the internal library function _onDragMove but i can’t seem to pass it the right variables to get it to update.
Any ideas anyone?
I notice your drag-and-drop code is being used at www.mySpace.com
If you have an account look at Top 8 Friends. You can drag and drop their pictures to reorder them. (Supposedly this site has 35 million users. I am told that News Corp bought the site)
Anyway, Tim your famous!
If you view http://www.MarkIreland.com.au in IE you see one thing and
if you view it in FireFox you see another.
Why is that?
Thanks
[…] was awesome to see, but once I had it up and running the problems started to crop up. The ToolMan DHTML library looked like it would do everything I needed, and at first blush it wo […]
Fantastic stuff! Thanks for sharing Tim.
Would anyone be able to tell me why the cookies aren’t working at this address?:
http://www.ekstasis.net/resources/domlist.htm
The only change I made is removing the window.onload function items not relating to ul=boxes. (and the directory structure)
Thanks.
@ knuckles and others
first of all Tim this is nice stuff !!!
but I have to agree with Knuckles about the lack of auto scrolling but i’ve put a little efford in hacking your script and made it scrolling for Safari and Firefox on the Mac
first of all i’ve added this function in the coordinates.js after mouseoffset : function ()
This is because Safari 1.3s mouse position weirdness
and i added this piece of code inside drag.js within the _drag : function() after this line var newTopLeftPosition = dragEvent.topLeftPosition.plus(dragDelta)
and i’ve added these lines in function _ToolManDragEvent(type, event, group) {
after this.topLeftOffset = ToolMan.coordinates().topLeftOffset(group.element)
it should work on Firfox and i hope you and or someone else can clean up the code and make it work for IE and hopefully see the implementation in v0.3
Sorry my 2nd piece of code got messed up, i forgot to transelate < and > hopefully this will work
I thought I would comment on the IE6 findHandle function that people seem to be having problems with.
The code given by Tim looks like this
The problem seems to arrise in the this call — child.getAttribute(”class”) — Apparently in IE using element.getAttribute to get the class attribute always returns null, therefore setting the handle never works. After doing some research I found that their is an alternate way in IE to get at the class attribute. This is done by doing element.className.
so here is an alternative to the given code –
I don’t know if element.className is supported in the standard or supported by all browsers, but it does fix the IE6 bug.
Apparently using lessthan and greaterthan tags in this completely screws up what you write. So here is my last try to post the correct code. Also that is why previous comments have looked funky by other people.
Hi,
my IE6 always returns the ‘factory is null or not an object’-error, Is there an working example to copy the code, i test any version of in the comments here, but no success.
Jens
Hi,
Is there any way to put a sortable list within a sortable list, my efforts so far have not worked.
Cheers
I encountered a bug recently. I’m using this library in my Netflix Queue Manager. The drag-n-drop capability was broken after Netflix updated their domutils.js script. For some reason they extended the Array class with an append() method that just wraps the native push() method.
The library has two instances where it uses the for … in construct to iterate over array elements. This is incorrect, as this will iterate over not just the elements, but also any user-defined properties. So the append() method was now being iterated over, which promptly failed when the handler was given this unexpected object.
The problem is solved by using the Array length property to access the proper range of elements:
This
Trying again…
instead of
Excellent script Tim.
Been playing a bit and come up with the following new addition to the dragsort.js module…
My requirement was to add new LI elements to an existing, already sortable UL (which I do via JS and createElement etc), but to make the new item dragable within that existing UL. As there is no easy way to
makeListUnSortable, this new extension to Tim’s prototype is here for you all to comment/break etc! Of course, if you useremoveChildto delete a LI from a UL, nothing is broken, as the event listeners for that specific get killed when you kill the LI itself.Ok, here it is, it needs to be added to dragsort.js, just before the definition
_onDragStart : function(dragEvent) {Excellent script Tim.
Been playing a bit and come up with the following new addition to the dragsort.js module…
My requirement was to add new LI elements to an existing, already sortable UL (which I do via JS and createElement etc), but to make the new item dragable within that existing UL. As there is no easy way to
makeListUnSortable, this new extension to Tim’s prototype is here for you all to comment/break etc! Of course, if you useremoveChildto delete a LI from a UL, nothing is broken, as the event listeners for that specific get killed when you kill the LI itself.Ok, here it is, it needs to be added to dragsort.js, just before the definition
_onDragStart : function(dragEvent) {You use it like this. Assume that you’ve already called
makeListSortable(document.getElementById('mylist'))where mylist is your UL and you’ve added a new LI element as described above, you simply call:Ensure of course that your new LI element has been assigned an ID of ‘mynewliitemid’ otherwise it won’t work!
Comments here would be welcome.
– Dave (Intranet App Developer, BBC News, London UK).
Awesome tool!! Marvellous work!! Just exactly what I was looking for. I am having this wiered “Factory is null or not an object” error pop up whenever I go out of the browser window upon draging the list item… Is it something specific to my browser settings? I tried to put the code in the dragEnd function where it does the group.notifyListeners and ToolMan.events().unregister calls in an if loop. basically do it only when the var group = this.toolManDragGroup is not null. Not sure if that is a nasty way to fix it rather than identifying what the exact cause is. Excuse me if so! But it got rid of that error.
Has anyone used this in .net aspx pages? If so, other than using a query string, do you hae any idea how I can send the reordered list item values to back my server? If I set the Listbox to run as a server control, I see only the original order. Any suggestions will really help me!
Lookingforward eagerly to new features in your next version!!
Thanks once again Tim for providing us all with a wonderful tool!
Friends I was trying to add a element which would display the number of the cell starting from 1 after each of the element in the list. However, after the dragend, I am trying to renumber the innertext of elements starting from 1, but I still see the old values displayed. I am using the innetText property to change the value of the elements. I am basically doing this to show the cell numbers..a little more user firendly for my users. any idea how this can be achieved? Thanks
This tool is simply great, compliments. I have an application for which one gets a long list of rows, e.g. 100. The user wants to be able to select multiple rows and drag them to another position. How can it be done with your code ? I managed so far only single drag and drop. An example of what I would like to achieve (with Tool-man library) is shown in http://webmail.mbn.ch/table/musel.htm , however it does not refresh the table and it is not GPL.. I would very much appreciate your comment. compliments again. this is the best implementation of the draggable list I have found. luca
Hello, if found a little problem with the new version. If you use the overflow attribute auto the sorting will not work. Here is an example page:;
Drag & Drop Sortable Lists with JavaScript and CSS
First of all let me say this one cool library of scripts. One issue I am having though is with the “factory is null” error in IE 6. I have tried the fixes mentioned here all of them to no avail. I see the error even in the examples pages. It happens when you are draggin an item below or aboe the current window (arrow up or scroll mouse will scroll the page) then releasing the item gives you the error. Anyone have any other ideas of how to fix this issue.
thanks in advance
I’m attempting to alter the files and incorporate PHP into the mix (not a problem) problem is if I dice up the example page nothing works. What am I missing?
I have a strange problem with firefox 1.0x… When I reorder a list with an input element in the firefox doesnt post the moved input of the moved element. how can I fix that? or am i missing something?
thnaks in advance,
Vikasjain mentioned using this with a 3×4 grid of pictures. I, too, am trying to use a grid of pictures. In my case, it is a 4×6 grid of up to 24 photos, and I am not trying to allow dropping to some other “container” (his terminology), but only to allow reordering the photos in a manner similar to the “Sorting in two dimensions” example.
So far, I have not been able to get the whole thing to work. If I use a table so that the grid will be 4×6 regardless of screen or browser-window size, the drag-and-drop does not work (the pictures move, but never drop into place). If not, then the pictures all appear in a single, vertical line (and the drag-and-drop DOES work).
How may I arrange the pictures in a 4-column-by-6-row grid that will allow me to use the drag-and-drop to change the order of the pictures?
Although I have 28 years of computer experience, my web-related experience is only in PHP, MySQL, and very basic HTML and Javascript, so this CSS stuff is still a little mysterious.
Thanks!
Great scripts! I am using dnd for a 2d list, and I would like to add an href in each list element to allow that item to be deleted and then update the list on screen. My javascript programming has been limited to fairly straightforward web applications, so my OO programming is not particular sophisticated. I am having trouble getting this functionality to work. If anyone would be willing to help out I would really appreciate it. Thank you!
From what I read here there this is supposed to work in Safari, and the underlying stuff from youngpup.net does work on mac safari, but no examples on this site seem to. Has anyone resolved this ? Max osx Safari 2.0.3(417.8)
FYI.. It’s the example in the download that isn’t working on safari, not what is here on the site..
Hi, First of all, thanks Tim for the library, it provides awesome functionality to web applications.
I aplogize if this is a very basic question, but I’m new to JavaScript.
My problem is the following: I can’t get to have a page with two sorteable lists (each one works independent from the other, no need to pass items between them). The (erroneous) code I made look like this:
At this point I figured out that ToolMan.dragsort(); is not a constructor, but a pointer instead.
How can I have two instances of a sorteable list in one page? I’ll appreciate any clue to get this to work.
Best Regards Fabio Cavassini
Sorry to repeat but whats up with: ‘factory is null or not an object’, seems IE only.
Seems no solution was really posted.
Still don’t have an answer for the picture grid, but never mind: I got it to work with Scriptaculous, instead.
Here we go, must missed in in the reply to the last posting.
“I’ve detedted a javascript error in your tool-man example pages.
I’ve fixed the error adding the next line: if (!group) return into line 181 of drag.js”
Is there any way to make this work with scrollable layers. When I scroll the layer to drag an item that is not originally visible the item is dropped too far left. I quess the amount is off by the scrolled length.
so overflow: scroll is a no no at the moment. Problem is I can’t fit al the elements to fixed size window.
I tried to modify coordinates.js, but without anything else than a bad headache.
Wonderful, simple, useable!
How to use this to make a collaborative text editor? Or to make a collaborative web page that doesn’t require a full page refresh? AJAX?
Tim, this API is just great. I’m trying the Slides order example, and i’m having problems with IE. With firefox it works perfect, but when on IE when i drag some slide, it leaves spaces as if there were some invisible slides in the middle.
Anyone had the same situation? Possible solutions??
Thanks Again! Dario
For anyone trying to use this script and have editable content. When you define a handle, the javascript function simply takes a way the _dragInit trigger from non-handle elements. What it needs to also do is enable other mouse events, or more specifically, allow onmousedown to return true. To accomplish this all you need to do is replace this following lines of code in
drag.jsNow change your set handle function to:
This way, if you want selectable draggable contents, just add that last parameter. If not, leave it out.
Sorry if my code isn’t coded expertly, I’m no pro-coder.
Me likes!!! I have been looking for something like this for a while now to incorporate into my custom CMS. I think instead of Having all the content in the list I will just pass a mock up discription to a popup, or even cooler, a lightbox.
For all those above looking for support for IEMac. Microsoft has quit developing or distributing IEMac. I think they say to try out firefox. IE5Mac is worse then IE for Windows with CSS or at least until IE7 comes out.
There is a question above about posting into php. Because Javascript is client side and the saved order gets stored in a cookie, you can use the cookie to read the sort order. I used echo $_COOKIE[’list-boxes’] for my list but it looks like the names change per each type of list example. but whateva! That can be exploaded and used to define the sort order.
Also, instead of using the actual content from the list I found it more usefull to identify the list item with an id. I will be dynamically generating via mysql. so i copied the serializeList fuction and made it return the id of the list item rather then the content. The content is going to end up being snipits of page content and this is going to be a layout manager. I just wish it wasn;t so javascript based.
I also copied the inspect list order function and made it submit the form rather then just alerting it.
So now i have my sort order in a cookie. I am relativly new to cookies, but it would be best to set it and then destroy it. so there is no confusion when the user comes back. I am in the process of making a cms for my client, and this really helps. I will ask them if i can GPL the end product. if so i will definatly be contacting the tool man
SO after a fun filled all nighter with the library, I found some stuff out I’d like to share. I guess you can’t post javascript very well. The whole server / client side thing kinda gets in the way. I was never much for javascript writing anyways, but I managed to get this working. So instead I bumbed the order array out to the url and then collected it on the reload with if isset $_get into my sql query. It’s kinda ugly but all this stuff sits in a secure area anyways. I can’t share my stuff just yet, i need to optimize a bit and get rid of the sensitive stuff
Hello people! I’m sorry for me rnglish, but I need your help… I like Tim Taylor’s Drag & Drop Sortable Lists and Tom Westcott’s Multi List Drag Drop very much. But functionality of Tom Westcott’s script is too feeble. I want to use multi list d&d in my CMS. How can I get functionality of Tim Taylor’s script and abilities of Tom Westcott’s script? I already ported Tom Westcott’s script from SAJAX to XAJAX. And it’s realy work. I created menu editing in admin panel that using d&d, but i need mor functionality like handles. Please help me, and I never forget you!
And one more: I already created something like Tim Taylor’s shopping cart, but I used his multi list sorting only.
Hi, Great tool. When I also use prototype.js/scriptaculous.js to do some ajax works in the same page, script error occurs and the sortable list does not work. Seems to me could be names confict between prototype.js and drag.js. Does anybody know how to fix this problem? Thanks.
Many thanks for this script Tool Man! I’ve found that it does work for sorting table rows if you change two lines in dragsort.js to look for TR’s instead of LI’s:
Line 23 from: var items = list.getElementsByTagName(”li”) to: var items = list.getElementsByTagName(”tr”)
Line 33 from: var items = list.getElementsByTagName(”li”) to: var items = list.getElementsByTagName(”tr”)
salut!
i gotta say … greatjob with this release man! i like your streamofconsciousness
…and i hope your neurons will help me on this, cuz i tried to modify so many things around your script, but nothing to help me happened…
take a look on this: http://spinicrus.evonet.ro/ajaxeditor/testPage.html
…and click on “show” from any of the items from that list… you’ll get the ideea of what i want to do…
now, my questions is obvious
, but ill ask it anyway:
why the TinyMCE looks like that ?! i saw that this WYSIWYG editor is mentioned somewhere on this site, but did’t undestood in what context…
so … could you please help me … i’m running out of time on this project, and i have no f****** ideea on how to solve this… i’ll bye you a beer…
chears!
nervermind, i figured out: just comment this css line from lists.css(clickable a class): display: block;
…and that’s it! looks like i’m gonna buy myself a couple of beers… chears!
Excellent library.
FWIW - since I wanted to strip out whitespace and comments, I had to go through your javascript adding (numerous) ‘;’. If you’d like me to send over the resulting source, please let me know. ( I’ve made sure your licensing comment stays intact, though ).
Tim, I just found your library and WOW! EXCELLENT work and great use of patterns!
It’s given me a new inspriation to extend my JS and DHTML skills!
Great job!
-D
Tim,
Compliments on your script; it works great!
I want to use the draggable list as navigation, using the first element in the list. I added a small function to get this first element to core.js:
showFirstItem : function(id) { var list = document.getElementById(id) var items = list.getElementsByTagName("li")It works when I call as onclick event (e.g. ).
Now, I would like to trigger it on dragend. In dragsort.js I added “junkdrawer.showFirstItem(’boxes’)” at the end of the _onDragEnd function. It works, but sorting the list gives unexpected behaviour in FF (1.5.0.7): it sorts in a really strange way. It works ok in IE7, but I need this to work in FF.
Any idea how I can fix it?
Ok, found out that the strange behaviour was caused by the alert. When just returning a value it works OK.
The next challenge is to combine the tool-man script with moo.fx (http://moofx.mad4milk.net/). When adding the lines
to the example page things stop to work. To give extra confusion no error messages appear…
Hello, I have downloaded your script, and I would like to use it, but I have a problem ! There is m code : [code]
Drag & Drop Sortable Lists with JavaScript and CSS
[/code]
The don’t drag and drop ! What’s the problem ?
Thanks !
I’am Argentinian, sorry for my bad english!!! first, your examples is wonderfull !!! second i have a question, in http://www.fad.com.ar/drag.html have an implementation de your example with a error, one list is in a table, second list is in a layer, draging between list 2 and 1 the first item is ok, but drag the last items for example the item 35 on list 1 one stranger error it happens you have idea that can happen? thanks in advance
Fernando Dichiera from Argentina the south America
Hi, Has anyone figured out how to make this work on a page that also uses prototype.js? I’ve tried various things, but haven’t managed to get rid of the conflict and make it work at the same time.
I’m wondering what this is for?:
_ToolManCoordinate.prototype = {
there are only a few references to prototype in the library.
Hi there,
First of all thanks for putting all this work out there, its a fantstically useful and versitile little toolkit that has saved me countless hours of work and made my latest DHTML based app really simple to use.
Unfortunately, I have found a problem when putting a draggable list in an absolutely positioned div with a fix height and an auto overflow, when the list is long enough to cause a scrollbar the wrong co-ordinates are calculated to find the drag target.
I have put an example here: http://www.sqoo.co.uk/test/list_example.html
Unfortunately this particular configuration is rather useful, especially when contained within a draggable div
Snippet:
I would investigate further, but I have a Wed deadline for a big project.
Cheers, Dave
Sorry to sound like a total dumb-ass, but is there any documentation for the API? Can you tell I’m new to this?
Tim… great utility. Haven’t seen you reply to any messages lately… everything okay?
In reading through the other messages, I came across some problems as it relates to
_dragEnd, wheregroup = this.toolManDragGroupcomes back as null or not an object. You can get around it with theif(!group) return;statement, but this severely slows down any subsequent reorders of the list (I’m assuming that the events never get “unregistered” and start slowing everything down).With that said, what I am trying to do is to add a new list item (li) to the unordered list using document.createElement(”li”)… just as others have done above. I then make a call to
dragsort.makeListSortable(*myULElement*, setHandle). This allows me to drag my new list item up and down the unordered list, but as soon as I drag an existing item below the new item (regardless of where it is in the list), I receive the error'factory' is null or not an objectat the line…var dragEvent = group.factory._createEvent('dragend', event, group)I put an
alert(event.type)within the_dragEndfunction, and noticed that themouseupevent fires twice!?, with the second “firing” producing the error. Remember, this only happens when an existing list item is dragged BELOW the newly created list item, regardless of where the newly created list item is within the unordered list. I also tried usingevent.cancelBubble = true;thinking that maybe there was event bubbling occurring, but that had no effect.I also tried implementing the function submitted by dave_bevan (
addSortableItem). While no errors occur, I can’t drag the newly created list item. I can drag any original list item around the newly created list item, but that’s it. Seems like it needs a reference to thehandle, but I didn’t have any success usingsetHandleeither.Any help from either Tim or anyone else reading this blog would be greatly appreciated.
BTW mark, you don’t sound like a total dumb-ass… some documentation for the API would be a great addition.
Thanks again Tim for putting your code out here for everyone to use.
Get work! Your slideshow example was almost just what I need for a project. But I needed the ability to add new slides too. I made a copy of makeListSortable and changed a few lines and got makeListItemSortable. It’s functionality is identical to makeListSortable, except that you pass it a reference to the list item instead of the whole list (you have to have created the list item and added it to the list first). Just add this to dragsort.js:
I also cleaned up the editing API quite a bit for that example something you had commented TODO). I created a makeEditor function (a modified version of the existing join function) that is passed to makeListSortable or makeListItemSortable after the setHandle parameter. Using that tou don’t have to create editors, they’re created automatically for existing and new list items. It also means you don’t have to insert ids for “oneEdit” and “oneView” etc. and you don’t have to call the join function for each list item. The entire example is at http://www.tsdragon.com/toolman/slideshow.html
Thanks for the great work! I hope my contributions are useful.
For those who are having difficulties with using prototype.js and toolman’s library at the same time, here is your solution:
It is actually a fundamental issue with libraries which extend (add functions) to the basic javascript object (this includes prototype.js and others such as JSON.js). The problem is that arrays are actually objects in javascript, and by extending the basic object in javascript to add a function you automatically are adding members to all arrays. This has implications in javascript code, consider the following:
var test = array(’this’, ‘that’);
Normally you can have a simple loop such as:
for (var i in test) alert(test[i]);
which will alert 2 times with ‘this’ and ‘that’. When you use a library such as prototype.js or something which extends the basic object and adds a function named ‘foo’ you will actually get 3 alerts, ‘this’, ‘that’, and ‘function foo’.
This breaks many pieces of code which for loop on arrays, which includes the toolman library. This is not a bug in either direction, just a fact of the language construct and how prototype and others use the language.
There is an easy solution which I have found myself implementing a LOT in 3rd party javascript:
for (var i in test) { if (typeof test[i] == “function”) continue; alert(test[i]); }
I had to fix 2 places in drag.js which processed an array with a ‘for (var xx in yy)’ and this enabled the library to work happily with prototype (and others).
Hope this helps everyone.
Awesome job on the script Tim!
I am a teacher and I use it to create two dynamic word lists for students so they can increase their vocabulary. With Perl, JavaScript and your draggable list, things work like a charm! My students like trying to match up two lists of words, and my script generates new words all the time
Cheers!
One question: Is it possible to turn off the ability to drag via JavaScript dynamically somehow? I’d like to be able to do this when they are finished so the list becomes static (un-draggable).
Hi Tim,
I stumbled upon your impressive examples while researching alternatives to Scriptaculous.
I’m currently working on a web-based application which uses Scriptaculous to reproduce the behavior found here:
http://www.gregphoto.net/sortable/advanced/
Specifically, sortable elements within sortable groups. In addition, the elements are interchangable between groups and can be dragged any direction (not just vertically.)
Question: how much work would be involved to convert this example to your library? I suspect judging my your examples the answer is “not much”, but any advice/insight you could offer would be greatly appreciated.
Thank you, John
Hi! I’m from Bulgaria.
Apologize me for the bad english!
I am examining your briliant work and because I’m a newbie, I can’t understand the following code:
_showDragEventStatus : function(dragEvent) { window.status = dragEvent.toString() }, Where are you come from the dragEvent parameter?
@ jriffel Your solution didn’t work well here, what exactly did you change? Could you send me your changed files? (sktforfun@gmail.com) I need to fix this asap and I can’t find help anywhere
I changed this: for (i in group.transforms) { if (typeof group.transforms[i] == “function”) continue var transform = group._transforms[i] newTopLeftOffset = transform(newTopLeftOffset, dragEvent) }
That fixed the error “this._each is not a function” But now i get this error: “iterator is not a function”
Please someone help me
Thanks
If you get a javascript conflict between toolman and prototype first see jriffel post above, if you still have no luck try changing the lines below in toolman’s drag.js
CHANGE
for (i in group.transforms) { var transform = group.transforms[i] newTopLeftOffset = transform(newTopLeftOffset, dragEvent) }
TO
for (var i= 0; i < group.transforms.length; ++i) { var transform = group.transforms[i] newTopLeftOffset = transform(newTopLeftOffset, dragEvent) }
AND CHANGE
for (i in listeners) { listenersi }
TO for (var i= 0; i< listeners.length; ++i) { listenersi }