I’ve updated the Scriptaculous demo that I put up a while back. You can see it here. There were a large number of comments on the initial post, many of them wondering why the example didn’t work in Scriptaculous 1.6.X. I took a look at it today and after some experimentation made the following changes to get it to work:
- Reversed the order of creating the sortables - for whatever reason, it seems that the outer most sortable must now be created last, whereas it worked fine when created first before
Removed the code to ‘destroy’ the sortables before recreating them - this was necessary before, but it seems that they are automatically destroyed now when creating a sortable on the same element. While this slimmed down the code, it wasn’t essential to get it to workScratch that. I noticed a bug where dropping elements on the sections wasn’t working if a new group had been created before any of the line items had been added to a group. Adding back the destruction of the line item sortables did the trick. It still seems to be working without the destruction of the page-level sortable though.- Added a prefix to the new section id for consistency sake (as per John’s comment)
- Other miscellaneous JavaScript and CSS cleanup
There were also several comments questioning whether this positioning can be saved to the database. That’s exactly what the debug function is aimed at doing - showing the user how to get at the positioning information with JavaScript. Once you’ve got it into a JavaScript string/array/object, it’s trivial to put it into an input and submit a form.
Enjoy.
Greg
June 2nd, 2006 at 9:38 pm
This looks great, and just what I needed for a new app. I’m having a problem reproducing the create new group functionality. When I cut and paste your code to my system, all the drapdrop goodness works, but when I try create a new group, nothing happens. Any ideas?
June 4th, 2006 at 12:52 pm
Hey,
this is fantastic and exactly what I need, but I already sliced my layout and everything into lists (&) instead of divs?
Is it possible to use this with divs?
thx in advance,
seba
June 4th, 2006 at 9:45 pm
@David - don’t know what the problem might be, you might want to try running it in Firefox with Firebug to see if any JS errors show up.
@seba - it is certainly possible to use lists instead of divs. Check out the docs at the scriptaculous website for more information…
June 5th, 2006 at 8:25 pm
I was experimenting with this and was trying to add a simple “delete” link to run a fadeout effect on one of the groups. It has an annoying side-effect in IE and Netscape — when the group below the one that you are deleting contains items (the lineitems in your example), those items get shifted up more than they should, past the top of the containing group. Seems to work ok in Firefox and Opera. Here is my test:
http://www.noodletools.com/scriptaculous/greg.html
Just click the “delete” link above Group 2. Can anyone figure out if this is a known bug, or if there is a work-around for this? Note that after it happens, initiating a new drag operation on a Group or Lineitem seems to refresh the screen and correct the problem…
Damon
June 5th, 2006 at 9:11 pm
Thanks for the update!
Re: the addition of the section prefix. Where exactly in the code is this being implemented?
When adding a new group (”Group 4″) on the demo page, the debug output still shows:
group1:
group2:
group3:
4:
instead of
group4:
The latter is essential for my purposes (when saving the results to a database.)
June 5th, 2006 at 10:17 pm
@Damon - that certainly is a weird effect - could be a scriptaculous bug. Maybe it has something to do with the fact that Effect.Fade doesn’t remove the element from the page, it just hides it - maybe IE is getting confused somehow. Another thought would be to destroy the sortables before deleting the group and then recreate them after deleting the group.
@John H - correct. I must not have updated the latest version I had on my machine…it should work now though
June 6th, 2006 at 12:47 am
Hmmm… doesn’t seem to make any difference. Is there any kind of “refresh” I can do after the fact? Let me know if anyone solves this issue…
June 6th, 2006 at 5:29 am
Hi Greg,
did you mention that Opera(tried 8.4) has problems with your drag & drop functionality. Dragging works but dropping needs a mouse click, but if you click does not realize the onUpdate event.
By the way - I added a db connection that inserts new order into mysql db:
1. Add trigger “onUpdate” to call function “updateRanking”
Sortable.create(’playlist_1′,{tag:’div’,dropOnEmpty: true, containment: sections,only:’lineitem’, onUpdate:updateRanking});
Sortable.create(’left’,{tag:’div’,only:’section’,handle:’handle’});
2. updateRanking()
function updateRanking() {
var playlist = document.getElementById(”playlist_node”).value;
var options = {
method : ‘post’,
parameters : Sortable.serialize(’playlist_’ + playlist)
};
new Ajax.Request(’script_ranking.php?playlist=’ + playlist, options);
}
3. PHP script to update database
Cheers Marc,
perhaps you have a solution for the Opera problem, I mean no one I know uses Opera (I’m happy with IE, FF, NS and Safari compatibility), but I was wondering because the scriptaculous sortable lists have no problems with it and you two are using the same classes… weird.
June 6th, 2006 at 5:31 am
Here’s the PHP function again…
function processRanking($key) {
if (!isset($_POST[$key]) || !is_array($_POST[$key]))
return;
$playlist = $_GET[’playlist’];
$ranking=1;
foreach ($_POST[$key] as $movie_id) {
$query = “UPDATE playlist_content SET ranking = $ranking WHERE movie_id = $movie_id AND $playlist”;
mysql_query($query);
$ranking++;
}
}
}
June 6th, 2006 at 8:43 am
Wow - you’re amazing Greg!
Can anyone give me any tips on saving the list order to a database/cookie and then calling them when the user returns for a later visit. Thanks!
June 6th, 2006 at 9:48 am
@Marc / all - As a quick reminder…I didn’t write any of the scriptaculous stuff, all I did was put up a quick demo showing how it could be used since I thought it was such a useful and elegent set of effects. As for support in other browsers, you may want to check out the official scriptaculous page.
Personally, I’ve only used this stuff for administration-side pages on sites…so I’m fairly confident of the browsers that will be used…I haven’t used this on any publicly accessible site (except for these examples of course)
Greg
June 6th, 2006 at 11:15 am
Hey,
I ‘ve been busy with playing around with this, adding a delete function (for groups and items), auto-update with ajax and more, But i’ll be adding some more functionalityand I’ll show it when it’s ready
The only problem is that I always get the whole thing serialised, and then i have to find out wich one that is updatet (I select everything from the db, and see what is changed.)
So is there a way to only update a item if its updated.
so it calls a page like ajax.php with variables like:
itemid=1
groupid=3
and then I can just update that one…
June 6th, 2006 at 9:04 pm
Hello,
I’ve been looking for something just like this, but i’m wondering if there is a way to submit the final result to a database for a poll / vote?
June 8th, 2006 at 2:23 pm
@camo / all
Hey camo its easy. the function Sortable.serialize gives you an array of the list elements (see debug function as Greg called it).
By doing:
var pars = Sortable.serialize(’group1′);
var options = {method : ‘post’, parameters : pars};
new Ajax.Request(’mySite.php, options);
you can post this array to a PHP site. On the PHP site you can do
foreach ($_POST[’Group1′] as $item) {
echo item;
}
you can work with it.
June 8th, 2006 at 2:28 pm
@ all
I have only 2 lists and you’re able to drag and drop the elements from one to the other.
Now I want to add a button to every list element that onClick moves the element to the last position of the other list (without drag and drop).
Does anyone have an idea of how to implement this?
It might be useful as there are still problems with older browser that don not support the drag & drop functionality.
June 8th, 2006 at 2:35 pm
@Greg
If you replace all list (HTML) content between in the the drag and drop doesn’t work anymore, but after a refresh of the whole page it will do again. It might have something to do with the missing ‘destroy’.
Can you tell me how you worked out the ‘destroy’ in the earlier version of your example (i missed it)? Thx, Marc
June 14th, 2006 at 5:17 pm
Anyone have any idea if it is possible to get automatic scrolling working for these types of sortables? Like when you drag a draggable up past the top of the top of the browser window (or below). Google Notebook seems to have figured out a way to get this working nicely — any ideas? On the scriptaculous site, I think they say that implementing page scrolling is “in progress” — but there’s got to be a way if Google Notebook is doing it…
June 15th, 2006 at 7:50 pm
Never mind, figured it out.
July 5th, 2006 at 3:14 am
Is it possible to drag&drop an lineitem outside a section ?
I tried but without successes
July 5th, 2006 at 8:28 am
@Lichat - scriptaculous allows you to control which elements a draggable may be dropped upon. In my demo I set it up so that it could only be dropped within the various sections that had been defined…
July 13th, 2006 at 3:58 am
Is possible to nest multiple folder?
I’ve tried but the example won’t work…
Tkz
July 19th, 2006 at 12:56 pm
Nice example!
I have a little bug in IE (also your example):
move 3 elements from group1 to group2,
then move the 2nd element back to group1:
the gap between elemt1 and element3 in group2 will not close (as usual) and move down a bit…
any have a solution for this?
July 27th, 2006 at 2:30 pm
@Damon
How did you implement the automatic scrolling?
@Greg / all
Is there any way to “nest” sortable lists. For example; I have a five elements, which are in a sortable list, but within each of these five elements I need to have a list of three child-elements, which need to be able to be sorted within the parent element container. Any ideas?
July 29th, 2006 at 7:30 am
Damon,
I have been unable to get the automatic scrolling option to work properly.
Here’s where I’m at.
I added overflow:scroll to the container class.
I am setting
Position.includeScroll Offsets = true;
in my script just before calling Sortable.create.
The Sortable.create scroll option is set to the value of the container ID.
The scroll bars appear and I am able to add/remove items, but the automatic scrolling (as described in the documentation) doesn’t fire. In others word, the container doesn’t automatically scroll up or down when dragging an item above or below.
A syntax example would be most appreciated.
July 30th, 2006 at 3:41 am
John,
I wanted a particular behavior, where it would scroll a certain speed (and get faster as you neared the top or bottom of the screen), so I did my own home-grown page-scrolling. Basically just detecting where the mouse is on the page during a drag operation, and starting or stopping the scrolling (via setInterval/clearInterval) based on mouse position and mouse-down/up status.
Damon
August 4th, 2006 at 12:38 pm
add scroll:window to your Sortable.create’s to enble scolling of the browser window when dragging
function createLineItemSortables() {
for(var i = 0; i
August 4th, 2006 at 12:43 pm
I’ve been working on adding a new lineitem instead of a new group and I can get it to create the lineitem using:
var newvar = Builder.node(’div’,{id: ‘newassc3′, className: ‘lineitem’}, name);
$(’group_1′).appendChild(newvar);
where group_1 is the group container and newassc3 is the new lineitem.
I’m following that with a destroy and create to “rebuild”.
Getting the group order indicates that something is there but the value is blank instead of the lineitem id
ie:
group1:firstlineitem,
group2:thirdlineitem, fourthlineitem
I’m sure I’m not using the build node correctly but I’ve read everything I could find (which isn’t much)……
tia..dennis
August 4th, 2006 at 9:38 pm
that’s so weird. the last two wordpress blogs i have commented on cut my comments off short. maybe a firefox bug? trying with epiphany now. code snippet should have been:
function createLineItemSortables() {
for(var i = 0; i
August 4th, 2006 at 9:38 pm
guess not…oh well….sorry
August 6th, 2006 at 4:54 am
The sorting list works great. I added onUpdate to Sortable.create but it won’t call the class. Yes, updateOrder exists and yes I can call it with an onClick from another element. Yes the s had IDs. Any idea why it wouldn’t fire updateOrder when dropping an item?
Sortable.create(’priority_list’, { onUpdate : updateOrder });
thanks
August 7th, 2006 at 9:05 pm
When dragging and dropping an item between two sortable lists, I am performing a validation check before the drop. Does any one know how I could, upon failure of the validation, return the draggable item back to its’ original position in its’ original list?
Thanks
Jim,
I had the same problem with the onUpdate callback. The quik fix I found was this…
Sortable.create(’priority_list’, { onUpdate:function(){updateOrder();}});
I have since seen it doe differently, but I still use this method.
August 15th, 2006 at 2:02 pm
Hi,
where can i download the example-sourcecode (http://www.gregphoto.net/sortable/advanced/)?
Thanks and keep on your good work!
Asgard
August 23rd, 2006 at 12:29 pm
Greg, great example, it really helped me to understand the builder class better. I was able to make a php page that grabs sections from a database and also enables the user to create up to 4 subsections. However, I have a few problems I was hoping someone might know how to solve.
1) Can you create a hyperlink with the Builder class. I.E. When an item is created, it has links for edit and delete automatically?
2) Is there a way, when using the Builder - to set it up to a specific node. I.E. On the Group level, I had an add link. When I click this link I want it to add a lineitem to this group, and I would like to have one on each group so that when a lineitem is created, it doesn’t need to be dragged to it’s ’should be’ location.
If anyone has any ideas it was be appreciated.
thanks.
September 1st, 2006 at 2:32 pm
Hi
Great work,greg. Did you tried to have list items in horizontal direction? I added float:left and width:70px to listitem style and have them horizontal. But the section div height isnt calculated correctly. What could be the problem or is this a scriptaculous bug?
Thanks,
Tankut
September 6th, 2006 at 8:57 am
Hi,
I’m having problems trying to get the array passed in a java servlet from the request object. what is the name of the parameter on the server side that contains the new array. My understanding is that it is the same name as the container.
Thanks,
Marcus
September 6th, 2006 at 2:05 pm
Tankut,
I believe the answer to your question is to add
constraint:false
to the Sortable.create call.
Marcus,
Greg’s example stops short of showing how to pass data to the server so you’ll need to devise this yourself. I wrote my own JavaScript function to POST the group and list items.
Peter,
I wasn’t successfully in posting any code either. I believe you need to escape everything manually unless WordPress has a built-in way to do this for you.
October 6th, 2006 at 3:43 pm
Is it also possible to drag and drop lists inside each other.. so you can make a list or list item a new child of another list or item ?
October 17th, 2006 at 6:42 am
Hello,
Did anyone find a resolution to that IE problem that surfaces when you try to click and delete a row?
Thanks.
>>>>>>>>>>>>>>>>>>>
#
Greg says…
June 5th, 2006 at 10:17 pm
@Damon - that certainly is a weird effect - could be a scriptaculous bug. Maybe it has something to do with the fact that Effect.Fade doesn’t remove the element from the page, it just hides it - maybe IE is getting confused somehow. Another thought would be to destroy the sortables before deleting the group and then recreate them after deleting the group.
@John H - correct. I must not have updated the latest version I had on my machine…it should work now though
#
Damon says…
June 6th, 2006 at 12:47 am
Hmmm… doesn’t seem to make any difference. Is there any kind of “refresh” I can do after the fact? Let me know if anyone solves this issue…
December 13th, 2006 at 5:39 am
Hey all,
I’m having a weird IE problem with sortable list within a scrolling div. I think an example would speak better than an explanation so here’s one:
http://thurinusworks.com/experiment/scriptaculous/
Very simple, I’m trying to put a sortable list within a scrolling div. Done the work with the JS, and it works beautifully in Firefox. Throw it up on IE 6 and watch it fall apart. Would anyone happen to know a solution to this? I tried posting to the Scriptaculous wiki for help but it doesn’t seem like the question’s close to grabbing anyone’s attention.
Thanks for any help… like, I’d really really appreciate any help
January 2nd, 2007 at 1:28 pm
I’d like to bump Jay’s issue with the scrolling-div sortable. I’m having the same problem. A solution would be greatly appreciated.
January 2nd, 2007 at 2:48 pm
Jay: I have the solution. I traced the problem to a call to Prototype’s Element.makePositioned() function, which sets the element in question to position: relative. Well, apparently, MSIE6/7 has a bug where a relative positioned element inside a scrolling container rebels against the scrolling arrangement.
A workaround is to set the scrolling element’s own position to relative. I tried this on your demo code and it worked.
See: http://www.webdeveloper.com/forum/showthread.php?t=114891
January 26th, 2007 at 8:07 am
A solution to the groups within groups functionality asked for:
First, I added another array of containers that also included the page itself:
containers = [’group1′,’group2′,’group3′,’page’];
and add this to createNewSection():
containers.push(newDiv.id);
Then I updated the Sortable.create… to look like this:
Sortable.create(’group1′,{tag:’div’,dropOnEmpty: true, containment: containers,only: classes, onUpdate: sortChanged, tree: true, treeTag:’div’});
Sortable.create(’group2′,{tag:’div’,dropOnEmpty: true, containment: containers,only: classes, onUpdate: sortChanged, tree: true, treeTag:’div’});
Sortable.create(’group3′,{tag:’div’,dropOnEmpty: true, containment: containers,only: classes, onUpdate: sortChanged, tree: true, treeTag:’div’});
Sortable.create(’page’,{tag:’div’,dropOnEmpty: true, containment: containers,only: ’section’,handle:’handle’, onUpdate: sortChanged, tree: true, treeTag:’div’});
This allows groups to contain other groups (and links to an update function) as well as lineitems. The important part is the ” tree: true, treeTag: ‘div’ ” - with out this, during the re-creation of the sortables in the createNewSection() function, nested sections will no longer be draggable (but will be dropabble) and the parent section will be draggable but no longer droppable…
Try these additions or if you want the full code, drop me a line at johnnycannuk {at} gee-male dot kom.
March 22nd, 2007 at 12:26 pm
I have the same issue as John H - set the scroll: in the Sortable.create for each container, but when I add an element from one list to another, the scrolling doesn’t work at all, and it does this weird ghosting behavior. Some help would be greatly appreciated.
-E
April 1st, 2007 at 3:45 pm
I’m using a modified version of this demo (thanks Greg!) in my project.
I’m considering upgrading to the latest version of scriptaculous, but before doing so does anyone know if this demo works with it?
Eugene, I’m going to revisit the scrollable div issue and will report back on my progress.
April 13th, 2007 at 7:11 am
[…] Stuff About AJAX Libraries You Wanna Know Drag’n’Drop …uh, no… Sortables Drag’n’Drop in the browser world of AJAX means dragging DIVs and such to different locations on the screen, of which some of those locations can themselves be containers. If you’re looking to rearrange the elements within a container, that is called Sortables. These are container elements (like OL’s and DIV’s) which contain things (like LI’s, DIV’s, and IMG’s), and maintain the order of them. By far the best sortables example I’ve seen was done by Greg Neustaetter and he explains how he did it. […]
June 5th, 2007 at 8:31 am
I need your help…
I’ve made the dragables / dropables in a parent / child hierarchy. You can now drag / drop groups within each other. Dandy…
But, if you drag / drop 2 or more within each other, and then dynamically add a new item, the ones with a parent / child relationship get stuck and cant be separated any more…
Ex. If you Drop Group 2 in to Group 1, and drop Group 3 in to Group 2 and add a new group 5, you cant remove Group 3 out of Group 2, or Group 2 out of Group 1, they are stuck… If you click on Group 3, you start pulling Group 1?
Try it over here:
http://www.vplavevski.com.mk/test/test.htm
Please let me know if you have a remedy for this?
July 9th, 2007 at 10:10 pm
Hi Greg,
Could you provide a working sample of the advanced drag n drop list?
The facility is exactly what we need, but time is tight at the minute…
Thanks in advance,
Matt
August 1st, 2007 at 5:49 pm
Change group# to group_#
September 8th, 2007 at 12:19 pm
Hello Greg,
Should be a fairly easy question for ya…. In the getGroupOrder() => sections.each loop for debugging this, how would I get the h3 handle name to display rather than the section.id?
Thanks!
October 28th, 2007 at 2:23 pm
Is it possible to allow elements to be dropped onto the page itself aswell as sections?
November 23rd, 2007 at 8:01 pm
So I have everything with the dragability working, I just cannot figure out how to update my database, here is the JS I used:
/*
Debug Functions for checking the group and item order
*/
function getGroupOrder() {
var sections = document.getElementsByClassName(’section’);
var alerttext = ”;
sections.each(function(section) {
var sectionID = section.id;
var order = Sortable.serialize(sectionID);
alerttext += sectionID + ‘: ‘ + Sortable.sequence(section) + ‘\n’;
});
return false;
var options = {
method : ‘post’,
parameters : Sortable.serialize(’alerttext’)
};
new Ajax.Request(’reorder.php’, options);
}
Here is the PHP code:
$value) {
$sql= “UPDATE menuitems SET (menuType,menuOrder) VALUES (’$value’,'$i’)”;
if (!mysql_query($sql,$connect))
{
die(’Error: ‘ . mysql_error());
}
$i++;
}
?>
I don’t know how to test if the PHP is even getting the results over to it.
November 28th, 2007 at 8:46 pm
Hi Greg,
Found you articles and excellent example on Sortables really useful, thanks for spending the time. I had a need for the boxes to be horizontal and went on my own little journey getting it to work, which I’ve blogged. I couldn’t find any horizontal examples in my endless searching so I’ve extended your example with credit to yourself. Hopefully it will help someone else.
My extension into horizontal Sortables: http://blog.richardchurchill.co.uk/post/2007/11/Scriptaculous-Drag-And-Drop-Sortables-a-horizontal-example.aspx
Many Thanks
February 11th, 2008 at 9:52 am
Has anyone managed to add a delete item from the list working? If so can you post the code?
I tried adding a checkbox to the list items so that I could select multiple list items and then a submit button to delete the selected items, The problem is that I cant get the check boxes to work when they are in the list, when you click on them nothing gets checked. (the same thing happens with the test/demo scripts, the check boxes are not selectable)