PDA

View Full Version : Drag Source not working with extjs 3.4. Works fine with Extjs 3.0.



Pratik_Patel
25 Jun 2013, 3:04 AM
I am trying to achieve drag and drop with dragSource of Extjs.
User should be able to select the text and drag and drop it in the drop zone. I create a drag source instance when user selects some text.

The code is working fine in Extjs version 3.0. Now, I have moved to version 3.4 which is causing the following problem.

When I scroll the window down and select the text which was not visible initially, I am not able to drag it. The text gets selected properly and is applied proper styles but it is not draggable. Everything is fine in the visible part, the problem is when you have to scroll down for some text.

Below is the code that creates drag source.



handleTextSelection:function() {
var range = this.getRangeObject();
if (range) {
if ( (range.text && range.text.length == 0) || (range.toString && range.toString().length == 0)) {
this.lastUserSelection = null;
return;
}
var node = document.createElement("div");
node.id = "user_selection_" + SEM.util.getUID();
node.className = "anno_user_selection";
if (range.surroundContents) {
range.surroundContents(node);
}
node.style.display = "inline";
var el = Ext.get(node.id);
this.lastUserSelection = el;
if (el) {
el.dragSource = new Ext.dd.DragSource(el);
el.dragSource.dragData = {
objectType:SEM.JSGraph.USER_SELECTION_TYPE,
nodes:[node],
text:el.dom.textContent.trim(),
title:el.dom.textContent.trim()
};
}
}else if (!SEM.JSGraph.currentEditor.selectionstate){
if (this.lastUserSelection) {
var el = this.lastUserSelection;
Ext.DomHelper.insertAfter(el.dom.previousSibling, el.dom.textContent);
el.dom.parentNode.removeChild(el.dom);
//Ext.DomHelper.overwrite(el, el.dom.textContent);
}
this.lastUserSelection = null;
}


Following is the getRangeObject function used to create range object.



getRangeObject:function() {
var selection = null;
if (window.getSelection) {
selection = window.getSelection();
}else if (document.getSelection) {
selection = document.getSelection();
}else if (document.selection) {
selection = document.selection.createRange();
}
var range = null;
if (selection != "") {
if (selection.getRangeAt) {
range = selection.getRangeAt(0);
}else if(document.createRange) {
range = document.createRange();
range.setStart(selection.anchorNode, selection.anchorOffset);
range.setEnd(selection.focusNode, selection.focusOffset);
} else {
range = selection;
}
}
return range;
}


I have registered the function, handleTextSelection with the mouseUp event.

Ext.getBody().on("mouseup",this.handleTextSelection.createDelegate(this));

This code works perfectly with Extjs 3.0. But faces the problem described above, when used with Extjs 3.4.

I found following facts while debugging, which may be helpful.

1: I registered, listeners to following events of drag source.


el.dragSource.startDrag = function(){
alert('startDrag');
};
el.dragSource.b4Drag = function(){
alert('b4Drag');
};
el.dragSource.onBeforeDrag = function(){
alert('onBeforeDrag');
};
el.dragSource.onStartDrag = function(){
alert('onStartDrag');
};


As expected, these events are fired for the text which is visible initially.
But for the text which is not visible initially, only onBeforeDrag event is fired.


2: The behaviour is same for fireFox and chrome. So, this does not seem to be browser specific problem.


Is there anything wrong with respect to Extjs 3.4 specification in the above code?
Can any one point out why is this problem faced with Extjs 3.4?

Pratik_Patel
25 Jun 2013, 5:47 AM
Ok, I found the solution.


Some code in ext-all-debug.js of Extjs 3.4 was causing the problem. This code was not there in the 3.0 version.


To fix the problem, search for "getLocation: function(oDD) {" in ext-all-debug.js and comment out the following code.



/*
* The code below is to ensure that large scrolling elements will
* only have their visible area recognized as a drop target, otherwise it
* can potentially erronously register as a target when the element scrolls
* over the top of something below it.
*/
el = Ext.get(el.parentNode);
while (el && region) {
if (el.isScrollable()) {
// check whether our element is visible in the view port:
region = region.intersect(el.getRegion());
}
el = el.parent();
}


As explained in comments its there to fix some problem but then it was causing the above specified problem.


I don't know what they mean by



* otherwise it
* can potentially erronously register as a target when the element scrolls
* over the top of something below it.


It would be helpful if someone can elaborate more on it.