Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Drag&drop action - smartgwt Tree - new order of nodes + custom d&d action

    Hi all,

    I want to have the new order of nodes after drag&drop action was made in the onDrop method from addDropHandler.

    Here's the code:

    Code:
    package de.vogella.gwt.helloworld.client;
    
    import com.google.gwt.core.client.EntryPoint;
    import com.google.gwt.user.client.ui.RootPanel;
    import com.smartgwt.client.types.TreeModelType;
    import com.smartgwt.client.widgets.events.DropEvent;
    import com.smartgwt.client.widgets.events.DropHandler;
    import com.smartgwt.client.widgets.tree.Tree;
    import com.smartgwt.client.widgets.tree.TreeGrid;
    import com.smartgwt.client.widgets.tree.TreeNode;
    
    public class HelloGwt implements EntryPoint {
    
        private static final String NAVPATH_ROOT = "/";
        Tree nodesTree = null;
    
        @Override
        public void onModuleLoad() {
            // Tree structure
            nodesTree = new Tree();
            nodesTree.setRootValue(NAVPATH_ROOT);
            nodesTree.setModelType(TreeModelType.PARENT);
    
            TreeGrid navTreeGrid = new TreeGrid();
            navTreeGrid.setCanReorderRecords(true);
            navTreeGrid.setCanReparentNodes(true);
            navTreeGrid.setData(nodesTree);
    
            TreeNode newNode = new TreeNode();
            newNode.setTitle("a1");
            nodesTree.add(newNode, NAVPATH_ROOT);
    
            TreeNode newNode2 = new TreeNode();
            newNode2.setTitle("a2");
            nodesTree.add(newNode2, newNode);
    
            TreeNode newNode3 = new TreeNode();
            newNode3.setTitle("a3");
            nodesTree.add(newNode3, NAVPATH_ROOT);
    
            TreeNode newNode4 = new TreeNode();
            newNode4.setTitle("a4");
            nodesTree.add(newNode4, newNode3);
    
            navTreeGrid.addDropHandler(new DropHandler() {
                @Override
                public void onDrop(DropEvent event) {
                    resetNodesAttributes(); 
                }
            });
    
            RootPanel.get().add(navTreeGrid);
        }
    
    
        public void resetNodesAttributes() {
            // here I want to have the new order of nodes after d&d action was made
            for (TreeNode node : nodesTree.getAllNodes()) {
               System.out.println(node.getName());
            }
        }
    
    }
    If I'm using new com.smartgwt.client.widgets.tree.DataChangedHandler():

    Code:
    nodesTree.addDataChangedHandler(new com.smartgwt.client.widgets.tree.DataChangedHandler() 
    {
       @Override
       public void onDataChanged(com.smartgwt.client.widgets.tree.DataChangedEvent dataChangedEvent) 
       {
            resetNodesAttributes();
       }
    });
    the order is ok in resetNodesAttributes() method, but this method it is called to many times and I have bigger tree-s structures and I do not want this happen

    And another question I have: how can I add a custom drag&drop action to my tree?

    Thank you a lot!

    #2
    You should be using the FolderDropHandler. I use it in the following manner:

    Code:
            treeGrid.addFolderDropHandler(new FolderDropHandler() {
                List<TreeNode> toUpdate;
    
                void addToUpdatesList(TreeNode node, TreeNode[] movedNodes, String newParent) {
                    for (TreeNode moved : movedNodes) {
                        if (node.getAttribute("_id").equals(moved.getAttribute("_id"))
                                && !sameParents(node.getAttribute("parentId"), newParent)) {
                            return;
                        }
                    }
                    for (TreeNode updating : toUpdate) {
                        if (updating.getAttribute("_id").equals(node.getAttribute("_id")))
                            return;
                    }
                    toUpdate.add(node);
                }
    
                private boolean sameParents(String parent, String newParent) {
                    return (parent != null && parent.equals(newParent) || (parent == newParent));
                }
    
                @Override
                public void onFolderDrop(FolderDropEvent event) {
                    toUpdate = new ArrayList<TreeNode>();
                    TreeNode[] children = treeGrid.getTree().getChildren(event.getFolder());
                    TreeNode placeAfterNode = null;
                    if (event.getIndex() > 0) {
                        placeAfterNode = children[event.getIndex() - 1];
    
                    }
                    for (TreeNode movedNode : event.getNodes()) {
                        TreeNode parent = treeGrid.getTree().getParent(movedNode);
                        boolean adjust = false;
                        for (TreeNode sibling : treeGrid.getTree().getChildren(parent)) {
                            if (sibling.getAttribute("_id").equals(movedNode.getAttribute("_id"))) {
                                adjust = true;
                                continue;
                            }
                            if (adjust) {
                                sibling.setAttribute("position", sibling.getAttributeAsInt("position") - 1);
                                addToUpdatesList(sibling, event.getNodes(), event.getFolder().getAttribute("_id"));
                            }
                        }
                    }
    
                    boolean adjust = false;
                    for (int i = 0; i < children.length; i++) {
                        if (event.getIndex() == i) {
                            adjust = true;
                        }
                        if (adjust) {
                            children[i].setAttribute("position", children[i].getAttributeAsInt("position") + event.getNodes().length);
                            addToUpdatesList(children[i], event.getNodes(), event.getFolder().getAttribute("_id"));
                        }
                    }
    
    
                    int position = 0;
                    if (placeAfterNode != null)
                        position = placeAfterNode.getAttributeAsInt("position") + 1;
    
                    for (int i = 0; i < event.getNodes().length; i++) {
                        event.getNodes()[i].setAttribute("position", position + i);
                    }
    
                    for (TreeNode update : toUpdate) {
                        treeGrid.updateData(update);
                    }
                }
            });
    It automatically updates the 'position' and 'parentId' attributes of any nodes involved in the move, provided that attribute is set correctly (nodes are inserted with incremental position in my case) to begin with.

    Hope this helps,
    Andrius J.

    Comment

    Working...
    X