PDA

View Full Version : Ajax Tree drag&drop: is beforenodedrop blind?



ImShogun
9 Aug 2009, 3:38 PM
Hi folks,

I tought I could set up "that little drag & drop in my ajax tree database records reordering thing" easy. Well, it is almost done. All I need is to send the variables to the server and then if he says no, trigger the cancel drag event. I've found everything i need to send the request, using the nodedrop, but I would like to do the checking in beforenodedrop so I'll be able to cancel the event...

Or, I missed something. Quite possible. Certainly. Sure! Still a Newbee! Have only... 45 hours of Extjs so far :-)

Would you masters be so kind to help me?

Thanks! Keep up.



//DRAG START: Let's remember who's moving, from where...
tree1.on('startdrag', function(tree, node, event){
MyDragItem=node.id;
MyOldParent=node.parentNode.id;
MyOldSuccessor=node.nextSibling;
MyOldPosition=node.parentNode.indexOf(node);
});

//DRAG END 1: Let's cancel everything cause we don't know where the drop is...
tree1.on('beforenodedrop', function(tree, node, event){
//Can't check anything here?
return false;
});

//DRAG END 2: Now I'll know where the drop is happening, but won't be able to cancel it any more?
tree1.on("nodedrop", function(tree, node, event) {
MyDragItem2=node.id;
MyNewParent=node.parentNode.id;
MyNewSuccessor=node.nextSibling;
MyNewPosition=node.parentNode.indexOf(node);
// send it to the backend to save
Ext.Ajax.request({
method: 'POST',
params:{
Dragged:MyDragItem,
Dragged2:MyDragItem2,
OldParent:MyOldParent,
OldPosition:MyOldPosition,
NewParent:MyNewParent,
NewPosition:MyNewPosition,
NewSuccessor:MyNewSuccessor,
OldSuccessor:MyOldSuccessor
},
url: 'reorder.cfm'
});
return false;// wont work here!
});

ImShogun
11 Aug 2009, 8:22 AM
Mmmm. Really? Nobody?
Maybe it is so obvious you'd think I've found the solution myself now...
But I haven't...

According to the doc, here (http://www.extjs.com/deploy/dev/docs/source/TreePanel.html#event-Ext.tree.TreePanel-beforenodedrop), the beforenodedrop comes with these properties:



tree - The TreePanel

* target - The node being targeted for the drop

* data - The drag data from the drag source

* point - The point of the drop - append, above or below

* source - The drag source

* rawEvent - Raw mouse event

* dropNode - Drop node(s) provided by the source OR you can supply node(s)
* to be inserted by setting them on this object.
* cancel - Set this to true to cancel the drop.

* dropStatus - If the default drop action is cancelled but the drop is valid, setting this to true
* will prevent the animated "repair" from appearing.

..Which means I sould be able to read the target node properties, right?

It says


"The dropEvent passed to handlers has the following properties"

But then I don't know what is the right syntax to read these properties?

This is my best shot so far:



tree1.on('beforenodedrop',function(tree, target){
alert(target.node.id);
return false;

});


I don't understand (Because of my general javascript lak of knowledge?) what is the link between the doc, the red part and the green part.

If you could help me please, Seems I will never be able to make good progress without understanding that.

Animal
11 Aug 2009, 9:04 AM
Do not alert.

You will learn MUCH more if you set a Firebug break point in the beforenodedrop handler and just drill down into the available object seeing exactly what's where.

Then you just switch back to your IDE and write code to use what you just found. Very simple and quick.

Condor
11 Aug 2009, 9:07 AM
No, you didn't read the API docs correctly. The syntax is:

tree1.on('beforenodedrop',function(dropEvent){
alert(dropEvent.target.id);
return false;
});

Condor
11 Aug 2009, 9:09 AM
And, just in case you hadn't figured that part out yet, your beforenodedrop event needs to do something like this (http://www.extjs.com/forum/showthread.php?p=271923#post271923):

ImShogun
11 Aug 2009, 2:33 PM
Do not alert.

You will learn MUCH more if you set a Firebug break point in the beforenodedrop handler and just drill down into the available object seeing exactly what's where.

Then you just switch back to your IDE and write code to use what you just found. Very simple and quick.

Waw. Animal, if only I knew that weeks (months...) ago!! Sometimes, self-learning just sucks. Thank you man, I own you a few hours of my life.


No, you didn't read the API docs correctly. The syntax is:

tree1.on('beforenodedrop',function(dropEvent){
alert(dropEvent.target.id);
return false;
});
Condor, thanks to you, I begun to understand objects and properties concept... Take a guy who did 10 years of linear coding, then give him object oriented stuff to do, and you'll end up with me :-) And you are almost right: I did read the doc correctly. But I didn't had the requirements to understand it ;-)

Thanks to both of you and after walking around the forum about the many arguments related to synchronous requests being usefull for beforenodedrop cancel ability (here for example (http://extjs.com/forum/showthread.php?t=32288), or the really interesting debate with Animal here (http://extjs.com/forum/showthread.php?t=7376)), I ended up with these choices (the one I'm able to think of AND have time to implement):

1) Stick with asynchronous and build something to revert on failure (not forgeting the very nice "cancel" slide back effect);
2) Patch Extjs to be able to do synchronous requests (solutions here (http://extjs.com/forum/showthread.php?t=10857));
3) Create my own XMLhttrequest from scratch (and then re-invent the wheel again);
4) Combine the power of my 2 prefered libraries

Despite completely agreeing with Animal about what Ajax means (especially the first A), 99%, I saw an opportunity to combine some Extjs and Jquery togheter: After all, i find the two libraries are very complementary.

Basically, this is what I did to solve my problem:



//DRAG AND DROP CANCELLED IF SERVER SQL UPDATE FAILED

tree1.on('beforenodedrop',function(dropEvent){
//USING JQUERY SYNC REQUEST
var response = $.ajax({
type: "POST",
async: false,
url: "reorder.cfm",
data: ({


Dragged:dropEvent.dropNode.id,
OldParent:dropEvent.dropNode.parentNode.id,
OldPosition:dropEvent.dropNode.parentNode.indexOf(dropEvent.dropNode),
NewParent:dropEvent.target.parentNode.id, NewPosition:dropEvent.target.parentNode.indexOf(dropEvent.target)
})
})
//CHECKING HTTP RESPONSE STATUS
if(response.status=="200"){
return true;
}
else{
return false;
}
});
Now, I can drag and drop approximatly everything and cancel on server side request. I know there is still a small danger in this: what about requests that get a timeout but still are successfull on the server? That's something I patched on the server handling: For example, if the drag&drop was ment to reorder a list, I check the initial position against the database: if it fails, it is a good time to instruct Extjs to reload the parent node...

Thank you very much for your time.

Regards,

L.