Link to home
Start Free TrialLog in
Avatar of DrData68
DrData68

asked on

Drag and Drop between 2 list boxes in Javascript

I want to have the ability to drag and drop between 2 list boxes. If one selection is dragged to other list box, I want the original selection removed.  Conversely, I also want to drag in the opposite direction. So if I have a selection in the second list box and I drag it back to the fist, I want it to be removed from the second list box.  Optimally, if I can have it sort alphabetically by the selections, that would be great.  I need this to be compatible with IE and NS.  

Hope this is clear - thanks for the help.

DD
Avatar of StormyWaters
StormyWaters
Flag of United States of America image

Don't know about drag and drop, but this works just as well. Probably nicer:

http://www.mattkruse.com/javascript/optiontransfer/
Avatar of DrData68
DrData68

ASKER

I am actually a fan of Matt- I used some of his Javascript before, but I really wanted to get the drag and drop thing going as well as the buttons.  

DD
Consider why you want drag-and-drop. Is it because it's "cool," or is there a valid user-interface reason for it?
My suggestion is to just keep it simple. What are you trying to accomplish with drag-and-drop, exactly?
I am thinking that I might try and get some sorting going in the list boxes, so it might be name, state, group. So if they want to pull 10 to 20 names from a particular state over, I do not want them to have to click 20 times.  If they resort, I only want to see the remaining selections, and if they want to pull another 20 or 30 people over that belong to a certain group - again, I do not want them to click 20 times.

Make sense?
Since this was an interesting puzzle, I spend a few hours on it - not just to answer your question, but also as a form of geek-entertainement. I have to report that this is probably not going to work as straight-forward as you may have expected it.

First, I got it working fine in Mozilla-based browsers for single list elements, and it's actually pretty cool to click on a list element and be able to drag it to the other list - I even painted the list element itself next to the mouse pointer.

Then the problems started. When testing the finished code in IE, it turned out that the build-in event handler that actually changes the selections of the list gets executed AFTER the event is passed to my custom event handler. So when a user holds down the mouse button on an element in that list, that list's selectedIndex property is not updated when I read it. I tried some hackery with delayed evaluation of the list's selected items, but I would have to delay over 500 ms for that to work, and that makes the whole thing unusable from an interface-experience-perspective. Moreover, the <option> tag in IE does NOT support the onMouseDown event, which was what made it work in Firefox/Mozilla. There may be a possibility with some other hackery to get it working for a single element, but that was not what you wanted anyway.

You wanted drag and drop on multiple elements. Although I was able to write the logic for that to happen in Mozilla & Co., the user will never be able to do it and here is why: When you give a list field the ability to have multiple options selected, you can perform this selection by holding the mouse down and moving it accross the items you want to select. Unfortunately, that is the same process you would use to get it dragged. So everytime you try to grab on to a selection, instead of you being able to drag it, the browser will just start a new selection. I was not able to simply cancel the event after I handled it in Mozilla, and because of IE being screwed up with the simple stuff, I did try there either.

Although the idea is great, its implementation may prove more difficult. There is an entirely different approach that would be much easier to implement and could be made to work cross-browser fairly easily. Instead of using a real form field list element, a scrollable list could be simulated with a <div> containing <span>s or <p>s and having its overflow property set to auto, making sure none of the contents in the div can be wider than the div itself. The simulation of the list-behavior would be handled entirely in JavaScript, updating hidden form fields with the actual internal values for which items are in which list. Let me know whether you think this approach would be worth your 500 points and I give it a try.
ASKER CERTIFIED SOLUTION
Avatar of cwolves
cwolves

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
cwolves - this is nice.  Is there any way I can get multiple selections going?  I am anticipating a pretty large list,
and if they have the ability to do a multiple select of 20 or 30 at a time and drag it - that would be great!!

Thanks,
DD
not easily.  how well do you kow JS?
I would classify myself as high intermediate to lower advanced.
What do you suggest?
basically, 'e' in that code is the selected div tag.  in the mousedown function, you can check the event.ctrlKey property and if it's true, make 'e' an array and add event.srcElement to it.

'h' is the "ghost" element (it's the semi-transparent div tag that actually moves around when you drag the mouse).  Set that to e[0].

And on the mouseup tag, loop through each element in e instead of just referencing e in the try{} statement.

I'd do it myself but I have -no- time today, especially not to debug it  :-/
Let me take a look at it and see what I can do.
DrData, we wouldn't mind seeing the finished product ;-)
I agree.  I got pulled onto other things, so I have not done too much with it.
DrData68, do you need more help regarding this question?
Yes, that would be great!!!
Well, any specific questions? As I pointed out, doing what you where trying to do with actual <select>s is not going to work. Did you try cwolves' approach?
I tried playing with the HTML first and started going in the wrong direction.  I just reread his message and understand that I have to add code to the mouse down event.  Looking at it, i am not sure how to handle the code for the determining the className equal to 'Drag' if I have multiple selections and e is an array.  Any ideas?