How to Integrate Extjs Tree Panel Drag And Drop Into Extjs HtmlEditor

This is a problem that i face during an integration with Extjs Tree Panel drag and drop functionality into extjs htmleditor. The research process doesn't take very long because the only clue online was extjs forum with the title "Drag and drop into child iframe document". Many said it was impossible. But there were actually people who had done this previously and successfully drag and drop tree panel items into extjs htmleditor. However, many will be clueless without a proper demo or actual code to see the effect of such implementation.  The forum page do exist code that could be of help in your implementation but you would really need to guess and try to see whether it works. In my case, i manage to get it work.

Htmleditor Problem

The problem was fairly straight forward. The drag and drop functionality in extjs cannot drag into iframe. Our Extjs htmleditor is using iframe for their editor implementation. Therefore, if you try to drag your items into the iframe, it will basically stuck somewhere outside of the htmleditor/iframe. Drop is also an issue since the drop behavior is being stopped by the implementation done by the htmleditor. Now, our objective here in this article is to make it so that the drag and drop will work within the iframe.

Drag and drop into htmleditor Solution

The solutions here is to overwrite the behavior of the htmleditor so that it accept the drag items into the iframe. This can be done using Extjs Event manager as shown below,

pushValue: function(){
	var ddm = Ext.dd.DragDropMgr;
	Ext.EventManager.on(this.iframe.contentDocument, "mousemove", ddm.handleMouseMove, ddm, true);
	Ext.EventManager.on(this.iframe.contentDocument, "mouseup", ddm.handleMouseUp, ddm, true);
},

The above code utilized htmleditor pushValue functionality to overwrite two behavior on extjs htmleditor. mousemove and mouseup is overwritten with the default behavior of Ext.dd.DragDropMgr. This will allow the behavior to properly mouseover the htmleditor content and also drop it accordingly. Once you have done that, your treepanel items should have no problem dragging around the htmleditor. However, drop will still be an issue since we haven't attached the appropriate drop zone into the htmleditor.

DropZone on Htmleditor

In order to drag the items on the treepanel into the extjs htmleditor, we will definitely needs to define a dragzone which is similiar to the dragzone on the treepanel. However to create a dragzone, the component must be initialized before any attachment can be done. Hence, we will create a listeners on htmleditor to see when it is render so that we can attach a dragzone into it.

listeners: {
	'render': function(){
		var DCZone = new Ext.dd.DropZone(Ext.get('ext-gen10'), {
			ddGroup: 'DCZone',
			/* If the mouse is over a target node, return that node. This is
			provided as the "target" parameter in all "onNodeXXXX" node event handling functions */
			getTargetFromEvent: function(e) {
				//console.log('getTargetFromEvent'+new Date().getTime());
				return e.getTarget();
			},

			/* On node drop, we can interrogate the target node to find the underlying
			application object that is the real target of the dragged data.
			We can use the data set up by the DragZone's getDragData method to read
			any data we decided to attach. */
			onNodeDrop : function(target, dd, e, data){
				console.log('onNodeDrop');
				// do your work here

				Ext.fly(this.getEl()).frame("00AE00");
				return true;
			}
		});

	}
}

Now, the important part here for our htmleditor iframe to work so that the drop items will land on it is the overwrite function of getTargetFromEvent. If this function doesn't exist, the whole thing must not work. Therefore, the method is important to have. Ext.get('ext-gen10') is the parent element of the iframe. Once this are all done properly, you should be able to get an iframe that is draggable and droppable into it.

 

Solution Demo

Like i have mention, a demo will be much more appropriate. Hence, here's an attachment of what i have been saying.

Tutorial: jQuery Live With ExtJs

For all jQuery user out there. We are all fully aware that there is a function 'LIVE' in jQuery which sole purpose is to attach event handler into any new element entering the page dynamically. This is very clear and obvious in jQuery. However, in ExtJs it will be a little bit more confusing than you think it will be. Hence, i would like to drop this down on this article on the way ExtJS works.

jQuery Live Event

Before i come to the main point, let's look at how jQuery Live event works.

var event = function(){
alert("action clicked")
}
jQuery("p").live("click", event);

Simple and clear. We know what it does so i won't bother to explain.

ExtJs Live Event

How about ExtJs live event? Unfortunately, in Extjs this is not so direct. There are also tricks you should know in order to achieve the same functionality in Extjs. In Extjs, it is as simple as an event attachment as shown below,

var fblike_hide = function(ev, target){
	var item = Ext.get(target).findParent("#facebook_container", 50,true).setDisplayed("none");
}
Ext.getBody().on("click", fblike_hide, this, {delegate: ".fb_cancel"});

The above code shows two things. The method that was triggered upon a click event which is "fblike_hide" and the 'delegate' key used on the 'on' event attachement. The important here is the delegate. Extjs uses delegate to mimic the same behavior as 'LIVE' in jQuery. Of course, jQuery itself also has delegate method but i won't show here since i'm talking about jQuery Live.

In pure english the below sentences means,

Ext.getBody().on("click", fblike_hide, this, {delegate: ".fb_cancel"});

"Attached click event on all .fb_cancel element that can be found within the body tag. Fire 'fblike_hide' when click event is triggered on any element with the class 'fb_cancel'". The trick to use delegate in Extjs is to understand that the event click is attached to all element of .fb_cancel and not the body! The body doesn't get attached with a click event when the delegate key is used! If you are familiar with delegate in jQuery, this should be quite obvious but if you don't, you might get a little bit confuse by Extjs delegate functionality.

Hope it helps!