Thursday, March 12, 2009

Cross-browser drag and drop “ListBoxes” using jQuery.

My latest project involved creating a public facing website on top of Microsoft Sharepoint. For one of the custom administrative pieces, I determined that drag and droppable lists provided the best solution for managing collections of objects. However, I ran into several problems while trying to implement this using jQuery with support for all browsers.

The ideal option was to use an ASP.Net ListBox. This control is rendered as a select html element, with all of the ListItems rendered as html option elements. Unfortunately, I quickly learned that this was a limiting factor in what I was trying to accomplish. It is not possible to bind events to option elements in any browser except Firefox. Therefore the following jQuery statement does not work in most browsers:

$(“option”).draggable();

After discovering this limitation, I decided to use ASP.Net BulletedList controls. These controls are rendered as unordered list elements (<ul>), with each ListItem rendered as an html listitem element (<li>). Internet Explorer, Chrome, Safari and Firefox all support binding events to ListItem elements. Therefore, the following statement was possible in all browsers:

$(“li”).draggable();

Now that I had discovered how to get jQuery’s drag and drop working for lists, my next goal was to create a decent looking user interface. I needed to somehow get my unordered lists to look similar to a standard ListBox.

After some googling, I stumbled upon a great jQuery plugin, jScrollPane (not to be confused with a Java jScrollPane!). jScrollPane allows you to convert div containers to fully customizable scrollable boxes. Implementing jScrollPane is incredible easy as well. All that is required is calling .jScrollPane() on the div element you want to convert.

Now that I had created a “ListBox” with draggable items, the final step was implementing droppable for my jScrollPane’s. My layout consisted of a jScrollPaneDiv containing a SelectedItemsDiv. Within the SelectedItemsDiv, there was a <ul> with the id of SelectedItemsList. With this setup, the following jQuery snippet created a droppable container within my jScrollPane.

   1: $("#SelectedItemsDiv").droppable({ 
   2:     accept: 'li', 
   3:     hoverClass: 'ui-state-hover',
   4:     drop: function(event, ui) {    
   5:         (ui.draggable).clone().appendTo("#SelectedItemsList");
   6:     } 
   7: });    
I hope this helps some of the issues and requirements for implementing drag and droppable lists using jQuery. If anyone has any questions or would like to get a more complete example, feel free to leave a comment!

Thanks.

11 comments:

  1. Hi Dave
    This is exactly what I am looking for.
    Can you send me a complete example?
    ikarbary@gmail.com

    ReplyDelete
  2. This looks absolutely splendid. Thanks for the tip.

    Can you confirm for me, though, that after dragging items from one list to another, users will be able to properly post the modified lists back to the server? Any advice with respect to this is much appreciated.

    ReplyDelete
  3. Can I have a copy of the example too? stanleycn@hotmail.com.

    ReplyDelete
  4. This looks great. Could I get a copy of the example?

    ReplyDelete
  5. This is a nice article..
    Its very easy to understand ..
    And this article is using to learn something about it..
    asp.net, c#, javascript
    Thanks a lot..!

    ReplyDelete
  6. If you still have this around I'd like to see your code. If your still using the control have you upgraded to jQuery 1.6.2? I can't seem to get it to work here. mcmcne01@gmail.com

    ReplyDelete
  7. Hi , I need the files. Please send me that.

    This is my email Id: pan.sathish@gmai.com

    ReplyDelete
  8. hello ... please give me complete code ...Please

    Thanks.

    ReplyDelete
  9. I have just discovered jQuery and feel so much behind the times. Please add me to the list of people who would like a copy of the source. :)

    ReplyDelete
  10. can you publish the whole code for this functionality or send it to boubaker@gmx.com? Thanks

    ReplyDelete