Opened 12 years ago
Last modified 7 years ago
#6054 open bug
Sortable: cancel method cannot be called in a beforeStop event handler
Reported by: | tos1121 | Owned by: | tos1121 |
---|---|---|---|
Priority: | minor | Milestone: | 2.0.0 |
Component: | ui.sortable | Version: | 1.8.4 |
Keywords: | parentNode | Cc: | |
Blocked by: | Blocking: |
Description
line 1032 on "jquery.ui.sortable.js"
this.placeholder[0].parentNode is null in some condition.
[WRONG] this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
[RIGHT] if(this.placeholder[0].parentNode)
this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
thank you! --- Node.parentNode(Mozilla develop center) https://developer.mozilla.org/En/DOM/Node.parentNode
Change History (15)
comment:1 follow-up: 2 Changed 11 years ago by
comment:2 Changed 11 years ago by
Replying to scott.gonzalez:
Can you provide an example of when this occurs?
Yes, This is the sample program.
comment:3 follow-up: 4 Changed 11 years ago by
Owner: | set to tos1121 |
---|---|
Status: | new → pending |
I'm not seeing any errors in the example.
comment:4 Changed 11 years ago by
Status: | pending → new |
---|
Replying to scott.gonzalez:
I'm not seeing any errors in the example.
I'm sorry, I mistook to tell you #6873 and #6054.
-- 「Table header sorting on Chrome break layout」 http://bugs.jqueryui.com/ticket/6873
I'll comment later about this topic.
comment:5 Changed 11 years ago by
This issue still exists. I've created a simple test case at http://jsfiddle.net/zVpn5/1/
Tested with the following browsers:
- Google Chrome 12.0.742.122 (Windows 7)
- Firefox 5.0 (Windows 7, Mac OSX)
comment:7 Changed 10 years ago by
Based on a comment on http://forum.jquery.com/topic/problem-with-sortable-4-10-2010 I was able to narrow this down a bit.
If you provide a beforeStop callback, and the callback returns false (for instance, to disallow a drag operation based on business rules), this error will happen. Additionally, since there is no error handling in this code, once the error happens stop() is never called. This makes it very challenging to hook behavior on the beginning/end of drag operations.
There is a workaround. If beforeStop() has no return value, everything appears to work as expected. Simply using stop() for the whole operation may not suffice because some fields (eg, ui.helper) get cleared between these two calls. In that case, if you perform your checks in beforeStop() and return the value from stop(), then you can still cancel the actions, and you don't get the error.
comment:9 Changed 10 years ago by
Milestone: | TBD → 2.0.0 |
---|
comment:10 Changed 10 years ago by
Status: | new → open |
---|---|
Summary: | "this.placeholder[0].parentNode is null" on sortable line 1032 → Sortable: "this.placeholder[0].parentNode is null" |
comment:11 Changed 9 years ago by
Summary: | Sortable: "this.placeholder[0].parentNode is null" → Sortable: cancel method cannot be called in a beforeStop event handler |
---|
Test case against master - http://jsfiddle.net/tj_vantoll/dk9A4/.
The issue only occurs if you call the cancel
method in a beforeStop
event handler so I'm changing the description to be more indicative of the problem.
The error occurs on this line of the _clear
method:
this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
comment:13 Changed 9 years ago by
in IE8 the following statement fails:
if(this.helper[0] !== this.currentItem[0]) {
and needs to be changed to:
if(this.helper!==null && this.helper[0] !== this.currentItem[0]) {
comment:15 Changed 7 years ago by
I'm also experiencing this bug.
In my case I'm just returning a false from beforeStop
callback so
The issue only occurs if you call the cancel method in a beforeStop event handler so I'm changing the description to be more indicative of the problem.
while it is true, it also happens because returning false from beforeStop makes jQueryUI call the cancel
method internally.
The point is _clear
method is trying to remove the placeholder parent without checking if this parent still exists:
//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
A simple check would fix this.
if (this.placeholder[0].parentNode) { //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! this.placeholder[0].parentNode.removeChild(this.placeholder[0]); }
Can you provide an example of when this occurs?