Success! Looks like we've fixed this one. According to our records the fix was applied for a bug in our system in a recent build.
  1. #1
    Sencha User
    Join Date
    May 2008
    Posts
    6
    Vote Rating
    0
    oboyklubben is on a distinguished road

      0  

    Question Ext.tree.ViewDDPlugin beforedrop event not working accordingly the API docs

    Ext.tree.ViewDDPlugin beforedrop event not working accordingly the API docs


    I am trying to validate the node being dropped with an ajax request but the event handler for 'beforedrop' does not seem to work accordingly the API docs. Here is my code:

    Code:
    Ext.define('TestTree', {
        displayField: 'name',
        extend: 'Ext.tree.Panel',
        rootVisible: false,
        useArrows: true,
    
        initComponent: function() {
            this.store = new Ext.data.TreeStore({
                model: 'Resource',
                nodeParam: 'parent',
                proxy: {
                    type: 'ajax',
                    url: 'resource/getresources/'
                },
                root: {
                    expanded: true,
                    id: 'root'
                },
                sorters: [{
                    property: 'position'
                }]
            });
    
            this.viewConfig = {
                listeners: {
                    beforedrop: { fn: this.onBeforedrop, scope: this }
                },
                plugins: {
                    ptype: 'treeviewdragdrop'
                }
            };
    
            this.callParent(arguments);
        },
    
        onBeforedrop: function(node, data, overModel, dropPosition, dropFunction) {
            Ext.Ajax.request({
                url: 'resource/canmove/',
                params: {
                    idFrom: data.records[0].data.id,
                    idTo: overModel.data.id
                },
                success: function(response){
                    var canMove = Ext.JSON.decode(response.responseText);
    
                    if (canMove) {
                        dropFunction();
                    }
                }
            });
    
            return 0;
        }
    });
    When debugging it seems that following Ext code does not return the correct result from the event handler:
    Code:
    if (Ext.util.Observable.prototype.fireEvent.apply(this, arguments) !== false) {
    return me.dispatch.call(me, ev, this, arguments);
    }
    return false;
    If I return false from the event handler it works, but when returning 0 as the API docs suggests it returns undefined.

    When stepping into the 'dispatch' function you can see that 'this.bus' does not contain any events and therefore the 'selectors = bus[ev]' will return undefined and 'return event.fire.apply(event, Array.prototype.slice.call(args, 1));' code will not be called.

  2. #2
    Ext JS Premium Member
    Join Date
    Mar 2011
    Posts
    9
    Vote Rating
    0
    mjcaisse is on a distinguished road

      0  

    Default


    I'm hitting this bug too. Any ideas for a work around?

  3. #3
    Ext JS Premium Member
    Join Date
    Jul 2007
    Location
    New York, NY
    Posts
    9
    Vote Rating
    0
    shanonvl is on a distinguished road

      0  

    Default Same issue here ...

    Same issue here ...


    I'm hitting the same thing and I've played around with a bunch of configs and *always* the bus is {} and selectors aren't defined, thus the method returns undefined.

    For now, I've implemented this hack which seems to work ( but adds a closure ). Can someone from the Sencha team please advise if this is pilot error or an actual bug?

    Thanks,
    Shanon

    Code:
                    var originalDispatch = Ext.app.EventBus.prototype.dispatch;
                    Ext.override(Ext.app.EventBus,{
                                dispatch:function() {
                                    var ret = originalDispatch.apply(this,arguments);
                                    if( typeof(ret) === 'undefined') {
                                        return true;
                                    }
                                }
                            });

  4. #4
    Ext JS Premium Member
    Join Date
    Mar 2011
    Posts
    9
    Vote Rating
    0
    mjcaisse is on a distinguished road

      0  

    Default


    Hi Shanon -

    It is a bug in the library. There is a fix in SVN trunk. Rev 167 if memory serves right.

    hth

  5. #5
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,496
    Vote Rating
    44
    Animal has a spectacular aura about Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    Yes, this doesn't work as it should. I'll have to discuss it with Tommy Maintz who is in charge of trees. I though he had a proposed solution in which the event handler set a property in one of the passed objects to specify that there was no error, but not to perform the drop.

  6. #6
    Sencha - Services Team
    Join Date
    Mar 2007
    Location
    Foristell, MO
    Posts
    1,108
    Vote Rating
    3
    jratcliff is on a distinguished road

      0  

    Default


    Well, until this gets fixed you can 'return false' and give your plugin an id, then use that id to get a handle to it and it's dropZone in your Ajax success handler. From there you can reset the two needed properties that the drop function will needed to process your drop.

    Code:
    Ext.define('TestTree', {
        displayField: 'name',
        extend: 'Ext.tree.Panel',
        rootVisible: false,
        useArrows: true,
    
        initComponent: function() {
            this.store = new Ext.data.TreeStore({
                model: 'Resource',
                nodeParam: 'parent',
                proxy: {
                    type: 'ajax',
                    url: 'resource/getresources/'
                },
                root: {
                    expanded: true,
                    id: 'root'
                },
                sorters: [{
                    property: 'position'
                }]
            });
    
            this.viewConfig = {
                listeners: {
                    beforedrop: { fn: this.onBeforedrop, scope: this }
                },
                plugins: {
                    ptype: 'treeviewdragdrop',
                    pluginId: 'ddplugin'
                }
            };
    
            this.callParent(arguments);
        },
    
        onBeforedrop: function(node, data, overModel, dropPosition, dropFunction) {
            Ext.Ajax.request({
                url: 'resource/canmove/',
                params: {
                    idFrom: data.records[0].data.id,
                    idTo: overModel.data.id
                },
                success: function(response){
                    var canMove = Ext.JSON.decode(response.responseText),
                          plugin = this.getPlugin('ddplugin'),
    		      dropZone = plugin.dropZone;
    					    	
    	        // reset this since these props were deleted
    	    	dropZone.overRecord = model;
    	    	dropZone.currentPosition = pos;
    
                    if (canMove) {
                        dropFunction();
                    }
                }
            });
    
            return false;
        }
    });
    Jack Ratcliff
    Sencha Inc, Green bleeding Senchan

    How to report a bug:
    http://www.sencha.com/forum/showthre...o-report-a-bug

  7. #7
    Sencha - Services Team
    Join Date
    Mar 2007
    Location
    Foristell, MO
    Posts
    1,108
    Vote Rating
    3
    jratcliff is on a distinguished road

      0  

    Default


    I checked our issue tracker and this just recently was fixed and will be available in an upcoming release. The fifth param is now an object with a property called 'wait' that when set to true, will delay the drop processing. You can then call the processDrop or cancelDrop methods later (see example below).


    Code:
    listeners : {
        beforedrop : function(node, data, model, pos, dropHandlers) {
            
            // we are processing the drop later asynchronously
            // so we just set the dropHandlers.wait property to true to delay the processing
            // instead of returning true/false from this handler
            dropHandlers.wait = true;
            
            Ext.MessageBox.confirm(
                'Confirm', 
                'Do the drop?', 
                function(btn) {
                    if (btn == 'yes') {
                        dropHandlers.processDrop();
                    } else {
                        dropHandlers.cancelDrop();
                    }
                 }
            );
        }
    }
    Jack Ratcliff
    Sencha Inc, Green bleeding Senchan

    How to report a bug:
    http://www.sencha.com/forum/showthre...o-report-a-bug

  8. #8
    Ext JS Premium Member
    Join Date
    Nov 2009
    Location
    St Louis,MO
    Posts
    267
    Vote Rating
    18
    James Goddard will become famous soon enough James Goddard will become famous soon enough

      0  

    Default


    Quote Originally Posted by jratcliff View Post
    I checked our issue tracker and this just recently was fixed and will be available in an upcoming release. The fifth param is now an object with a property called 'wait' that when set to true, will delay the drop processing. You can then call the processDrop or cancelDrop methods later (see example below).
    Which release? I checked 4.0.6 and it's not there.

  9. #9
    Sencha User
    Join Date
    Mar 2010
    Location
    Delft - The Netherlands
    Posts
    28
    Vote Rating
    2
    bas_tzx is on a distinguished road

      0  

    Default


    Quote Originally Posted by James Goddard View Post
    Which release? I checked 4.0.6 and it's not there.
    And also not in the 4.0.7 release.

  10. #10
    Sencha Premium Member
    Join Date
    Mar 2011
    Posts
    41
    Vote Rating
    0
    annette is on a distinguished road

      0  

    Default Will be fixed in 4.1

    Will be fixed in 4.1


    I've reported the problem as a ticket (for Ext.tree.plugin.TreeViewDragDropView, ptype: treeviewdragdrop).

    I've got the following response, and have successfully applied the patch.

    It will be fixed in 4.1 since it's an API change.

    The code looks like this:

    Code:
    onNodeDrop : function (node, dragZone, e, data) {    var me = this,
        dropHandled = false,
        
        // Create a closure to perform the operation which the event handler may use.
        // Users may now set the wait parameter in the beforedrop handler, and perform any kind
        // of asynchronous processing such as an Ext.Msg.confirm, or an Ajax request,
        // and complete the drop gesture at some point in the future by calling either the
        // processDrop or cancelDrop methods.
        dropHandlers = {
            wait : false,
            processDrop : function () {
                me.invalidateDrop();
                me.handleNodeDrop(data, me.overRecord, me.currentPosition);
                dropHandled = true;
                me.fireViewEvent('drop', node, data, me.overRecord, me.currentPosition);
            },
            
            cancelDrop : function () {
                me.invalidateDrop();
                dropHandled = true;
            }
        },
        performOperation = false;
        
        if (me.valid) {
            performOperation = me.fireViewEvent('beforedrop', node, data, me.overRecord, me.currentPosition, dropHandlers);
            if (dropHandlers.wait) {
                return;
            }
            
            if (performOperation !== false) {
                // If either of the drop handlers were called in the event handler, do not do it again.
                if (!dropHandled) {
                    dropHandlers.processDrop();
                }
            }
        }
        return performOperation;
    }




    The updated docs:

    Code:
    * @param {Object} dropHandler An object containing methods to complete/cancel the data transfer operation and either
         * move or copy Model instances from the source View's Store to the destination View's Store.
         *
         * This is useful when you want to perform some kind of asynchronous processing before confirming/cancelling
         * the drop, such as an {@link Ext.window.MessageBox#confirm confirm} call, or an Ajax request.
         *
         * Set dropHandler.wait = true in this event handler to delay processing. When you want to complete the event, call
         * dropHandler.processDrop(). To cancel the drop, call dropHandler.cancelDrop.





    Last edited by annette; 6 Dec 2011 at 1:03 AM. Reason: Bad formatting, hope this one is better.