Search and Top Navigation
#6807 closed bug (notabug)
Opened January 05, 2011 12:34AM UTC
Closed January 05, 2011 12:38AM UTC
Last modified January 05, 2011 01:32AM UTC
Draggable DOM Helper Deleted - Causes JS Errors on Next Drag
Reported by: | taitems | Owned by: | |
---|---|---|---|
Priority: | minor | Milestone: | 1.9.0 |
Component: | ui.draggable | Version: | 1.8.7 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
I found this odd bug when experimenting with jQuery UI draggable and droppable.
JSFiddle is located here: http://jsfiddle.net/RBzUa/1/
Essentially, I read online how to specify an existing DOM element as a helper by using the function argument (and using a return). This can be done for many reasons: in my non-fiddle case we need to show an icon in the helper and the helper has been constructed elsewhere in plain html.
On line 437 of jquery.ui.draggable.js the object is removed once it has been used. The next time you try and drag this object (and its helper) it will throw an error because the object can no longer be found.
Firefox shows:
this.offsetParent[0] is undefined
While Chrome shows:
Cannot read property 'tagName' of undefined
For now I can get around this issue by doing an "if exists" check in the function - but recreating the DOM every time is a pain. The alternative to this is using a clone, but for more complex structures this may become troublesome. There are certain tricks to get around this bug, for sure, but I thought I should draw this to your attention as I couldn't find anything online.
Attachments (0)
Change History (6)
Changed January 05, 2011 12:38AM UTC by comment:1
resolution: | → invalid |
---|---|
status: | new → closed |
Changed January 05, 2011 12:43AM UTC by comment:2
Yep, that's my diagnosis - but should this be a feature request for the future? Allow a selector to be passed in the helper argument?
Changed January 05, 2011 01:04AM UTC by comment:3
The jQuery UI team had an API design meeting a few months ago where we reviewed the API of all existing plugins. Here are the relevant notes about draggable's helper option:
keep helper (though try to find a better name), but change values
change "original" to false, meaning don't use a helper
change "clone" to true, meaning use a helper (that its cloning the original element is just an implementation detail, can be mentioned in the docs)
keep the function argument for customizing the helper
I don't think the use case for using existing DOM elements is that big. Cloning an existing element should work fine (and is easily implemented using a function). I'm not sure why you said "recreating the DOM every time is a pain." What is painful about it?
Changed January 05, 2011 01:14AM UTC by comment:4
My specific scenario involves showing whether a CMS component is being inserted or moved, the icon of the component and the name of the component. Considering it's also for an enterprise web app, my helper's rounded corners require extra HTML and CSS to work in older versions of IE. Below is a rough replication of the HTML, which is why I think it lends itself more to a clone() or tmpl() rather than a "from scratch" creation.
<div id="mouseFollow"> <div> <span></span> <span><img /></span> <span></span> </div> </div>
I'm glad you could share the team discussion notes with me as it gives me a clearer picture. Thanks for the help Scott :)
Changed January 05, 2011 01:30AM UTC by comment:5
Sure, you could easily do:
$( elem ).draggable({ helper: function() { return $( "#mouseFollow" ).clone().removeAttr( "id" ); } });
or use .tmpl()
instead of .clone()
as you've said.
You could probably even build an extension that accepts a selector, but my main concern would be people not realizing that internally the extension would do a clone on the element found by the selector and they might end up with duplicate ids.
Changed January 05, 2011 01:32AM UTC by comment:6
Also, the notes from the design meeting are gradually being posted on the blog and forum for feedback. It'll still be a few weeks before we get to draggable.
The helper isn't meant to work that way. The helper is always removed after the drag and therefore you're not returning a valid helper on the second drag.