1. #1
    Sencha User willf1976's Avatar
    Join Date
    May 2009
    Location
    carpinteria, ca
    Posts
    84
    Vote Rating
    0
    willf1976 is on a distinguished road

      0  

    Post treePanel Plugin: Ext.ux.tree.TreePanel.CopyDropNode

    treePanel Plugin: Ext.ux.tree.TreePanel.CopyDropNode


    Hi All

    I have made a simple treePanel plugin which allows for a copy of a node to be created when it is dropped into the tree (as opposed to the default functionality where the node is just moved).

    The plugin includes some properties which can be used to set up simple logic for when a node is copied instead of moved (such as defining an array of components whose nodes will be copied when they are dropped into the treePanel).

    The class also adds some events to the treePanel class which you can attach listeners to in order to define your own logical for when a node is copied instead of moved. Please see the documentation with in the class for more details.

    Note: This plugin needs to be applied to the treePanel which the nodes will be dropped to and does not need to be on the treePanel where the nodes are dragged from.

    Please let me know if you find any bugs or having suggestions.

    Best regards

    Will Ferrer

    Update (09/03/09): This code now uses Ext.ux.tree.TreePanel.toObject to copy childNodes that have been dynamically added to branches. This code is available in thread: http://www.extjs.com/forum/showthread.php?t=20793.

    Here is Ext.ux.tree.TreePanel.toObject:

    HTML Code:
    /*
    original author: dpasichnik
    modified by: Will Ferrer
    date: 09/03/09
    history:
        09/03/09 -- posted to ExtJS forums
    */
    /**
        This code is based on dpasichnik's treeSerializer found at:
        http://www.extjs.com/forum/showthread.php?t=20793
    */
    /**
     * Returns a object that represents the tree
     * @param {Function} nodeFilter (optional) A function, which when passed the node, returns true or false to include
     * or exclude the node.
     * @param {Function} attributeFilter (optional) A function, which when passed an attribute name, and an attribute value,
     * returns true or false to include or exclude the attribute.
     * @param {Object} attributeMapping (optional) An associative array which can you use to remap attribute names on the nodes as they are converted to an object. Keys in the array represent attributes to be remapped, and their associated values represent the new keys that those attributes will be remapped onto in the returned object.
     * @return {String}
     */
    Ext.tree.TreePanel.prototype.toObject = function(nodeFilter, attributeFilter, attributeMapping){
          return this.getRootNode().toObject(nodeFilter, attributeFilter, attributeMapping);
    };
    
    /**
     * Returns an object that represents the node
     * @param {Function} nodeFilter (optional) A function, which when passed the node, returns true or false to include
     * or exclude the node.
     * @param {Function} attributeFilter (optional) A function, which when passed an attribute name, and an attribute value,
     * returns true or false to include or exclude the attribute.
     * @param {Object} attributeMapping (optional) An associative array which can you use to remap attribute names on the nodes as they are converted to an object. Keys in the array represent attributes to be remapped, and their associated values represent the new keys that those attributes will be remapped onto in the returned object.
     * @return {String}
     */
    
    Ext.tree.TreeNode.prototype.toObject = function(nodeFilter, attributeFilter, attributeMapping){
    //    Exclude nodes based on caller-supplied filtering function
        if (nodeFilter && (nodeFilter(this) == false)) {
            return {};
        }
        var c = false, returnObj = {};
    
    //    Add the id attribute unless the attribute filter rejects it.
        if (!attributeFilter || attributeFilter("id", this.id)) {
            returnObj.id = this.id;
            c = true;
        }
    
    //    Add all user-added attributes unless rejected by the attributeFilter.
        for(var key in this.attributes) {
            if ((key != 'id') && (!attributeFilter || attributeFilter(key, this.attributes[key]))) {
                if (attributeMapping && attributeMapping[key]) {
                    thisKey = attributeMapping[key];
                } else {
                    thisKey = key;
                }
                returnObj[thisKey] = this.attributes[key];
                c = true;
            }
        }
    //    Add child nodes if any
        var children = this.childNodes;
        var clen = children.length;
        if(clen != 0){
            returnObj['children'] = [];
            for(var i = 0; i < clen; i++){
                returnObj['children'][i] = children[i].toObject(nodeFilter, attributeFilter, attributeMapping);
            }
        }
        return returnObj;
    }
    Ext.ux.tree.TreePanel.CopyDropNode:

    HTML Code:
    /*
    author: Will Ferrer
    date: 09/02/09
    history:
        08/09/09 -- posted to ExtJS forums
        08/09/09 -- minor structural changes and changed class name
        08/13/09 -- fixed a problem where copying nodes inside the same tree could result in duplicate node its.
        08/21/09 -- added superclass.constructor.call for posterities sake
        08/24/09 -- acceptFromComponents property added
        09/02/09 -- added acceptFromSelf property
    */
    /**
     * @class Ext.ux.tree.TreePanel.CopyDropNode
     * @extends Ext.util.Observable
     * A simple plug in for TreePanel that allows you to make nodes dropped into the tree panel be copied instead of moved to the panel.
     * Plugin includes properties that can be configured to discern what nodes should be copied and what nodes shouldn't.
     * This plugin also adds some events to the treePanel on which the plugin was applied -- these events provide additional control over when a node is copied.
     * In order to override the logic used in this plug in to determine whether a node should be copied or not, a boolean value of doCopy may be set on the node which is being dropped. 
     * You may also control this functionality by modifying the drop event itself -- please see the beforecopydropnode event definition for more details. 
     * @constructor
     * @param {Object} config The config object
     * @ptype ux-tree-treepanel-copydropnode
     */
    Ext.ns('Ext.ux.tree.TreePanel');
    Ext.ux.tree.TreePanel.CopyDropNode = function(config){
        Ext.apply(this, config);
        Ext.ux.tree.TreePanel.CopyDropNode.superclass.constructor.call(this);
    };/*
    author: Will Ferrer
    date: 09/03/09
    history:
        08/09/09 -- posted to ExtJS forums
        08/09/09 -- minor structural changes and changed class name
        08/13/09 -- fixed a problem where copying nodes inside the same tree could result in duplicate node its.
        08/21/09 -- added superclass.constructor.call for posterities sake
        08/24/09 -- acceptFromComponents property added
        09/02/09 -- added acceptFromSelf property
        09/03/09 -- added fullBranchCopy, nodeFilter, attributeFilter, attributeMapping
        09/04/09 -- added parent.copyDropNode = this;
    */
    /**
     * @class Ext.ux.tree.TreePanel.CopyDropNode
     * @extends Ext.util.Observable
     * A simple plug in for TreePanel that allows you to make nodes dropped into the tree panel be copied instead of moved to the panel.
     * Plugin includes properties that can be configured to discern what nodes should be copied and what nodes shouldn't.
     * This plugin also adds some events to the treePanel on which the plugin was applied -- these events provide additional control over when a node is copied.
     * In order to override the logic used in this plug in to determine whether a node should be copied or not, a boolean value of doCopy may be set on the node which is being dropped. 
     * You may also control this functionality by modifying the drop event itself -- please see the beforecopydropnode event definition for more details. 
     * @constructor
     * @param {Object} config The config object
     * @ptype ux-tree-treepanel-copydropnode
     */
    Ext.ns('Ext.ux.tree.TreePanel');
    Ext.ux.tree.TreePanel.CopyDropNode = function(config){
        Ext.apply(this, config);
        Ext.ux.tree.TreePanel.CopyDropNode.superclass.constructor.call(this);
    };
    Ext.extend(Ext.ux.tree.TreePanel.CopyDropNode, Ext.util.Observable, {
    //Public Properties:
        /**
        * @cfg {Boolean} enabled
        * Whether or not copying is enabled -- if set to false this plug in will stop copying nodes. Defaults to true.
        */
        enabled : true,
        /**
        * @cfg {Mixed} copyFromComponents
        * An array of component ids or null to disable the feature. When a node is dropped on the tree we will check to see if the id of the tree the node was dragged from is present in this array, if it is we will copy the node rather than moving it. If set to null then which tree the node was dragged from won't be a factor in whether it is coppied or not. Defaults to null.
        */
        copyFromComponents : null,
        /**
        * @cfg {Boolean} rejectFromComponents
        * An array of component ids or null to disable the feature. When a node is dropped on the tree we will check to see if the id of the tree the node was dragged from is present in this array, if it is we will accept the drag opperation. Defaults to null.
        */
        acceptFromComponents : null,
        /**
        * @cfg {Boolean} acceptFromSelf
        * Whether or not to accept drags from with in the same tree. Defaults to true.
        */
        acceptFromSelf : true,
        /**
        * @cfg {Boolean} copyLeafs
        * Allow copying of leaf nodes. Defaults to true.
        */
        copyLeafs : true,
        /**
        * @cfg {Boolean} copyLeafs
        * Allow copying of branch nodes. Defaults to true.
        */
        copyBranches : true,
        /**
        * @cfg {Boolean} preventCopyFromSelf
        * Prevent a copy from occuring when droping nodes that originated in this tree panel
        */
        preventCopyFromSelf : true,
        /**
        * @cfg {Boolean} copyInSameTreeChangeId
        * When a copy takes place with in the same tree that the nodes orgenated from should we generated a new id for that node () in order to prevent duplicate nodes. Defaults to true.
        */
        copyInSameTreeChangeId : true,
        /**
        * @cfg {Boolean} copyToDifferentTreeChangeId
        * When a copy takes place between 2 trees should we generated a new id for that node () in order to prevent duplicate nodes. Defaults to false.
        */
        copyToDifferentTreeChangeId : true,
        
    //!!NOTE: The following features requires Ext.ux.tree.TreePanel.toObject which can be found at: http://www.extjs.com/forum/showthread.php?t=20793. 
        /**
        * @cfg {Boolean} fullBranchCopy
        * If set to true child nodes that have been added to branches of the tree will be properly coppied when you copy a branch node -- other wise these child nodes may not be coppied properly. Defaults to false.
        */
        fullBranchCopy : false,
        /**
        * @cfg {Function|null} nodeFilter
        * A function that will be used when a fullBranchCopyOccures -- which when passed the node, returns true or false to include or exclude the node. Defaults to null;
        */
        nodeFilter : null,
        /**
        * @cfg {Function|null} attributeFilter
        * A function that will be used when a fullBranchCopyOccures -- which when passed an attribute name, and an attribute value, returns true or false to include or exclude the attribute.. Defaults to null;
        */
        attributeFilter : null,
        /**
        * @cfg {Array|null} attributeMapping
        * A associative array that will be used when a fullBranchCopyOccures -- which can you use to remap attribute names on the nodes as they are converted to an object. Keys in the array represent attributes to be remapped, and their associated values represent the new keys that those attributes will be remapped onto in the returned object. Defaults to null;
        */
        attributeMapping : null,
    //Private Functions:
        //@private
        init: function(parent){
            this.parent = parent;
            this.parent.copyDropNode = this;
            this.parent.on('beforenodedrop', this.onBeforeNodeDrop, this);
            this.parent.addEvents(
                /**
                * @event beforecopydropnode
                * Fires right before the copyDropNode function is run. This happens every time the treePanels beforenodedrop event fires. If you would like to override the standard logic used to define if a copy occures or not you may set a boolean value on the event object passed to the listener -- set a value of doCopy true or false to manually dictate whether or not a copy should occure. You may also return false from this event in order to stop the drop action from completeing enterly.
                * @param {Ext.ux.tree.TreePanel.CopyDropNode} this
                * @param {Object} e The dropNode event contains: (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.
                */
                'beforecopydropnode',
                /**
                * @event aftercopydropnode 
                * Fires right after the copyDropNode function is run.
                * @param {Ext.ux.tree.TreePanel.CopyDropNode} this
                * @param {Boolean} copied true if a copy occured, false if one did not occure
                * @param {Object} newNode the new node that was created when the copy occured
                * @param {Object} e The dropNode event contains: (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.
                */
                'aftercopydropnode'
            );
        },
        //@private
        onBeforeNodeDrop: function(e){
            var finishDrop = this.parent.fireEvent("beforecopydropnode", this, e);
            
            var enabled = this.enabled;
            var copyFromComponents = (typeof(this.copyFromComponents)=='string')?[this.copyFromComponents]:this.copyFromComponents;
            var acceptFromComponents = (typeof(this.acceptFromComponents)=='string')?[this.acceptFromComponents]:this.acceptFromComponents;
                    
            var copyLeafs = this.copyLeafs;
            var copyBranches = this.copyBranches;
            var preventCopyFromSelf = this.preventCopyFromSelf;
            var acceptFromSelf = this.acceptFromSelf;
            
            var node = e.dropNode;
            var isLeaf = (typeof(node.attributes.leaf)!='undefined' && node.attributes.leaf);
            var fromTreeId = e.source.tree.id;
            var toTreeId = e.tree.id;
            var fromSelf = (fromTreeId == toTreeId);
    
            var doCopy = e.doCopy;
            doCopy = (typeof(doCopy)=='undefined')?node.doCopy:doCopy;
            
            var newNode;
            
            finishDrop = ((Ext.isArray(acceptFromComponents) && this.inArray(acceptFromComponents, fromTreeId)) || !acceptFromComponents || (fromSelf && acceptFromSelf))?finishDrop:false;
            
            if (finishDrop) {
                if (enabled) {
                    if (typeof(doCopy)=='undefined') {
                        doCopy = ((Ext.isArray(copyFromComponents) && this.inArray(copyFromComponents, fromTreeId)) || !copyFromComponents);
                        doCopy = ((isLeaf && copyLeafs) || (!isLeaf && copyBranches))?doCopy:false;
                        doCopy = (!preventCopyFromSelf || !fromSelf)?doCopy:false;
                    }
                    newNode = (doCopy)?this.copyDropNode(e, node):null;
                    this.parent.fireEvent("aftercopydropnode", this, doCopy, newNode, e);
                }
                return true;
            } else {
                return false;
            }
        },
        //@private
        copyDropNode : function (e, node) {
        //We make a new node based on the attributes of the node that was going to be dropped and then we swap it over the old node that was on the event in order to cause the new node to be added rather than the old node to be moved. Then the rest of the standard drag and drop functionality will proceed as normal.
            var fromSelf = (node.ownerTree.id == e.tree.id), attributes;
            if (this.fullBranchCopy) {
                attributes = node.toObject(this.nodeFilter, this.attributeFilter, this.attributeMapping);
            } else {
                attributes = node.attributes
            }
            var newNode = new Ext.tree.AsyncTreeNode(attributes);
            
            if ((fromSelf && this.copyInSameTreeChangeId) || (!fromSelf && this.copyToDifferentTreeChangeId)) {
                var dummyNode = new Ext.tree.AsyncTreeNode({});
                newNode.setId(dummyNode.id);
            }
            e.dropStatus = true;
            e.dropNode = newNode;
            return newNode;
        },
        //@private
        inArray : function (array, value, caseSensitive) {
            var i;
            for (i=0; i < array.length; i++) {
                // use === to check for Matches. ie., identical (===),
                if(caseSensitive){ //performs match even the string is case sensitive
                    if (array[i].toLowerCase() == value.toLowerCase()) {
                        return true;
                    }
                }else{
                    if (array[i] == value) {
                        return true;
                    }
                }
            }
            return false;
        }
    });
    Ext.preg('ux-tree-treepanel-copydropnode', Ext.ux.tree.TreePanel.CopyDropNode);

  2. #2
    Ext User
    Join Date
    Oct 2009
    Posts
    1
    Vote Rating
    0
    ppiche is on a distinguished road

      0  

    Default How I use this plugin.

    How I use this plugin.


    Sorry to ask this question, as I am not an expert in ExtJS. I was trying the example of ExtJS with two trees and I search for a way to copy instead of moving the files to the other tree and found your post. Can I have some help on how to modify the example to do the trick?

    here is the example page I was working with:
    http://www.extjs.com/deploy/ext/exam...two-trees.html

    Thanks in advance

  3. #3
    Sencha User willf1976's Avatar
    Join Date
    May 2009
    Location
    carpinteria, ca
    Posts
    84
    Vote Rating
    0
    willf1976 is on a distinguished road

      0  

    Default


    Hi PPiche

    First of all make sure you have saved/included in your page both the js files needed for the plugin to work:
    Ext.ux.tree.TreePanel.toObject.js
    Ext.ux.tree.TreePanel.CopyDropNode.js


    And then modify the right tree (the one you want to have files copied into) to include the plugin -- here is an example of adding the plugin with lazy instantiation (lazy instantiation means that the plugin isn't created until the tree is finished being created)
    HTML Code:
     var tree2 = new Tree.TreePanel({
                    animate:true,
                    autoScroll:true,
                    //rootVisible: false,
                    loader: new Ext.tree.TreeLoader({
                        dataUrl:'get-nodes.php',
                        baseParams: {path:'extjs'} // custom http params
                    }),
    		plugins : [
    		    {ptype :'ux-tree-treepanel-copydropnode'}		   
    		],
                    containerScroll: true,
                    border: false,
                    enableDD:true,
                    dropConfig: {appendOnly:true}
                });

    Or if you don't want to use lazy instantiation you can write it like this (in this case it will do the exact same thing)

    HTML Code:
    var tree2 = new Tree.TreePanel({
                    animate:true,
                    autoScroll:true,
                    //rootVisible: false,
                    loader: new Ext.tree.TreeLoader({
                        dataUrl:'get-nodes.php',
                        baseParams: {path:'extjs'} // custom http params
                    }),
    		plugins : [
    		    new Ext.ux.tree.TreePanel.CopyDropNode()
    		],
                    containerScroll: true,
                    border: false,
                    enableDD:true,
                    dropConfig: {appendOnly:true}
                });
    I hope it all works for you .

    Best Regards

    Will Ferrer

  4. #4
    Sencha User Mjollnir26's Avatar
    Join Date
    Oct 2008
    Location
    Germany
    Posts
    152
    Vote Rating
    0
    Mjollnir26 is on a distinguished road

      0  

    Default


    This works perfectly, thank you!

  5. #5
    Sencha User
    Join Date
    Sep 2008
    Posts
    16
    Vote Rating
    0
    aborjinos is on a distinguished road

      0  

    Default


    Hi willf1976
    this sounds very cool and it is what i need

    but when i tried this script in ff an error occurs

    Error: Ext.preg is not a function
    Source File: js/core/Ext.ux.tree.TreePanel.CopyDropNode.js
    Line: 230

    and line 230 is
    Code:
    Ext.preg('ux-tree-treepanel-copydropnode', Ext.ux.tree.TreePanel.CopyDropNode);
    I am using 2.2.1 version and
    adapter/ext/ext-base.js and ext-all-debug.js are included

    Do you know what i have to do? Any solution would be great.

    Thanks

  6. #6
    Sencha User willf1976's Avatar
    Join Date
    May 2009
    Location
    carpinteria, ca
    Posts
    84
    Vote Rating
    0
    willf1976 is on a distinguished road

      0  

    Default


    Hi Aborjinos

    I think the problem may be that you are using an old version of extjs that I never tested this plug in with.

    I actually only started using extjs extensively around version 3. I suspect that version 2 doesn't use preg (registers an xtype for a plug in).

    I am currently using a slightly updated version of this plug in which I will post in this thread.

    Best regards

    Will

    Quote Originally Posted by aborjinos View Post
    Hi willf1976
    this sounds very cool and it is what i need

    but when i tried this script in ff an error occurs

    Error: Ext.preg is not a function
    Source File: js/core/Ext.ux.tree.TreePanel.CopyDropNode.js
    Line: 230

    and line 230 is
    Code:
    Ext.preg('ux-tree-treepanel-copydropnode', Ext.ux.tree.TreePanel.CopyDropNode);
    I am using 2.2.1 version and
    adapter/ext/ext-base.js and ext-all-debug.js are included

    Do you know what i have to do? Any solution would be great.

    Thanks

  7. #7
    Sencha User willf1976's Avatar
    Join Date
    May 2009
    Location
    carpinteria, ca
    Posts
    84
    Vote Rating
    0
    willf1976 is on a distinguished road

      0  

    Default


    Hi All

    I have made some changes to this plug in. The changes I have made may cause some issues for those using the plug in already so I am giving the update its own post instead of posting it over the previous version:

    HTML Code:
    /*
    author: Will Ferrer
    date: 09/03/09
    history:
        08/09/09 -- posted to ExtJS forums
        08/09/09 -- minor structural changes and changed class name
    	08/13/09 -- fixed a problem where copying nodes inside the same tree could result in duplicate node its.
    	08/21/09 -- added superclass.constructor.call for posterities sake
    	08/24/09 -- acceptFromComponents property added
    	09/02/09 -- added acceptFromSelf property
    	09/03/09 -- added fullBranchCopy, nodeFilter, attributeFilter, attributeMapping
    	09/04/09 -- added parent.copyDropNode = this;
    	04/13/10 -- made it so that the copied node is passed to listeners so they may modify it.
    	04/26/10 -- added onEndDrag function
    */
    /**
     * @class Ext.ux.tree.TreePanel.CopyDropNode
     * @extends Ext.util.Observable
     * A simple plug in for TreePanel that allows you to make nodes dropped into the tree panel be copied instead of moved to the panel.
     * Plugin includes properties that can be configured to discern what nodes should be copied and what nodes shouldn't.
     * This plugin also adds some events to the treePanel on which the plugin was applied -- these events provide additional control over when a node is copied.
     * In order to override the logic used in this plug in to determine whether a node should be copied or not, a boolean value of doCopy may be set on the node which is being dropped. 
     * You may also control this functionality by modifying the drop event itself -- please see the beforecopydropnode event definition for more details. 
     * @constructor
     * @param {Object} config The config object
     * @ptype ux-tree-treepanel-copydropnode
     */
    Ext.ns('Ext.ux.tree.TreePanel');
    Ext.ux.tree.TreePanel.CopyDropNode = function(config){
        Ext.apply(this, config);
    	Ext.ux.tree.TreePanel.CopyDropNode.superclass.constructor.call(this);
    };
    Ext.extend(Ext.ux.tree.TreePanel.CopyDropNode, Ext.util.Observable, {
    //Public Properties:
        /**
        * @cfg {Boolean} enabled
        * Whether or not copying is enabled -- if set to false this plug in will stop copying nodes. Defaults to true.
        */
        enabled : true,
        /**
        * @cfg {Mixed} copyFromComponents
        * An array of component ids or null to disable the feature. When a node is dropped on the tree we will check to see if the id of the tree the node was dragged from is present in this array, if it is we will copy the node rather than moving it. If set to null then which tree the node was dragged from won't be a factor in whether it is coppied or not. Defaults to null.
        */
        copyFromComponents : null,
    	/**
        * @cfg {Boolean} rejectFromComponents
        * An array of component ids or null to disable the feature. When a node is dropped on the tree we will check to see if the id of the tree the node was dragged from is present in this array, if it is we will accept the drag opperation. Defaults to null.
        */
    	acceptFromComponents : null,
    	/**
        * @cfg {Boolean} acceptFromSelf
        * Whether or not to accept drags from with in the same tree. Defaults to true.
        */
    	acceptFromSelf : true,
        /**
        * @cfg {Boolean} copyLeafs
        * Allow copying of leaf nodes. Defaults to true.
        */
        copyLeafs : true,
        /**
        * @cfg {Boolean} copyLeafs
        * Allow copying of branch nodes. Defaults to true.
        */
        copyBranches : true,
        /**
        * @cfg {Boolean} preventCopyFromSelf
        * Prevent a copy from occuring when droping nodes that originated in this tree panel
        */
        preventCopyFromSelf : true,
    	/**
        * @cfg {Boolean} copyInSameTreeChangeId
        * When a copy takes place with in the same tree that the nodes orgenated from should we generated a new id for that node () in order to prevent duplicate nodes. Defaults to true.
        */
    	copyInSameTreeChangeId : true,
    	/**
        * @cfg {Boolean} copyToDifferentTreeChangeId
        * When a copy takes place between 2 trees should we generated a new id for that node () in order to prevent duplicate nodes. Defaults to false.
        */
    	copyToDifferentTreeChangeId : true,
    	
    //!!NOTE: The following features requires Ext.ux.tree.TreePanel.toObject which can be found at: http://www.extjs.com/forum/showthread.php?t=20793. 
    	/**
        * @cfg {Boolean} fullBranchCopy
        * If set to true child nodes that have been added to branches of the tree will be properly coppied when you copy a branch node -- other wise these child nodes may not be coppied properly. Defaults to false.
        */
    	fullBranchCopy : false,
    	/**
        * @cfg {Function|null} nodeFilter
        * A function that will be used when a fullBranchCopyOccures -- which when passed the node, returns true or false to include or exclude the node. Defaults to null;
        */
    	nodeFilter : null,
    	/**
        * @cfg {Function|null} attributeFilter
        * A function that will be used when a fullBranchCopyOccures -- which when passed an attribute name, and an attribute value, returns true or false to include or exclude the attribute.. Defaults to null;
        */
    	attributeFilter : null,
    	/**
        * @cfg {Array|null} attributeMapping
        * A associative array that will be used when a fullBranchCopyOccures -- which can you use to remap attribute names on the nodes as they are converted to an object. Keys in the array represent attributes to be remapped, and their associated values represent the new keys that those attributes will be remapped onto in the returned object. Defaults to null;
        */
    	attributeMapping : null,
    //Private Functions:
        //@private
        init: function(parent){
            this.parent = parent;
    		this.parent.copyDropNode = this;
            this.parent.on('beforenodedrop', this.onBeforeNodeDrop, this);
    		this.parent.on('enddrag', this.onEndDrag, this);
            this.parent.addEvents(
                /**
                * @event beforecopydropnode
                * Fires right before the copyDropNode function is run. This happens every time the treePanels beforenodedrop event fires. If you would like to override the standard logic used to define if a copy occures or not you may set a boolean value on the event object passed to the listener -- set a value of doCopy true or false to manually dictate whether or not a copy should occure. You may also return false from this event in order to stop the drop action from completeing enterly.
                * @param {Ext.ux.tree.TreePanel.CopyDropNode} this
                * @param {Object} e The dropNode event contains: (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.
                */
                'beforecopydropnode',
                /**
                * @event aftercopydropnode 
                * Fires right after the copyDropNode function is run.
                * @param {Ext.ux.tree.TreePanel.CopyDropNode} this
                * @param {Object} e The dropNode event contains: (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.
                */
                'aftercopydropnode'
            );
        },
        //@private
        onBeforeNodeDrop: function(e){
            var enabled = this.enabled;
            var copyFromComponents = (typeof(this.copyFromComponents)=='string')?[this.copyFromComponents]:this.copyFromComponents;
    		var acceptFromComponents = (typeof(this.acceptFromComponents)=='string')?[this.acceptFromComponents]:this.acceptFromComponents;
    				
            var copyLeafs = this.copyLeafs;
            var copyBranches = this.copyBranches;
            var preventCopyFromSelf = this.preventCopyFromSelf;
    		var acceptFromSelf = this.acceptFromSelf;
    
            var node = e.dropNode;
            var isLeaf = (!Ext.isEmpty(node.attributes.leaf) && node.attributes.leaf)?true:false;
            var fromTreeId = e.source.tree.id;
            var toTreeId = e.tree.id;
            var fromSelf = (fromTreeId == toTreeId)?true:false;
    
            var doCopy = e.doCopy;
            doCopy = (typeof(doCopy)=='undefined')?node.doCopy:doCopy;
            
            var newNode;
    		if (enabled) {
    			if (typeof(doCopy)=='undefined') {
    				doCopy = ((Ext.isArray(copyFromComponents) && this.inArray(copyFromComponents, fromTreeId)) || !copyFromComponents);
    				doCopy = ((isLeaf && copyLeafs) || (!isLeaf && copyBranches))?doCopy:false;
    				doCopy = (!preventCopyFromSelf || !fromSelf)?doCopy:false;
    			}
    			newNode = (doCopy)?this.copyDropNode(e, node):null;
    		}
            var finishDrop = this.parent.fireEvent("beforecopydropnode", this, e);
    		finishDrop = ((Ext.isArray(acceptFromComponents) && this.inArray(acceptFromComponents, fromTreeId)) || !acceptFromComponents || (fromSelf && acceptFromSelf))?finishDrop:false;
    		
            if (finishDrop) {
    			e.tree.on('nodedrop', function (e) {
    				this.parent.fireEvent("aftercopydropnode", this, e);
    			}, this, {single:true});
             	//this.parent.fireEvent("aftercopydropnode", this, doCopy, newNode, e);
                return true;
            } else {
                return false;
            }
        },
    	//@private
        onEndDrag: function(target, node, e){
          this.parent.fireEvent("aftercopydropnode", this, node, e);
        },
        //@private
        copyDropNode : function (e, node) {
        //We make a new node based on the attributes of the node that was going to be dropped and then we swap it over the old node that was on the event in order to cause the new node to be added rather than the old node to be moved. Then the rest of the standard drag and drop functionality will proceed as normal.
    		var fromSelf = (node.ownerTree.id == e.tree.id), attributes;
    		if (this.fullBranchCopy) {
    			attributes = node.toObject(this.nodeFilter, this.attributeFilter, this.attributeMapping);
    		} else {
    			attributes = node.attributes
    		}
    		
    		var newNode = new Ext.tree.AsyncTreeNode(attributes);
    		
    		if ((fromSelf && this.copyInSameTreeChangeId) || (!fromSelf && this.copyToDifferentTreeChangeId)) {
    			var dummyNode = new Ext.tree.AsyncTreeNode({});
    			newNode.setId(dummyNode.id);
    		}
            e.dropStatus = true;
            e.dropNode = newNode;
    		e.dropNode.ownerTree = node.ownerTree;
    		
            return newNode;
        },
        //@private
        inArray : function (array, value, caseSensitive) {
            var i;
            for (i=0; i < array.length; i++) {
                // use === to check for Matches. ie., identical (===),
                if(caseSensitive){ //performs match even the string is case sensitive
                    if (array[i].toLowerCase() == value.toLowerCase()) {
                        return true;
                    }
                }else{
                    if (array[i] == value) {
                        return true;
                    }
                }
            }
            return false;
        }
    });
    Ext.preg('ux-tree-treepanel-copydropnode', Ext.ux.tree.TreePanel.CopyDropNode);

  8. #8
    Sencha User willf1976's Avatar
    Join Date
    May 2009
    Location
    carpinteria, ca
    Posts
    84
    Vote Rating
    0
    willf1976 is on a distinguished road

      0  

    Default


    Hi All

    Here is an updated version of this plug in which may not work quite the same as it did before if you already using the plug in. For this reason I am posting it separately instead of just posting it over the old version of the plug in.

    HTML Code:
    /*
    author: Will Ferrer
    date: 09/03/09
    history:
        08/09/09 -- posted to ExtJS forums
        08/09/09 -- minor structural changes and changed class name
    	08/13/09 -- fixed a problem where copying nodes inside the same tree could result in duplicate node its.
    	08/21/09 -- added superclass.constructor.call for posterities sake
    	08/24/09 -- acceptFromComponents property added
    	09/02/09 -- added acceptFromSelf property
    	09/03/09 -- added fullBranchCopy, nodeFilter, attributeFilter, attributeMapping
    	09/04/09 -- added parent.copyDropNode = this;
    	04/13/10 -- made it so that the copied node is passed to listeners so they may modify it.
    	04/26/10 -- added onEndDrag function
    */
    /**
     * @class Ext.ux.tree.TreePanel.CopyDropNode
     * @extends Ext.util.Observable
     * A simple plug in for TreePanel that allows you to make nodes dropped into the tree panel be copied instead of moved to the panel.
     * Plugin includes properties that can be configured to discern what nodes should be copied and what nodes shouldn't.
     * This plugin also adds some events to the treePanel on which the plugin was applied -- these events provide additional control over when a node is copied.
     * In order to override the logic used in this plug in to determine whether a node should be copied or not, a boolean value of doCopy may be set on the node which is being dropped. 
     * You may also control this functionality by modifying the drop event itself -- please see the beforecopydropnode event definition for more details. 
     * @constructor
     * @param {Object} config The config object
     * @ptype ux-tree-treepanel-copydropnode
     */
    Ext.ns('Ext.ux.tree.TreePanel');
    Ext.ux.tree.TreePanel.CopyDropNode = function(config){
        Ext.apply(this, config);
    	Ext.ux.tree.TreePanel.CopyDropNode.superclass.constructor.call(this);
    };
    Ext.extend(Ext.ux.tree.TreePanel.CopyDropNode, Ext.util.Observable, {
    //Public Properties:
        /**
        * @cfg {Boolean} enabled
        * Whether or not copying is enabled -- if set to false this plug in will stop copying nodes. Defaults to true.
        */
        enabled : true,
        /**
        * @cfg {Mixed} copyFromComponents
        * An array of component ids or null to disable the feature. When a node is dropped on the tree we will check to see if the id of the tree the node was dragged from is present in this array, if it is we will copy the node rather than moving it. If set to null then which tree the node was dragged from won't be a factor in whether it is coppied or not. Defaults to null.
        */
        copyFromComponents : null,
    	/**
        * @cfg {Boolean} rejectFromComponents
        * An array of component ids or null to disable the feature. When a node is dropped on the tree we will check to see if the id of the tree the node was dragged from is present in this array, if it is we will accept the drag opperation. Defaults to null.
        */
    	acceptFromComponents : null,
    	/**
        * @cfg {Boolean} acceptFromSelf
        * Whether or not to accept drags from with in the same tree. Defaults to true.
        */
    	acceptFromSelf : true,
        /**
        * @cfg {Boolean} copyLeafs
        * Allow copying of leaf nodes. Defaults to true.
        */
        copyLeafs : true,
        /**
        * @cfg {Boolean} copyLeafs
        * Allow copying of branch nodes. Defaults to true.
        */
        copyBranches : true,
        /**
        * @cfg {Boolean} preventCopyFromSelf
        * Prevent a copy from occuring when droping nodes that originated in this tree panel
        */
        preventCopyFromSelf : true,
    	/**
        * @cfg {Boolean} copyInSameTreeChangeId
        * When a copy takes place with in the same tree that the nodes orgenated from should we generated a new id for that node () in order to prevent duplicate nodes. Defaults to true.
        */
    	copyInSameTreeChangeId : true,
    	/**
        * @cfg {Boolean} copyToDifferentTreeChangeId
        * When a copy takes place between 2 trees should we generated a new id for that node () in order to prevent duplicate nodes. Defaults to false.
        */
    	copyToDifferentTreeChangeId : true,
    	
    //!!NOTE: The following features requires Ext.ux.tree.TreePanel.toObject which can be found at: http://www.extjs.com/forum/showthread.php?t=20793. 
    	/**
        * @cfg {Boolean} fullBranchCopy
        * If set to true child nodes that have been added to branches of the tree will be properly coppied when you copy a branch node -- other wise these child nodes may not be coppied properly. Defaults to false.
        */
    	fullBranchCopy : false,
    	/**
        * @cfg {Function|null} nodeFilter
        * A function that will be used when a fullBranchCopyOccures -- which when passed the node, returns true or false to include or exclude the node. Defaults to null;
        */
    	nodeFilter : null,
    	/**
        * @cfg {Function|null} attributeFilter
        * A function that will be used when a fullBranchCopyOccures -- which when passed an attribute name, and an attribute value, returns true or false to include or exclude the attribute.. Defaults to null;
        */
    	attributeFilter : null,
    	/**
        * @cfg {Array|null} attributeMapping
        * A associative array that will be used when a fullBranchCopyOccures -- which can you use to remap attribute names on the nodes as they are converted to an object. Keys in the array represent attributes to be remapped, and their associated values represent the new keys that those attributes will be remapped onto in the returned object. Defaults to null;
        */
    	attributeMapping : null,
    //Private Functions:
        //@private
        init: function(parent){
            this.parent = parent;
    		this.parent.copyDropNode = this;
            this.parent.on('beforenodedrop', this.onBeforeNodeDrop, this);
    		this.parent.on('enddrag', this.onEndDrag, this);
            this.parent.addEvents(
                /**
                * @event beforecopydropnode
                * Fires right before the copyDropNode function is run. This happens every time the treePanels beforenodedrop event fires. If you would like to override the standard logic used to define if a copy occures or not you may set a boolean value on the event object passed to the listener -- set a value of doCopy true or false to manually dictate whether or not a copy should occure. You may also return false from this event in order to stop the drop action from completeing enterly.
                * @param {Ext.ux.tree.TreePanel.CopyDropNode} this
                * @param {Object} e The dropNode event contains: (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.
                */
                'beforecopydropnode',
                /**
                * @event aftercopydropnode 
                * Fires right after the copyDropNode function is run.
                * @param {Ext.ux.tree.TreePanel.CopyDropNode} this
                * @param {Object} e The dropNode event contains: (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.
                */
                'aftercopydropnode'
            );
        },
        //@private
        onBeforeNodeDrop: function(e){
            var enabled = this.enabled;
            var copyFromComponents = (typeof(this.copyFromComponents)=='string')?[this.copyFromComponents]:this.copyFromComponents;
    		var acceptFromComponents = (typeof(this.acceptFromComponents)=='string')?[this.acceptFromComponents]:this.acceptFromComponents;
    				
            var copyLeafs = this.copyLeafs;
            var copyBranches = this.copyBranches;
            var preventCopyFromSelf = this.preventCopyFromSelf;
    		var acceptFromSelf = this.acceptFromSelf;
    
            var node = e.dropNode;
            var isLeaf = (!Ext.isEmpty(node.attributes.leaf) && node.attributes.leaf)?true:false;
            var fromTreeId = e.source.tree.id;
            var toTreeId = e.tree.id;
            var fromSelf = (fromTreeId == toTreeId)?true:false;
    
            var doCopy = e.doCopy;
            doCopy = (typeof(doCopy)=='undefined')?node.doCopy:doCopy;
            
            var newNode;
    		if (enabled) {
    			if (typeof(doCopy)=='undefined') {
    				doCopy = ((Ext.isArray(copyFromComponents) && this.inArray(copyFromComponents, fromTreeId)) || !copyFromComponents);
    				doCopy = ((isLeaf && copyLeafs) || (!isLeaf && copyBranches))?doCopy:false;
    				doCopy = (!preventCopyFromSelf || !fromSelf)?doCopy:false;
    			}
    			newNode = (doCopy)?this.copyDropNode(e, node):null;
    		}
            var finishDrop = this.parent.fireEvent("beforecopydropnode", this, e);
    		finishDrop = ((Ext.isArray(acceptFromComponents) && this.inArray(acceptFromComponents, fromTreeId)) || !acceptFromComponents || (fromSelf && acceptFromSelf))?finishDrop:false;
    		
            if (finishDrop) {
    			e.tree.on('nodedrop', function (e) {
    				this.parent.fireEvent("aftercopydropnode", this, e);
    			}, this, {single:true});
             	//this.parent.fireEvent("aftercopydropnode", this, doCopy, newNode, e);
                return true;
            } else {
                return false;
            }
        },
    	//@private
        onEndDrag: function(target, node, e){
          this.parent.fireEvent("aftercopydropnode", this, node, e);
        },
        //@private
        copyDropNode : function (e, node) {
        //We make a new node based on the attributes of the node that was going to be dropped and then we swap it over the old node that was on the event in order to cause the new node to be added rather than the old node to be moved. Then the rest of the standard drag and drop functionality will proceed as normal.
    		var fromSelf = (node.ownerTree.id == e.tree.id), attributes;
    		if (this.fullBranchCopy) {
    			attributes = node.toObject(this.nodeFilter, this.attributeFilter, this.attributeMapping);
    		} else {
    			attributes = node.attributes
    		}
    		
    		var newNode = new Ext.tree.AsyncTreeNode(attributes);
    		
    		if ((fromSelf && this.copyInSameTreeChangeId) || (!fromSelf && this.copyToDifferentTreeChangeId)) {
    			var dummyNode = new Ext.tree.AsyncTreeNode({});
    			newNode.setId(dummyNode.id);
    		}
            e.dropStatus = true;
            e.dropNode = newNode;
    		e.dropNode.ownerTree = node.ownerTree;
    		
            return newNode;
        },
        //@private
        inArray : function (array, value, caseSensitive) {
            var i;
            for (i=0; i < array.length; i++) {
                // use === to check for Matches. ie., identical (===),
                if(caseSensitive){ //performs match even the string is case sensitive
                    if (array[i].toLowerCase() == value.toLowerCase()) {
                        return true;
                    }
                }else{
                    if (array[i] == value) {
                        return true;
                    }
                }
            }
            return false;
        }
    });
    Ext.preg('ux-tree-treepanel-copydropnode', Ext.ux.tree.TreePanel.CopyDropNode);

  9. #9
    Ext User
    Join Date
    Nov 2010
    Posts
    3
    Vote Rating
    0
    sam.vloeberghs is on a distinguished road

      0  

    Question


    Hi Willf1976,

    I have a simalar setup as ppiche,mentioned in this topic, based on this example:
    http://dev.sencha.com/deploy/ext/exa...two-trees.html

    When I drag a node to from the left tree to the right three, all works fine! The node is copied.
    But I can't seem to get a reference to the node that has been dropped in the right three..

    How can I get a reference to this Treenode?

    Greetings
    Sam Vloeberghs

  10. #10
    Sencha User willf1976's Avatar
    Join Date
    May 2009
    Location
    carpinteria, ca
    Posts
    84
    Vote Rating
    0
    willf1976 is on a distinguished road

      0  

    Default


    Hi Sam

    You can always use the findChild and findChildBy methods of the treeNode, or use a listener on the CopyDropNode class to modify our record the node as it is being copied. Also this post reminded me I should post my latest version of the plugin -- see below.

    HTML Code:
    /*
    author: Will Ferrer
    date: 09/03/09
    history:
        08/09/09 -- posted to ExtJS forums
        08/09/09 -- minor structural changes and changed class name
    	08/13/09 -- fixed a problem where copying nodes inside the same tree could result in duplicate node its.
    	08/21/09 -- added superclass.constructor.call for posterities sake
    	08/24/09 -- acceptFromComponents property added
    	09/02/09 -- added acceptFromSelf property
    	09/03/09 -- added fullBranchCopy, nodeFilter, attributeFilter, attributeMapping
    	09/04/09 -- added parent.copyDropNode = this;
    	04/13/10 -- made it so that the copied node is passed to listeners so they may modify it.
    	04/26/10 -- added onEndDrag function
    	05/04/10 -- load nodes after add
    	06/18/10 -- prevented the copying from taking place when it shouldn't.
    */
    /**
     * @class Ext.ux.tree.TreePanel.CopyDropNode
     * @extends Ext.util.Observable
     * A simple plug in for TreePanel that allows you to make nodes dropped into the tree panel be copied instead of moved to the panel.
     * Plugin includes properties that can be configured to discern what nodes should be copied and what nodes shouldn't.
     * This plugin also adds some events to the treePanel on which the plugin was applied -- these events provide additional control over when a node is copied.
     * In order to override the logic used in this plug in to determine whether a node should be copied or not, a boolean value of doCopy may be set on the node which is being dropped. 
     * You may also control this functionality by modifying the drop event itself -- please see the beforecopydropnode event definition for more details. 
     * @constructor
     * @param {Object} config The config object
     * @ptype ux-tree-treepanel-copydropnode
     */
    Ext.ns('Ext.ux.tree.TreePanel');
    Ext.ux.tree.TreePanel.CopyDropNode = function(config){
        Ext.apply(this, config);
    	Ext.ux.tree.TreePanel.CopyDropNode.superclass.constructor.call(this);
    };
    Ext.extend(Ext.ux.tree.TreePanel.CopyDropNode, Ext.util.Observable, {
    //Public Properties:
        /**
        * @cfg {Boolean} enabled
        * Whether or not copying is enabled -- if set to false this plug in will stop copying nodes. Defaults to true.
        */
        enabled : true,
        /**
        * @cfg {Mixed} copyFromComponents
        * An array of component ids or null to disable the feature. When a node is dropped on the tree we will check to see if the id of the tree the node was dragged from is present in this array, if it is we will copy the node rather than moving it. If set to null then which tree the node was dragged from won't be a factor in whether it is coppied or not. Defaults to null.
        */
        copyFromComponents : null,
    	/**
        * @cfg {Boolean} rejectFromComponents
        * An array of component ids or null to disable the feature. When a node is dropped on the tree we will check to see if the id of the tree the node was dragged from is present in this array, if it is we will accept the drag opperation. Defaults to null.
        */
    	acceptFromComponents : null,
    	/**
        * @cfg {Boolean} acceptFromSelf
        * Whether or not to accept drags from with in the same tree. Defaults to true.
        */
    	acceptFromSelf : true,
        /**
        * @cfg {Boolean} copyLeafs
        * Allow copying of leaf nodes. Defaults to true.
        */
        copyLeafs : true,
        /**
        * @cfg {Boolean} copyLeafs
        * Allow copying of branch nodes. Defaults to true.
        */
        copyBranches : true,
        /**
        * @cfg {Boolean} preventCopyFromSelf
        * Prevent a copy from occuring when droping nodes that originated in this tree panel
        */
        preventCopyFromSelf : true,
    	/**
        * @cfg {Boolean} copyInSameTreeChangeId
        * When a copy takes place with in the same tree that the nodes orgenated from should we generated a new id for that node () in order to prevent duplicate nodes. Defaults to true.
        */
    	copyInSameTreeChangeId : true,
    	/**
        * @cfg {Boolean} copyToDifferentTreeChangeId
        * When a copy takes place between 2 trees should we generated a new id for that node () in order to prevent duplicate nodes. Defaults to false.
        */
    	copyToDifferentTreeChangeId : true,
    	
    //!!NOTE: The following features requires Ext.ux.tree.TreePanel.toObject which can be found at: http://www.extjs.com/forum/showthread.php?t=20793. 
    	/**
        * @cfg {Boolean} fullBranchCopy
        * If set to true child nodes that have been added to branches of the tree will be properly coppied when you copy a branch node -- other wise these child nodes may not be coppied properly. Defaults to false.
        */
    	fullBranchCopy : false,
    	/**
        * @cfg {Function|null} nodeFilter
        * A function that will be used when a fullBranchCopyOccures -- which when passed the node, returns true or false to include or exclude the node. Defaults to null;
        */
    	nodeFilter : null,
    	/**
        * @cfg {Function|null} attributeFilter
        * A function that will be used when a fullBranchCopyOccures -- which when passed an attribute name, and an attribute value, returns true or false to include or exclude the attribute.. Defaults to null;
        */
    	attributeFilter : null,
    	/**
        * @cfg {Array|null} attributeMapping
        * A associative array that will be used when a fullBranchCopyOccures -- which can you use to remap attribute names on the nodes as they are converted to an object. Keys in the array represent attributes to be remapped, and their associated values represent the new keys that those attributes will be remapped onto in the returned object. Defaults to null;
        */
    	attributeMapping : null,
    	/**
        * @cfg {Boolean} loadCoppiedNodes
        * Whether or not to load coppied nodes -- be aware that nodes that have not been loaded do not have there children attribute transfered into childNodes. Defaults to true;
        */
    	loadCoppiedNodes : true,
    //Private Functions:
        // @private
        init: function(parent){
            this.parent = parent;
    		this.parent.copyDropNode = this;
            this.parent.on('beforenodedrop', this.onBeforeNodeDrop, this);
    		this.parent.on('enddrag', this.onEndDrag, this);	
            this.parent.addEvents(
                /**
                * @event beforecopydropnode
                * Fires right before the copyDropNode function is run. This happens every time the treePanels beforenodedrop event fires. If you would like to override the standard logic used to define if a copy occures or not you may set a boolean value on the event object passed to the listener -- set a value of doCopy true or false to manually dictate whether or not a copy should occure. You may also return false from this event in order to stop the drop action from completeing enterly.
                * @param {Ext.ux.tree.TreePanel.CopyDropNode} this
                * @param {Object} e The dropNode event contains: (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.
                */
                'beforecopydropnode',
                /**
                * @event aftercopydropnode 
                * Fires right after the copyDropNode function is run.
                * @param {Ext.ux.tree.TreePanel.CopyDropNode} this
                * @param {Object} e The dropNode event contains: (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.
                */
                'aftercopydropnode'
            );
        },
        // @private
        onBeforeNodeDrop: function(e){
            var enabled = this.enabled;
            var copyFromComponents = (typeof(this.copyFromComponents)=='string')?[this.copyFromComponents]:this.copyFromComponents;
    		var acceptFromComponents = (typeof(this.acceptFromComponents)=='string')?[this.acceptFromComponents]:this.acceptFromComponents;
    				
            var copyLeafs = this.copyLeafs;
            var copyBranches = this.copyBranches;
            var preventCopyFromSelf = this.preventCopyFromSelf;
    		var acceptFromSelf = this.acceptFromSelf;
    
            var node = e.dropNode;
            var isLeaf = (!Ext.isEmpty(node.attributes.leaf) && node.attributes.leaf)?true:false;
            var fromTreeId = e.source.tree.id;
            var toTreeId = e.tree.id;
            var fromSelf = (fromTreeId == toTreeId)?true:false;
    
            var doCopy = e.doCopy;
            doCopy = (typeof(doCopy)=='undefined')?node.doCopy:doCopy;
            
            var newNode;
    		if (enabled) {
    			if (typeof(doCopy)=='undefined') {
    				doCopy = ((Ext.isArray(copyFromComponents) && Ext.ux.inArray(fromTreeId, copyFromComponents)) || !copyFromComponents);
    				doCopy = ((isLeaf && copyLeafs) || (!isLeaf && copyBranches))?doCopy:false;
    				doCopy = (!preventCopyFromSelf || !fromSelf)?doCopy:false;
    			}
    			newNode = (doCopy)?this.copyDropNode(e, node):null;
    		}
    		
    		if (!Ext.isEmpty(newNode)) {
    			var finishDrop = this.parent.fireEvent("beforecopydropnode", this, e);
    			finishDrop = ((Ext.isArray(acceptFromComponents) && Ext.ux.inArray(fromTreeId, acceptFromComponents)) || !acceptFromComponents || (fromSelf && acceptFromSelf))?finishDrop:false;
    	
    			if (finishDrop) {
    				e.tree.on('nodedrop', function (e) {
    					if (this.loadCoppiedNodes) {
    						var loader = e.dropNode.loader || e.dropNode.attributes.loader || e.dropNode.getOwnerTree().getLoader();
    						loader.load(e.dropNode, e.dropNode.loadComplete.createDelegate(e.dropNode, [false, false, null, null]), e.dropNode);
    					}
    					this.parent.fireEvent("aftercopydropnode", this, e);
    				}, this, {single:true});
    				//this.parent.fireEvent("aftercopydropnode", this, doCopy, newNode, e);
    				return true;
    			} else {
    				return false;
    			}
    		}
    
        },
    	// @private
        onEndDrag: function(target, node, e){
          this.parent.fireEvent("aftercopydropnode", this, node, e);
        },
        // @private
        copyDropNode : function (e, node) {
        //We make a new node based on the attributes of the node that was going to be dropped and then we swap it over the old node that was on the event in order to cause the new node to be added rather than the old node to be moved. Then the rest of the standard drag and drop functionality will proceed as normal.
    		var fromSelf = (node.ownerTree.id == e.tree.id), attributes;
    		if (this.fullBranchCopy) {
    			attributes = node.toObject(this.nodeFilter, this.attributeFilter, this.attributeMapping);
    		} else {
    			attributes = node.attributes
    		}
    		
    		var newNode = new Ext.tree.AsyncTreeNode(attributes);
    		
    		if ((fromSelf && this.copyInSameTreeChangeId) || (!fromSelf && this.copyToDifferentTreeChangeId)) {
    			var dummyNode = new Ext.tree.AsyncTreeNode({});
    			newNode.setId(dummyNode.id);
    		}
    		
            e.dropStatus = true;
            e.dropNode = newNode;
    		e.dropNode.ownerTree = node.ownerTree;
    		
            return newNode;
        },
        // @private
        inArray : function (array, value, caseSensitive) {
            var i;
            for (i=0; i < array.length; i++) {
                // use === to check for Matches. ie., identical (===),
                if(caseSensitive){ //performs match even the string is case sensitive
                    if (array[i].toLowerCase() == value.toLowerCase()) {
                        return true;
                    }
                }else{
                    if (array[i] == value) {
                        return true;
                    }
                }
            }
            return false;
        }
    });
    Ext.preg('ux-tree-treepanel-copydropnode', Ext.ux.tree.TreePanel.CopyDropNode);
    Let me know if that helps

    Will Ferrer

film izle

hd film izle

film sitesi

takipci kazanma sitesi

takipci kazanma sitesi

güzel olan herşey

takipci alma sitesi

komik eğlenceli videolar