0

I've implemented a TreeGrid, that is bound to a RestDataSource in SmartGWT. To provide a numeration, i have a TreeGridField called requirementListing, which is calculated on the client-side. After each update, i run a function that (re)calculates the numeration.

the numeration looks like this.

1. Item 1 in level 0
|_ 1.1 item 1 in level 1
     |_ 1.1.1 item 1 in level 2
2. Item 2 in level 0

To trigger the calculation function after an update of a node accured, i've used several Handlers like

  • DataArrivedHandler
  • EditCompleteHandler
  • RemoveRecordClickHandler

All these work properly, the only case the numeration doesn't update is, if I move an item to another folder (or within a folder). I tried to call the numeration function from DropCompleteHandler and FolderDropHandler, none of them seem to work. After reading Tree - drag&drop nodes - refresh? I'm using a DeferredComand, which worked in Chrome, but not in Firefox. With the newest version of SmartGWT it won't work in Chrome either.

requirementTreeGrid.addDropCompleteHandler(new DropCompleteHandler() {

        @SuppressWarnings("deprecation")
        @Override
        public void onDropComplete(DropCompleteEvent event) {
            SC.logInfo("Drop complete");
            DeferredCommand.addCommand(new Command() {
                public void execute() {
                  treeNumerator.addTreeNumeration(requirementTreeGrid);
                    requirementTreeGrid.refreshFields();
                    requirementTreeGrid.redraw();
                    SC.logInfo("tree updated");
                }
            });
        }
    });
requirementTreeGrid.addFolderDropHandler(new FolderDropHandler() {
                   //same code like above
            });
        }
    });

Since DeferredCommand is deprecated I also tried it with Scheduler.scheduleDeferred() but sadly this didn't work out either.

My numeration function:

public void addTreeNumeration(TreeGrid treeGrid) {
    this.levels = new Integer[numberOfLevels];
    for (int i=0; i<=numberOfLevels-1;i++){ //fill array with 1
        levels[i] = 1;
    }

    TreeNode rootNode = treeGrid.getTree().getRoot(); // root element of tree
    int levelIndex = 0;

    calculateRequirementTreeNumeration(treeGrid, treeGrid.getTree()
            .getChildren(rootNode), levelIndex, levels);
}

private void calculateRequirementTreeNumeration(TreeGrid treeGrid,
        TreeNode[] lvlNodes, int levelIndex, Integer[] levels) {
    levels[levelIndex]=1;
    for (TreeNode lvlNode : lvlNodes) {
        String numerationLabel = "";
        for (int i = 0; i <= levelIndex; i++) {
            numerationLabel = numerationLabel + levels[i] + ".";
        }
        SC.logInfo("->Req " + numerationLabel);
        lvlNode.setAttribute("requirementListing", numerationLabel);
        // weitere ebene?
        if (treeGrid.getTree().hasChildren(lvlNode)) {
            SC.logInfo(numerationLabel + " -> new level");
            if (levelIndex + 1 < numberOfLevels) { // nur "numberOfLevels" ebenen werden berechnet.
                calculateRequirementTreeNumeration(treeGrid, treeGrid
                        .getTree().getChildren(lvlNode), levelIndex + 1,
                        levels);
            } else {
                deleteRequirementTreeNumeration(treeGrid, treeGrid
                        .getTree().getChildren(lvlNode), levelIndex + 1);
            }
        }
        levels[levelIndex]++;
    }
}

I've also debugged the problem with the client developer console, and it seems to me that the problem is that the numeration is done after the drop but before the RestDataSource sent a response. It looks like the node i just moved is gone, until the DS sends a response. (and therefore the requirementListing field is not updated)

JavaScriptDebug:

12:35:35.724:MUP5:INFO:Log:Drop complete
12:35:35.736:INFO:Log:->Req 1.
12:35:35.736:INFO:Log:1. -> new level
12:35:35.736:INFO:Log:->Req 1.1.
12:35:35.736:INFO:Log:->Req 1.2.
12:35:35.736:INFO:Log:->Req 2.
12:35:35.736:INFO:Log:2. -> new level
12:35:35.737:INFO:Log:->Req 2.1.
12:35:35.737:INFO:Log:->Req 2.2.
12:35:35.737:INFO:Log:->Req 2.3.
12:35:35.737:INFO:Log:->Req 3.
12:35:35.738:INFO:Log:3. -> new level
12:35:35.738:INFO:Log:->Req 3.1.
12:35:35.742:INFO:Log:->Req 3.2.
12:35:35.744:INFO:Log:->Req 3.3.
12:35:35.744:INFO:Log:3.3. new level
12:35:35.744:INFO:Log:->Req 3.3.1.
12:35:35.745:INFO:Log:->Req 3.3.2.
........
12:35:35.756:DEBUG:TreeGrid:isc_TreeGrid_0:delaying adjustOverflow: childClear
12:35:35.866:INFO:Log:tree updated
12:35:35.878:XRP8:INFO:ResultTree:isc_ResultTree_0 (created by:  isc_TreeGrid_0):Updating cache: operationType 'update', 1 rows update data:
[
{id: 32,
parentId: 40,
requirement: "g",
typ: undef,
cluster: undef}
]
12:35:35.878:XRP8:DEBUG:ResultTree:isc_ResultTree_0 (created by:  isc_TreeGrid_0):updated cache: 0 row(s) added, 1 row(s) updated, 0 row(s) removed.

Maybe someone experienced a similar problem? I'm really not sure how to solve this problem.

My Version of SmartGWT: 4.1d /SmartClient v9.1d_2013-08-11/LGPL (built 2013-08-11)

Community
  • 1
  • 1
thenet
  • 23
  • 6
  • It seems you have to re-calculate `"requirementListing"` after every data source operation caused by add/edit/delete/drag drop/etc. It might be much easier if you can include a field in the result set (which probably is fetched after every operation) at the server side itself, that has the updated values. For example, Oracle hierarchical queries should provide what you need. Check "LEVEL" and "Function Demo" in http://psoug.org/reference/connectby.html. – Sithsu Aug 25 '13 at 16:08
  • Thank you for your comment! i was hoping for a magic handler that i've been missing. But the serverside approach is probably the way to go in that case. – thenet Aug 28 '13 at 13:02

1 Answers1

0

I don't know about treegrid but i have a simple tree for the menu and i update the nodes by setting a new array with the parent of the nodes set as one integer (converted to string) and the nodes get updated by calling the linknodes(arrayOfNodes) method...

softwareplay
  • 1,379
  • 4
  • 28
  • 64