Tuesday, February 10th, 2009

Drag and drop your widgets in a portal with Shindig and Dojo

Category: Dojo, Showcase

<p>Matthew Russell has taken Shindig, an OpenSocial implementation, and added the shine that you need in a portal including drag and drop of the components.

Click the image above to see it in action. Matthew posts some of the details of the implementation:

  • When doing anything like this, you need infrastructure. For this part of the project, Dojo streamlined tons of things like setting up event handlers, styling nodes, getting coordinates on the screen, abstracting a lightweight fabric for drag-and-drop operations, and so forth. Currently, the code uses AOL’s CDN to keep things nice and simple, but you’d definitely want to use the build tools to consolidate and minify the code when it’s game time.
  • When an IFRAME is inserted into the DOM, it (re)loads. So, when you’re dragging an IFRAME all over the screen, its location in the DOM doesn’t change and it doesn’t continually reload because it’s just being positioned absolutely. It’s when the drag event ends that you’re faced with the reload event because you want to move it into its new column (versus trying to maintain the geometry of never manipulating the DOM tree and keeping track of everything in a snap-to-grid fashion.) Anyhow, that’s the approach we took. The one reload event that takes place when the gadget being drug reaches its final destination seemed more reasonable than all of that geometry. Other than the frame getting drug around, no other IFRAMES ever get removed and reinserted, so they never have to reload.
  • For security reasons, Shindig renders gadgets inside of their own individual IFRAMEs versus rendering gadgets in an element like a DIV. That may not sound like a big deal, but it does bring up a few more implementation details worth noting. The first one that comes to mind is that when you’re dragging a DIV that contains an IFRAME, it’s not uncommon for the mouse to occasionally slide ever so slightly into the IFRAME. Unfortunately, the IFRAME then captures mouse events, and then drag-and-drop starts to get choppy and wig out a bit. You can work around this by creating a transparent overlay and placing it on top of the IFRAME during drag events so that the IFRAME can never capture those mouse events. Overlays also come in handy when you popup menus on the titlebar and want them to disappear when the user clicks anywhere else on the screen (including in other IFRAMEs.) One day, hopefully, Caja will kill those IFRAMEs, which will also probably help performance a bit (especially on IE.)
  • There are a few peculiarities that arise when you remove the last element from a container like a DIV, so one way you can deal with this is to ensure it always has a minimum height and width by placing an element in there that spans the width of the column and has a minimal height so that it can accept drag events.
  • As always, there are always a few special cases, so you have to do a little extra bookkeeping here and there. Hopefully the code is commented well enough that it’s not hard to follow. All in all, it’s only about 150 lines for the drag and drop mechanics, including whitespace.

All of this work has been done for Life360.

Posted by Dion Almaer at 6:21 am

3.8 rating from 23 votes


Comments feed TrackBack URI

@nunziofiore – I totally agree about not liking the iframe. But that’s the way Shindig’s default gadget implementation works, so I had to roll with it. We’re also working on some R&D (as time allows) to use Caja to get rid of the iframes all together, but there’s a bit of work involved in doing that because you have to get all of the gadgets.* libs cajoled along with any other infrastructure you use like Dojo or some other jstoolkit. Using Caja would also likely make the performance a little better on IE (I hope.)

Comment by ptwobrussell — February 10, 2009

@ptwobrussel i didn’t know Caja, thank you for the suggestion.. Your work is complete of server side management, if I well understood.. I didn’t want to criticize your work… it’s a nice idea.. and I downloaded it and i will saw it tonight, when I’ll became neo… now I’m at work.. where I’m Mr Anderson…

Comment by nunziofiore — February 10, 2009

Internet Explorer actually has a couple nice element attributes, setCapture() and releaseCapture() that you can use to keep the iframes from capturing the mouse activity while you are dragging the windows around. I’d love to see these added to the HTML5 standard.

On mousedown you just set myDragHandle.setCapture(), and then on mouseup, myDragHandle.releaseCapture(). For all the other browsers I use the overlay hack mentioned above, though IE solution in this case is much preferred.

Comment by GregHouston — February 10, 2009

Leave a comment

You must be logged in to post a comment.