Start Building Professional
Web Apps Today


 
Categories Question details Back To List
Question  posted by Paul K on Aug 25, 2008 18:05
open dhtmlx forum
Changing cursors for Drag and Drop

I'd like to change the cursor to the not-allowed cursor when a rule would prevent the user from dropping an item on a node in a tree as well as a row in a grid.

I've created a function for the onDragIn event for the tree as a test:

function treeOnDragInEvent (draggedItem, landingItem, treeObjectSource, treeObjectTarget) {
// add rules checking code later.
document.body.style.cursor="not-allowed";
return true;
}

The only place the cursor changes to not-allowed is when it is over the icon for a tree node. What do I need to specify to get it to change when hovering over the text of a node and in between nodes (complex drag and drop behavior is set)?

Also there is no "onDragOut" event for the tree so I can't reset the cursor to the default when the cursor is moved off an item. How can I do that?

When I use the onDragIn and onDragOut events for the grid, does the answer change?

Paul
Answer posted by Support on Aug 26, 2008 01:45

The elements of tree has their own cursor style settings, so while changing global style setting for document, the cursor settings for current item stay unchanged. 
You can drop default style setting by using next command during init

  tree =new dhtmlXTreeObject(...
  tree.style_pointer="";

>>Also there is no "onDragOut" event for the tree 
The most simlple approach is to add custom event in existing code
dhtmlxtree.js , line 3825

dhtmlXTreeObject.prototype._dragOut=function(htmlObject){
    this._clearMove();
    if (this._autoOpenTimer) clearTimeout(this._autoOpenTimer);
    this.callEvent("onDragOut",[]); //this line can be added
}

>>When I use the onDragIn and onDragOut events for the grid, does the answer change?
In case of grid, there is no separate cursor settings, so changing the global style will work without any additional steps. 

Answer posted by Paul K on Sep 15, 2008 18:10
I've gone further with the code in the onDragIn event function for the tree.  I've found that if I drag a row from a grid on the same page to the tree, the source id parameter is 'undefined'. I need the value of the source id.

Paul
Answer posted by Support on Sep 16, 2008 09:28
You can try to use onBefore event handler in order to get the id of the source item/row:
var src_id = ""; 
function doOnBeforeDra(id){
src_id = id;
return true
})
grid.attachEvent("onBeforeDrag",doOnBeforeDrag);
tree.attachEvent("onBeforeDrag",doOnBeforeDrag);


Answer posted by Paul K on Sep 16, 2008 17:26
The new function for the onBeforeDrag lets me capture the id of the row being dragged.  But I'm still having problems. 

I applied the patch to dhtmlxtree.js that you described to set up an onDragOut event for a tree.  I attached an event handler function to it, but it doesn't fire when I expect it to.  It seems to fire only when I drag the cursor out of an error that my onDragIn event handler says is a valid landing zone (that is, the onDragIn function returned true). 

What I want to do is:

Leave the cursor alone as an item is being dragged to the tree (either from the tree or the grid)
Once the cursor hovers over a node in the tree (on either the icon or text) it changes depending on rules in the on drag in event handler.  (I have this working.)
If the cursor moves off the node, the cursor shape changes to the default.  (Not working, the on drag out function only works as described above)
If the object is dropped on a valid landing zone, a new node is created and the cursor returns to the default shape.  (Working)
If the object is dropped anywhere else, the tree is not changed and the cursor returns to the default shape.  (Not working.)

How can I get the two cases (drag off tree node and drop on invalid zones) to work?

Paul
Answer posted by Paul K on Sep 19, 2008 10:12
Normally I receive a response the morning (your time) after I post a question or response.  I'm disappointed to see nothing for three days.  I'm still having the problem described above.

Paul
Answer posted by Support on Sep 22, 2008 01:56
Sorry for the late response.
 
onDragOut and onDragIn events  allow to change cursor in tree. For example:

var target = null;

tree.attachEvent("onDragOut",function(){
            
    target.style.cursor="default";
                
    return true
});

tree.attachEvent("onDragIn",function(source_id,target_id){

    if(tree._idpull[id]){

        target = tree._idpull[id].span.parentNode;

        if(....) target.style.cursor="some_cursor";
else
            target.style.cursor="default";
     return true

})
Answer posted by Paul K on Sep 22, 2008 16:41
I got it to work, sort of.  By changing id to target_id in your example:

tree.attachEvent("onDragIn",function(source_id,target_id){
    if(tree._idpull[target_id]){  <==
        target = tree._idpull[id].span.parentNode;
        if(....) target.style.cursor="some_cursor";
else
        target.style.cursor="default";
     return true
})

I can capture the tree element that I want to changet the cursor for.

The problem is the cursor stays as "not-allowed" on those elements that I set them for.  The onDragOut event isn't being called when the cursor moves off those elements so it is not set back to the default.  As a result the cursor changes to not allowed over those elements whenever the cursor moves over it when not dragging an item. 

This is the due to the problem I described previously where the onDragOut event doesn't happen unless the landing item is valid (that is onDragIn returns true first.  If onDragIn returns false then the onDragOut event is not called when the cursor moves off the tree item.  Which leaves the cursor at "not-allowed".  How can I change the cursor back in this case?

Paul
Answer posted by dhtmlx support on Sep 24, 2008 03:24
You can try to deny drag-n-drop in the onDrag event handler and here you can set default style for the cursor. onDragIn should always  return true.
var target = null;
tree.attachEvent("onDragIn",function(source_id,target_id){
    if(tree._idpull[target_id])
        target = tree._idpull[id].span.parentNode;
    if(tree.getUserData(target_id,"disabled"))
        target.style.cursor="some_cursor";
    else
        target.style.cursor="default";
     return true
})
tree.attachEvent("onDrag",function(source_id,target_id){
    target.style.cursor="default";
    if(tree.getUserData(target_id,"disabled"))
        return false;
    return true
})
Answer posted by Paul K on Sep 24, 2008 14:27
Ok, I have it just about working.  The last thing I need to work out is how to change the icon when it hovers over the icon in the tree.  It does change when hovering over the text for the node but not the icon for the node.  I'm using the code you pasted earlier:

tree.attachEvent("onDragIn",function(source_id,target_id){
    if(tree._idpull[target_id]){
        target = tree._idpull[target_id].span.parentNode;
        if(....)
           target.style.cursor="some_cursor";
      else
         target.style.cursor="default";
      return true
})

Apparently the target element doesn't include the icon.

Paul
Answer posted by Paul K on Sep 24, 2008 15:16
I guess I spoke too soon!  I also found that if you drag a parent onto one of its children (at any level!), the onDragIn event function is called but not the OnDrag event function.  So while I can set the cursor to not allowed in the on drag in function, I can't set it back to the default in the on drag function.  So the cursor remains as not allowed when hovering over the element.  (The on drag out event function is also not called.)

I understand that it shouldn't be valid to drop a parent node on of its children, but I'm not sure how to handle resetting the cursor.

Also earlier in this message chain you mentioned setting the global style for the cursor.  I am using "document.body.style.cursor" to set the cursor in the onDragIn and onDragOut events for the grid but the cursor never changes within the grid itself.  (It does change for the rest of the document.)  Is there something else I should use to change the cursor for the grid control.

Paul
Answer posted by dhtmlx support on Sep 26, 2008 05:47
>> It does change when hovering over the text for the node but not the icon for the node.

You can try to set the following element as a target:

target = tree._idpull[id].htmlNode;

tree.attachEvent("onDragIn",function(source_id,target_id){
    if(tree._idpull[target_id]){
        target = tree._idpull[target_id].htmlNode;
...
}
>> I also found that if you drag a parent onto one of its children (at any level!), the onDragIn event function is called but not the OnDrag event function.

You can try to use onMouseIn event handler in order to set cursor to default:

tree.attachEvent("onMouseIn",function(id){
    if(tree._idpull[id]){
        target = tree._idpull[id].htmlNode;
        target.style.cursor="default";
    }
 })


Answer posted by Paul K on Oct 01, 2008 09:43
>>        target = tree._idpull[target_id].htmlNode;

That works for the both the icon and the text!

The onMouseIn function does not work to let me changed the cursor back to the default.  In fact it doesn't seem to get caused (fired) at all.

I still cannot control the cursor when dropping into the grid control on the page.  I want to allow drag and drop within the grid, but not from tree to grid.  (Described earlier in this thread.)

Paul
Answer posted by Support on Oct 01, 2008 10:06
>>  I am using "document.body.style.cursor" to set the cursor in the onDragIn and onDragOut events for the grid but the cursor never changes within the grid itself
Grid has its own cursor settings for element of grid's header and for data parts, so the global style assigned for the document.body will not affect it. You can resolve problem but assigning cursor style not only to body, but for grid.entBox as well. 

>>The onMouseIn function does not work to let me changed the cursor back to the default
Please check attached sample. 
If you are using old version of dhtmlxtree - please try to use setOnMouseInHandler to assign event handler instead of attachEvent
Attachments (1)
Answer posted by Paul K on Oct 01, 2008 18:27
Using the grid.entBox.style.cursor = "default", etc., worked to change the cursor style over the grid.  I didn't need to change the cursor for the body, I just thought it had been suggested earlier in this thread.

Your example works, for me at least, in Firefox 3 but not in IE 6.  That is, the id is displayed below the tree when I open sample.html in Firefox 3 and move the mouse cursor over items in the tree.  In IE 6 I don't see any text displayed below the tree as the mouse moves over the tree nodes.

Paul
Answer posted by Support on Oct 02, 2008 01:46
>> In IE 6 I don't see any text displayed below the tree as the mouse moves over the tree nodes.
Please be sure to load sample page by http, when loaded from local filesystem ( c:\some\sample.html ) the functionality really doesn't works
( To have functionality workable for any type of loading, just move loadXML command after attachEvent ) 
Answer posted by Paul K on Oct 03, 2008 16:51
The example works if I run it from a server (such as tomcat).  However the onMouseIn event handler function is not called in my code. 

It could be because of the number of event handlers I have on the tree:  onDragIn, onDrag, onDrop, onDragOut, and of course onMouseIn.

I did find one case where the onMouseIn event function is called.  That is when I drag and drop a row from the grid on the same page into the tree.  A new node is added to the tree by the tree control.  At that point the mouse in function is called as I move the cursor around the tree but only for that new node.  When I save and reload the data from XML, the function is no longer called for that new node (or any node).

Paul
Answer posted by Support on Oct 06, 2008 05:46
>>It could be because of the number of event handlers
While you not blocking grid logic ( by returning false), all events must fire correctly. 

>>, the function is no longer called for that new node (or any node).
Please be sure that attachEvent("onMouseIn" called before data loaded in tree.  ( before loadXML command in common case ) 
Answer posted by Paul K on Oct 06, 2008 13:13
>> Please be sure that attachEvent("onMouseIn" called before data loaded in tree.  ( before loadXML command in common case )

That was it, thanks!

Paul