Years ago, I implemented some code that allowed the user to drag one or more HTML elements from locations within one iFrame (or Frame) and drop them into a droppable location within the same iFrame or another.
I wrote this code using HTML4, JavaScript, jQuery, and jQuery UI. It proved to be compatible with Firefox, Chrome, and IE 7+, and it worked quite well. The same technique should work with HTML5 and newer versions of jQuery and jQuery-UI as well.
This article explains how I did this.

Dependencies
This requires two iFrame windows within one browser viewport, all three containing JavaScript, jQuery, and jQuery UI code for this to work.
Scenario
I will explain how to drag the contents of one or more (via multi-select) html <div> elements (contains jQuery-ui draggable class) such as a table row from one iFrame and drop it into a droppable location in another iFrame within the same browser viewport as the source iFrame. This could be a form field, for example.
NOTE: The domain of both iFrames must be the same as the domain of the parent viewport. This is because it is not possible to access cross-domain information through the DOM, and this is a security restriction implemented in every browser.
The Sequence
- Create a table in the source iFrame and make some rows jQuery-ui draggable elements by intializing them as jQuery-ui draggable elements. By doing so, these elements will then have a “ui-draggable” class added to them.
- In the destination iFrame, create a text box and make it a jQuery-ui droppable element. This will result in a class called “ui-droppable” to be added to it.
- Within the context of the iFrames that contain draggable or droppable jQuery-ui elements that you wish to do cross-iFrame dnd with, write Javascript and jQuery code that enables a hidden <div> element that covers the entire viewport of the main viewport only when the mouse pointer is over a draggable or droppable html element in the corresponding iFrame. We will call this the iFrame mask from now on, and this will be used to catch mouseup and mousedown events in the parent context of the iFrame and forward them to the underlying iFrame viewport via the jQuery trigger() method. It should also contain html for an empty jQuery-ui draggable element. The draggable html content from the iFrame context will be copied to this in a step shown below.
- Write within the context of the main viewport, a mousedown() event handler that calculates the mouse pointer coordinates relative to the iFrame viewport and then, only if the mousedown event is over an iFrame viewport, disables the iFrame mask, sends a mousedown event to the iFrame viewport via a jQuery trigger(‘mousedown’, <coords>) method call, and then re-enables the iFrame mask.
NOTE: When the jQuery.trigger mousedown event is received by the jQuery-ui library, the empty jQuery-ui draggable element that is located within the iFrame mask should now be activated as draggable. You should double-check this with your versions of jQuery and jQuery-ui before continuing this DnD implementation.
- When you hover over a draggable html element located in the source iFrame viewport and press and hold down the mouse button, the mousedown event will be sent to the iFrame viewport via your mousedown event handler code in the previous step, and this will trigger a mousedown event in the iFrame viewport.
- In the iFrame context, write some Javascript and jQuery that binds an event listener to the jQuery-ui draggable.drag event, where this event will trigger a call to a function that checks how many draggables are selected, and if there is only one selected, replace the parent viewport’s jQuery-ui draggable with the html that is within the draggable element. This function should also extract the droppable values from within the draggable html and then attach them to the draggable element <div> in the main viewport context via a jQuery data() method call.
- If there is more than one draggable selected, this is a multi-select situation, and rather than using the copied html for this main viewport draggable, a box with the number of selected draggables should be used instead.
NOTE: To maintain a consistent format if the draggable element’s graphics and text positioning should change in the future, hide the draggable data at the root of its corresponding html element when generating the iFrame html.
NOTE: I copied the iFrame draggable’s html to be a draggable image in the main viewport’s context by calling a function such as window.parent.setDraggable(draggableHtml, draggableData, numOfDraggables). This function set the main viewport draggable image via $(‘#draggable’).html(draggableHml) for example, with the html being a box with numOfDraggables shown inside it if numOfDraggables was > 1, or set to draggableHtml if numOfDraggables was equal to 1. It also saved draggableData to the draggable image <div> via a jQuery data() method call.
NOTE: The dragged image in the main viewport context looks better if it is semi-transparent. You can just use CSS for this.
- The received mouseup event in the destination iFrame viewport will trigger a jQuery-ui droppable.drop event which will then run an event handler where you should write code to update the textbox with the draggableData. If this forced jQuery.trigger mouseup event does not trigger a jQuery-ui drop event, then instead you may need to call it directly via $jQueryUiDroppableElement.trigger(‘drop’, {}) or a variant of this, for example.
- Keeping the the mouse button down, move the draggable image out of the originating iFrame (actually, from the iFrame mask) and into a jQuery-ui droppable location within the destination iFrame viewport (actually, over the iFrame’s hidden <div> mask). In this case, it will be the textbox.
- Release the mouse button over the textbox. At this point, the Javascript and jQuery code that you need to write in the main viewport’s context will catch the mouseup event over the destination iFrame mask. The corresponding mouseup event handler that you need to write disables the mask, pushes the mouseup event to the iFrame viewport via a jQuery.trigger(‘mouseup’, draggableData) call that is pushed to the iFrame viewport context, and then re-enables the mask.


