-
-
Save Craga89/8219459 to your computer and use it in GitHub Desktop.
// Create new object to cache iframe offsets | |
$.ui.ddmanager.frameOffsets = {}; | |
// Override the native `prepareOffsets` method. This is almost | |
// identical to the un-edited method, except for the last part! | |
$.ui.ddmanager.prepareOffsets = function (t, event) { | |
var i, j, | |
m = $.ui.ddmanager.droppables[t.options.scope] || [], | |
type = event ? event.type : null, // workaround for #2317 | |
list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack(), | |
doc, frameOffset; | |
droppablesLoop: for (i = 0; i < m.length; i++) { | |
//No disabled and non-accepted | |
if (m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0], (t.currentItem || t.element)))) { | |
continue; | |
} | |
// Filter out elements in the current dragoged item | |
for (j = 0; j < list.length; j++) { | |
if (list[j] === m[i].element[0]) { | |
m[i].proportions().height = 0; | |
continue droppablesLoop; | |
} | |
} | |
m[i].visible = m[i].element.css("display") !== "none"; | |
if (!m[i].visible) { | |
continue; | |
} | |
//Activate the droppable if used directly from draggables | |
if (type === "mousedown") { | |
m[i]._activate.call(m[i], event); | |
} | |
// Re-calculate offset | |
m[i].offset = m[i].element.offset(); | |
// Re-calculate proportions (jQuery UI ~1.10 introduced a `proportions` cache method, so support both here!) | |
proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; | |
typeof m[i].proportions === 'function' ? m[i].proportions(proportions) : (m[i].proportions = proportions); | |
/* ============ Here comes the fun bit! =============== */ | |
// If the element is within an another document... | |
if ((doc = m[i].document[0]) !== document) { | |
// Determine in the frame offset using cached offset (if already calculated) | |
frameOffset = $.ui.ddmanager.frameOffsets[doc]; | |
if (!frameOffset) { | |
// Calculate and cache the offset in our new `$.ui.ddmanager.frameOffsets` object | |
frameOffset = $.ui.ddmanager.frameOffsets[doc] = $( | |
// Different browsers store it on different properties (IE...) | |
(doc.defaultView || doc.parentWindow).frameElement | |
).offset(); | |
} | |
// Add the frame offset to the calculated offset | |
m[i].offset.left += frameOffset.left; | |
m[i].offset.top += frameOffset.top; | |
} | |
} | |
}; |
Updated code to clean up and fix some small issues with previous fix.
Great work man!
I have forked your work, but I can't make an pull request.
I try to use your fix for more iframe drag and drop, but I found an issue: it uses always the offset of the first registered iframe. The problem is in the storing of the offsets. I have changed the '$.ui.ddmanager.frameOffsets[doc]' in '$.ui.ddmanager.frameOffsets[frame.id]' where frame is the frameElement. Give a look to my fork for see the code ;-)
Great!
save me a lot of time. Thanks.
Hi Craig,
Can you specify what version of jQuery you targeted with this fix? It's not clear from your post.
thanks
EDIT: Author originally posted about this on his blog, here: http://blog.craigsworks.com/jquery-ui-draggable-droppables-in-an-iframe/
Specifically this fix was for jquery UI 1.8+
This is a great fix and saved me a lot of issues. There's just one further fix I made to it - in my app I drag elements both into an iframe from the main doc, and within the iframe itself. The current code will apply the offset fix to elements dragged inside the iframe, causing an over-correction to the other side.
The solution is simple - instead of checking whether the droppable is in a different document than the main doc, compare it to the draggable element's document:
Replace line 48 with this:
var draggableDocument = t.element[0].ownerDocument;
if ((doc = m[i].document[0]) !== draggableDocument) {
Some times I get this weird error
Uncaught TypeError: Cannot read property 'ddmanager' of undefined
Anybody has fix?
Hi, I have some issues in droppable for example i have a iframe that is having inside mouse move event and parent page having draggable elements after using iframefix true, i am able to over the inside iframe droppable area but mouse move event not working
@karlhenselin not sure what you mean. If you share a reduced test case on codepen.io or similar, we might be able to help.