Announcement

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

    3.1 TreeGrid.setSort (getSort ()) does not sort

    3.1 TreeGrid.setSort (getSort ()) does not sort

    To the best of my knowledge, this worked with 3.0.
    No longer works with 3.1d from 2012-09-23.

    With 3.1:
    1. setSort (getSort ()) does not wort
    2. setSort (new SortSpecifier[] {...}) does sort
    3. setSort (deep clone of getSort ()) does sort

    Version
    GWT version: 2.3.0
    SmartGWT version: 3.1d
    SmartGWT buildDate: Sun Sep 23 00:02:00 PDT 2012
    SmartGWT major-minor-patch: 3-1d-0
    SmartGWT SC: SNAPSHOT_v8.3d_2012-09-23
    Browser: FireFox 6.0.2

    Dev console
    Code:
    09:50:01.503:INFO:Log:initialized
    09:50:01.530:WARN:Log:NOTE: Firebug is enabled. Firebug greatly slows the performance of applications that make heavy use of JavaScript. Isomorphic highly recommends Firebug for troubleshooting, but Firebug and other development tools should be disabled when assessing the real-world performance of SmartClient applications.
    09:50:08.071:INFO:Log:isc.Page is loaded
    Sample code:
    Code:
    import com.smartgwt.client.util.SC;
    import com.smartgwt.client.widgets.tree.TreeGrid;
    import com.smartgwt.client.widgets.tree.Tree;
    import com.smartgwt.client.widgets.tree.TreeGridField;
    import com.smartgwt.client.widgets.tree.TreeNode;
    import com.smartgwt.client.widgets.IButton;
    import com.smartgwt.client.widgets.events.ClickHandler;
    import com.smartgwt.client.widgets.events.ClickEvent;
    import com.smartgwt.client.widgets.layout.VLayout;
    import com.smartgwt.client.types.TreeModelType;
    import com.smartgwt.client.types.SortDirection;
    import com.smartgwt.client.data.SortSpecifier;
    import com.smartgwt.client.Version;
    
    import com.google.gwt.core.client.EntryPoint;
    import com.google.gwt.core.client.GWT;
    
    public class TestTreeGridSort implements EntryPoint {
    
      // my attributes
      int nextNodeId = 1;
    
      /**
       * The EntryPoint interface
       */
      public void onModuleLoad () {
    
        // test
        SC.showConsole ();
        GWT.log ("GWT version: " + GWT.getVersion ());
        GWT.log ("SmartGWT version: " + Version.getVersion ());
        GWT.log ("SmartGWT buildDate: " + Version.getBuildDate ());
        GWT.log ("SmartGWT major-minor-patch: " + Version.getMajor () + "-" + Version.getMinor () + "-" + Version.getPatch ());
        GWT.log ("SmartGWT SC: " + Version.getSCVersionNumber ());
    
        // configure Tree
        final Tree tree = new Tree ();
        tree.setModelType (TreeModelType.PARENT);
        tree.setNameProperty ("name");
        tree.setIdField ("nodeId");
        tree.setParentIdField ("parentNodeId");
        tree.setShowRoot (true);
    
        // configure TreeGrid
        final TreeGridField nameField = new TreeGridField ("name", "Name", 200);
        final TreeGrid treeGrid = new TreeGrid ();
        treeGrid.setWidth (300);
        treeGrid.setHeight (200);
        treeGrid.setSeparateFolders (true);
        treeGrid.setSortFoldersBeforeLeaves (true);
        treeGrid.setSortField ("name");
        treeGrid.setSortDirection (SortDirection.ASCENDING);
        treeGrid.setFields (nameField);
        treeGrid.setData (tree);
    
        // add a few nodes, folders
        addTreeNode (tree, true, "A");
        addTreeNode (tree, false, "B");
        addTreeNode (tree, true, "C");
        addTreeNode (tree, false, "D");
        addTreeNode (tree, true, "E");
        addTreeNode (tree, false, "F");
        addTreeNode (tree, true, "G");
        
        // call setSort (getSort ()). this worked with 3.0
        final IButton setSortGetSortButton = new IButton ();
        setSortGetSortButton.setAutoFit (true);
        setSortGetSortButton.setTitle ("setSort (getSort ())");
        setSortGetSortButton.addClickHandler (new ClickHandler () {
          public void onClick (final ClickEvent event) {
            final SortSpecifier [] sortSpecifierArray = treeGrid.getSort ();
            GWT.log ("sortSpecifierArray [0]: " + sortSpecifierArray[0].getField () + " / " + sortSpecifierArray[0].getSortDirection ().getValue ());
            treeGrid.setSort (sortSpecifierArray);
          }
        });
        
        // call setSort (new SortSpecifier[] ()).
        final IButton setSortWithSortSpecifierButton = new IButton ();
        setSortWithSortSpecifierButton.setAutoFit (true);
        setSortWithSortSpecifierButton.setTitle ("setSort (SortSpecifier[])");
        setSortWithSortSpecifierButton.addClickHandler (new ClickHandler () {
          public void onClick (final ClickEvent event) {
            final SortSpecifier [] sortSpecifierArray = new SortSpecifier [] {
              new SortSpecifier ("name", SortDirection.ASCENDING)
            };
            GWT.log ("sortSpecifierArray [0]: " + sortSpecifierArray[0].getField () + " / " + sortSpecifierArray[0].getSortDirection ().getValue ());
            treeGrid.setSort (sortSpecifierArray);
            
            // treeGrid.setSort (new SortSpecifier [] { new SortSpecifier ("name", SortDirection.ASCENDING) });
          }
        });
        
        // call setSort (rebuild SortSpecifier[] from getSort ())
        final IButton resortButton = new IButton ();
        resortButton.setAutoFit (true);
        resortButton.setTitle ("resort ()");
        resortButton.addClickHandler (new ClickHandler () {
          public void onClick (final ClickEvent event) {
            resort (treeGrid);
          }
        });
        
        // layout
        final VLayout layout = new VLayout ();
        layout.addMember (treeGrid);
        layout.addMember (setSortGetSortButton);
        layout.addMember (setSortWithSortSpecifierButton);
        layout.addMember (resortButton);
        layout.show ();
      }
    
      /**
       * Helper: uniformely adds the given TreeNode
       * @param tree
       * @param isFolder
       * @param name
       */
      private void addTreeNode (
        final Tree tree,
        final boolean isFolder,
        final String name) {
    
        nextNodeId ++;
    
        final TreeNode treeNode = new TreeNode ();
        treeNode.setAttribute ("nodeId", nextNodeId);
        treeNode.setAttribute ("parentNodeId", 1); // hard-coded
        treeNode.setAttribute ("name", name);
        treeNode.setIsFolder (isFolder);
        final TreeNode rootTreeNode = tree.getRoot ();
        tree.add (treeNode, rootTreeNode);
      }
      
      /**
       * Resorts this TreeGrid based on the current sorting specifiers
       */
      public static void resort (final TreeGrid treeGrid) {
    
        // get the current config
        final SortSpecifier[] sortSpecifierArray = treeGrid.getSort ();
        if (sortSpecifierArray == null) {
          return;
        }
    
        // rebuild the SortSpecifier array
        final SortSpecifier[] sortSpecifierArray2 = new SortSpecifier[sortSpecifierArray.length];
        int index = -1;
        for (final SortSpecifier sortSpecifier : sortSpecifierArray) {
          index ++;
          sortSpecifierArray2 [index] = new SortSpecifier (sortSpecifier.getField (), sortSpecifier.getSortDirection ());
        }
        
        // sort with that
        treeGrid.setSort (sortSpecifierArray2);
      }
    }
    Attached Files

    #2
    That should have been a no-op, and now it is - calling resort() is now the correct (and simpler) way to explicitly ask for data to be sorted again to reflect changes.

    Comment


      #3
      I changed my example to also call treeGrid.resort (), but treeGrid.resort () does not resort.
      See attached screenshot for an example.

      The following code does resort, by it is my own resort which clones the SortSpecifier array from getSort () and passes it into setSort ():
      Code:
        public static void resort (final TreeGrid treeGrid) {
      
          // get the current config
          final SortSpecifier[] sortSpecifierArray = treeGrid.getSort ();
          if (sortSpecifierArray == null) {
            return;
          }
      
          // rebuild the SortSpecifier array
          final SortSpecifier[] sortSpecifierArray2 = new SortSpecifier[sortSpecifierArray.length];
          int index = -1;
          for (final SortSpecifier sortSpecifier : sortSpecifierArray) {
            index ++;
            sortSpecifierArray2 [index] = new SortSpecifier (sortSpecifier.getField (), sortSpecifier.getSortDirection ());
          }
          
          // sort with that
          treeGrid.setSort (sortSpecifierArray2);
        }
      Full example:
      Code:
      import com.smartgwt.client.util.SC;
      import com.smartgwt.client.widgets.tree.TreeGrid;
      import com.smartgwt.client.widgets.tree.Tree;
      import com.smartgwt.client.widgets.tree.TreeGridField;
      import com.smartgwt.client.widgets.tree.TreeNode;
      import com.smartgwt.client.widgets.IButton;
      import com.smartgwt.client.widgets.events.ClickHandler;
      import com.smartgwt.client.widgets.events.ClickEvent;
      import com.smartgwt.client.widgets.layout.VLayout;
      import com.smartgwt.client.types.TreeModelType;
      import com.smartgwt.client.types.SortDirection;
      import com.smartgwt.client.data.SortSpecifier;
      import com.smartgwt.client.Version;
      
      import com.google.gwt.core.client.EntryPoint;
      import com.google.gwt.core.client.GWT;
      
      public class TestTreeGridSort implements EntryPoint {
      
        // my attributes
        int nextNodeId = 1;
      
        /**
         * The EntryPoint interface
         */
        public void onModuleLoad () {
      
          // test
          SC.showConsole ();
          GWT.log ("GWT version: " + GWT.getVersion ());
          GWT.log ("SmartGWT version: " + Version.getVersion ());
          GWT.log ("SmartGWT buildDate: " + Version.getBuildDate ());
          GWT.log ("SmartGWT major-minor-patch: " + Version.getMajor () + "-" + Version.getMinor () + "-" + Version.getPatch ());
          GWT.log ("SmartGWT SC: " + Version.getSCVersionNumber ());
      
          // configure Tree
          final Tree tree = new Tree ();
          tree.setModelType (TreeModelType.PARENT);
          tree.setNameProperty ("name");
          tree.setIdField ("nodeId");
          tree.setParentIdField ("parentNodeId");
          tree.setShowRoot (true);
      
          // configure TreeGrid
          final TreeGridField nameField = new TreeGridField ("name", "Name", 200);
          final TreeGrid treeGrid = new TreeGrid ();
          treeGrid.setWidth (300);
          treeGrid.setHeight (200);
          treeGrid.setSeparateFolders (true);
          treeGrid.setSortFoldersBeforeLeaves (true);
          treeGrid.setSortField ("name");
          treeGrid.setSortDirection (SortDirection.ASCENDING);
          treeGrid.setFields (nameField);
          treeGrid.setData (tree);
      
          // add a few nodes, folders
          addTreeNode (tree, true, "A");
          addTreeNode (tree, false, "B");
          addTreeNode (tree, true, "C");
          addTreeNode (tree, false, "D");
          addTreeNode (tree, true, "E");
          addTreeNode (tree, false, "F");
          addTreeNode (tree, true, "G");
          
          // call setSort (getSort ()). this worked with 3.0
          final IButton setSortGetSortButton = new IButton ();
          setSortGetSortButton.setAutoFit (true);
          setSortGetSortButton.setTitle ("setSort (getSort ())");
          setSortGetSortButton.addClickHandler (new ClickHandler () {
            public void onClick (final ClickEvent event) {
              final SortSpecifier [] sortSpecifierArray = treeGrid.getSort ();
              GWT.log ("sortSpecifierArray [0]: " + sortSpecifierArray[0].getField () + " / " + sortSpecifierArray[0].getSortDirection ().getValue ());
              treeGrid.setSort (sortSpecifierArray);
            }
          });
          
          // call setSort (new SortSpecifier[] ()).
          final IButton setSortWithSortSpecifierButton = new IButton ();
          setSortWithSortSpecifierButton.setAutoFit (true);
          setSortWithSortSpecifierButton.setTitle ("setSort (SortSpecifier[])");
          setSortWithSortSpecifierButton.addClickHandler (new ClickHandler () {
            public void onClick (final ClickEvent event) {
              final SortSpecifier [] sortSpecifierArray = new SortSpecifier [] {
                new SortSpecifier ("name", SortDirection.ASCENDING)
              };
              GWT.log ("sortSpecifierArray [0]: " + sortSpecifierArray[0].getField () + " / " + sortSpecifierArray[0].getSortDirection ().getValue ());
              treeGrid.setSort (sortSpecifierArray);
              
              // treeGrid.setSort (new SortSpecifier [] { new SortSpecifier ("name", SortDirection.ASCENDING) });
            }
          });
          
          // call setSort (rebuild SortSpecifier[] from getSort ())
          final IButton resortButton = new IButton ();
          resortButton.setAutoFit (true);
          resortButton.setTitle ("treeGrid.resort ()");
          resortButton.addClickHandler (new ClickHandler () {
            public void onClick (final ClickEvent event) {
              treeGrid.resort ();
            }
          });
          
          // call setSort (rebuild SortSpecifier[] from getSort ())
          final IButton resort2Button = new IButton ();
          resort2Button.setAutoFit (true);
          resort2Button.setTitle ("my resort ()");
          resort2Button.addClickHandler (new ClickHandler () {
            public void onClick (final ClickEvent event) {
              resort (treeGrid);
            }
          });
          
          // layout
          final VLayout layout = new VLayout ();
          layout.addMember (treeGrid);
          layout.addMember (setSortGetSortButton);
          layout.addMember (setSortWithSortSpecifierButton);
          layout.addMember (resortButton);
          layout.addMember (resort2Button);
          layout.show ();
        }
      
        /**
         * Helper: uniformely adds the given TreeNode
         * @param tree
         * @param isFolder
         * @param name
         */
        private void addTreeNode (
          final Tree tree,
          final boolean isFolder,
          final String name) {
      
          nextNodeId ++;
      
          final TreeNode treeNode = new TreeNode ();
          treeNode.setAttribute ("nodeId", nextNodeId);
          treeNode.setAttribute ("parentNodeId", 1); // hard-coded
          treeNode.setAttribute ("name", name);
          treeNode.setIsFolder (isFolder);
          final TreeNode rootTreeNode = tree.getRoot ();
          tree.add (treeNode, rootTreeNode);
        }
        
        /**
         * Resorts this TreeGrid based on the current sorting specifiers
         */
        public static void resort (final TreeGrid treeGrid) {
      
          // get the current config
          final SortSpecifier[] sortSpecifierArray = treeGrid.getSort ();
          if (sortSpecifierArray == null) {
            return;
          }
      
          // rebuild the SortSpecifier array
          final SortSpecifier[] sortSpecifierArray2 = new SortSpecifier[sortSpecifierArray.length];
          int index = -1;
          for (final SortSpecifier sortSpecifier : sortSpecifierArray) {
            index ++;
            sortSpecifierArray2 [index] = new SortSpecifier (sortSpecifier.getField (), sortSpecifier.getSortDirection ());
          }
          
          // sort with that
          treeGrid.setSort (sortSpecifierArray2);
        }
      }
      When you say that setSort (getSort ()) is a no-op, can you expand?
      I am asking because the documentation for setSort () says that "This method sorts the grid on one or more fields" which seems to me to be an active statement, meaning that setSort () is supposed to sort when you call it.

      Also, in this forum I understood that, in order to sort, I should use setSort () and not sort () to sort -- which should I be using?
      http://forums.smartclient.com/showth...hlight=setsort
      Attached Files

      Comment


        #4
        Using setSort() but setting the exact same sort direction is a no-op, use resort() to explicitly ask for sorting to occur using the same direction that is currently configured.

        setSort() allows more sophisticated sort options to be passed than sort because it takes an array of SortSpecifiers.

        Comment


          #5
          Good, thanks.
          BTW I am calling resort () and it is not resorting.
          I posted the full example and screenshot in my previous post...

          Comment


            #6
            resort() should now be behaving as expected in the 3.1d branch

            Regards
            Isomorphic Software

            Comment


              #7
              Originally posted by Isomorphic View Post
              Using setSort() but setting the exact same sort direction is a no-op, use resort() to explicitly ask for sorting to occur using the same direction that is currently configured.

              setSort() allows more sophisticated sort options to be passed than sort because it takes an array of SortSpecifiers.
              Is this true even if the Tree has changed across setSort () invocations? For example:
              1. Add records
              2. call setSort ()
              3. Add more records
              4. call setSort (getSort ())

              I would expect #4 to not be a no-op and indeed resort the tree because the tree has changed since the previous setSort () invocation. So is this something we need to handle in our client code by detecting the situation, and calling resort () instead of setSort ()?

              Comment


                #8
                Originally posted by Isomorphic View Post
                resort() should now be behaving as expected in the 3.1d branch

                Regards
                Isomorphic Software
                Using SmartClient Version: v8.3d_2012-10-22/LGPL Development Only (built 2012-10-22)

                To test this fix, I commented-out the setSortField ("name") and setSortDirection (SortDirection.ASCENDING) calls.
                When I did this, the Tree started displaying the "/" record as the first record.
                See the treeGridWithSlash.png attachment for an example.
                Note that the "/" record disappears after I call setSort ("name").
                I would guess this is not intended behavior.
                Let me know if you want me to open a bug on google code for this.

                However, when testing this with the setSortField ("name") and setSortDirection (SortDirection.ASCENDING) as in the code from the initial post, I noticed that the tree is initially sorted.
                So I tested by adding some records AFTER the tree is initially shown, and the tree seems to place the newly added records in the right order (not at the end of the tree).
                The behavior is as if the tree automatically calls resort () after I call addData ().
                It seems that this makes it unnecessary for me to call resort () which, before this change, I had to do after adding a record to the tree in order to make it pop-up in the right place.
                BTW, when I call resort () anyway, the tree remains sorted properly.
                So I guess I cannot validate that this problem is fixed, but I can validate that the problem goes away entirely because I do not need to call resort () any more.

                It seems to me that this change is similar to the way that Windows' File Explorer changed adding files to a view.
                Windows XP: the new file is displayed at the end of the list in File Explorer
                Windows 7: the new file is displayed in the sorted location in File Explorer, as if you created a new file, and then resorted the view
                Attached Files

                Comment


                  #9
                  The "/" appears because you have setShowRoot(true). This is expected, and there's no mechanism in the code that we can see that would cause sort settings to be involved. Please double-check the result that changes to sorting settings actually caused this effect.

                  Comment


                    #10
                    Confirmed using:
                    v8.3d_2012-10-22/LGPL Development Only (built 2012-10-22)
                    FireFox 6.0.2

                    Here is a smaller test case:
                    Code:
                    import com.smartgwt.client.data.SortSpecifier;
                    import com.smartgwt.client.types.TreeModelType;
                    import com.smartgwt.client.types.SortDirection;
                    import com.smartgwt.client.widgets.tree.Tree;
                    import com.smartgwt.client.widgets.tree.TreeGridField;
                    import com.smartgwt.client.widgets.tree.TreeGrid;
                    import com.smartgwt.client.widgets.tree.TreeNode;
                    import com.smartgwt.client.widgets.IButton;
                    import com.smartgwt.client.widgets.layout.VLayout;
                    import com.smartgwt.client.widgets.events.ClickHandler;
                    import com.smartgwt.client.widgets.events.ClickEvent;
                    
                    import com.google.gwt.core.client.EntryPoint;
                    
                    public class TreeSetShowRoot implements EntryPoint {
                    
                      // my attributes
                      int nextNodeId = 1;
                    
                      /**
                       * The EntryPoint interface
                       */
                      public void onModuleLoad () {
                    
                        // configure Tree
                        // setShowRoot (true) tells the tree to show the "/" starting path
                        final Tree tree = new Tree ();
                        tree.setModelType (TreeModelType.PARENT);
                        tree.setNameProperty ("name");
                        tree.setIdField ("nodeId");
                        tree.setParentIdField ("parentNodeId");
                        tree.setShowRoot (true);
                    
                        // configure TreeGrid
                        // with smartgwt 3.1d-2012-10-22 it seems that when setSortField () and setSortDirection () are initially
                        // commented out, the tree shows the "/" root as expected, but after invoking setSort (), it disappears
                        final TreeGridField nameField = new TreeGridField ("name", "Name", 200);
                        final TreeGrid treeGrid = new TreeGrid ();
                        treeGrid.setWidth (300);
                        treeGrid.setHeight (300);
                        treeGrid.setSeparateFolders (true);
                        treeGrid.setSortFoldersBeforeLeaves (true);
                        // treeGrid.setSortField ("name");
                        // treeGrid.setSortDirection (SortDirection.ASCENDING);
                        treeGrid.setFields (nameField);
                        treeGrid.setCanReorderRecords (true);
                        treeGrid.setData (tree);
                    
                        // add a few nodes, folders and nodes
                        addTreeNode (tree, true, "G");
                        addTreeNode (tree, false, "F");
                        addTreeNode (tree, true, "E");
                        addTreeNode (tree, false, "D");
                        addTreeNode (tree, true, "C");
                        addTreeNode (tree, false, "B");
                        addTreeNode (tree, true, "A");
                    
                        // call setSort ("name");
                        final IButton setSortButton = new IButton ();
                        setSortButton.setAutoFit (true);
                        setSortButton.setTitle ("setSort (\"name\")");
                        setSortButton.addClickHandler (new ClickHandler () {
                          public void onClick (final ClickEvent event) {
                            final SortSpecifier [] sortSpecifierArray = new SortSpecifier [] {
                              new SortSpecifier ("name", SortDirection.ASCENDING)
                            };
                            treeGrid.setSort (sortSpecifierArray);
                          }
                        });
                    
                        // layout
                        final VLayout layout = new VLayout ();
                        layout.addMember (treeGrid);
                        layout.addMember (setSortButton);
                        layout.show ();
                      }
                    
                      /**
                       * Helper: uniformely adds the given TreeNode
                       * @param tree
                       * @param isFolder
                       * @param name
                       */
                      private void addTreeNode (
                        final Tree tree,
                        final boolean isFolder,
                        final String name) {
                    
                        nextNodeId ++;
                    
                        final TreeNode treeNode = new TreeNode ();
                        treeNode.setAttribute ("nodeId", nextNodeId);
                        treeNode.setAttribute ("parentNodeId", 1); // hard-coded
                        treeNode.setAttribute ("name", name);
                        treeNode.setIsFolder (isFolder);
                        final TreeNode rootTreeNode = tree.getRoot ();
                        tree.add (treeNode, rootTreeNode);
                      }
                    }
                    Dev Console:
                    Code:
                    11:08:22.766:INFO:Log:initialized
                    11:08:22.796:WARN:Log:NOTE: Firebug is enabled. Firebug greatly slows the performance of applications that make heavy use of JavaScript. Isomorphic highly recommends Firebug for troubleshooting, but Firebug and other development tools should be disabled when assessing the real-world performance of SmartClient applications.
                    11:08:27.924:INFO:Log:isc.Page is loaded
                    And attached is a screen shot showing:
                    1. When setSortField () and setSortDirection () and commented-out, the "/" root does show
                    2. After #1, if the tree is sorted by either clicking the setSort () button or clicking the columns, the "/" root goes away
                    2. When setSortField () and setSortDirection () and commented-in, the "/" root does NOT show
                    Attached Files

                    Comment


                      #11
                      Ah - the problem is that you're calling setShowRoot(true) on the Tree data object, but you need to actually call setShowRoot(true) on the TreeGrid component.

                      The property at the component level overrides the property specified directly on the data class.

                      We'll look into whether we can either make this clearer or change the implementation to make it more intuitive but this should get things working for you.

                      Regards
                      Isomorphic Software

                      Comment


                        #12
                        I don't know why, but I didn't even think of looking there.
                        Thanks!

                        Comment

                        Working...
                        X