Announcement

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

    Programmatically opening TreeGrid

    I want to programmatically open entries in my TreeGrid.

    I have tried the following:
    - setSelectedPaths(). No matter what string I pass in, it says "Unable to parse", even when that string was copy-and-pasted from an earlier call to getSelectedPaths().
    - setSelectedState(). That works if the record is already open, otherwise it does nothing.
    - setOpenedPaths(). That fails the same way that setSelectedPaths() fails.

    I have tried these three things with load-on-demand, and with loading all data at once. I did the latter by changing the DataSource so it returns all data at once. I have tried these things in a DataArrivedHandler, and in the execute() method of the DSCallback that I passed to TreeGrid.fetchData(). I have tried 2.4 and the latest nightly. All of this runs on FireFox in GWT's devmode.

    I kind of don't know what else to do. Any help? Thanks!

    EDIT: I thought it might help to post my data source:
    Code:
    <DataSource ID="browseNodes" serverConstructor="com.mycompany.server.BrowseNodesDataSource">
        <fields>
            <field name="id" type="integer" primaryKey="true" hidden="true"
                required="true"/>
            <field name="parentId" type="integer" foreignKey="browseNodes.id" hidden="true"
                required="true" rootValue="0"/>
            <field name="name" type="text" required="true"/>
        </fields>
    </DataSource>
    EDIT: More info:
    This is how the tree is set up:
    Code:
    m_tree = new TreeGrid();
    // m_tree.setAutoFetchData(true);
    m_tree.setDataSource(DataSource.get("browseNodes"));
    
    m_tree.addNodeClickHandler(new NodeClickHandler() {
        public void onNodeClick(final NodeClickEvent event) {
            final String selectedState = m_tree.getOpenState();    // This is where I copied and pasted from.
        }
    });
    
    m_tree.addDataArrivedHandler(new DataArrivedHandler() {
        public void onDataArrived(final DataArrivedEvent event) {
            m_tree.setOpenState("[\\r    \"/-330\", \\r    \"/\"\\r]");    // in other words: ["/-300", "/"]
        }
    });
    
    m_tree.fetchData();
    Last edited by dirkg; 24 Mar 2011, 16:51.

    #2
    Hi Dirk
    Sorry this is being tricky for you.

    Basically your options are

    - to call 'setOpenState()' and pass in a string like that received from a 'getOpenState()' call. This is most commonly used when you want to save out the state that a user has currently got a treeGrid in - for example as view-preferences to be applied when the user revisits the application in the future.
    This string is a serialized array of strings in Javascript. Typically you would be saving it from the getOpenState call so wouldn't need to write it out in your code directly but if you do, you should not need to include any of the whitespace (so no need for the \\r entries) and you should be able to simply return a quoted array of strings - so something like
    Code:
    "[\"/-300\", \"/\"]";
    Essentially you're escaping the double-quote character so the whole string can be evaluated in JavaScript and will get back just ["/-300","/"]

    - to call 'openFolder()' on the tree of data directly - so m_tree.getData().openFolder(...) and pass in an actual node from the tree (You could find it with find or findById)

    - to set an 'openProperty' on your Tree of data - you'd do this via TreeGrid.setDataProperties(...) passing in a tree with the openProperty specified and having that attribute be set on your actual data so it loads open if appropriate.

    If you still can't get it working let us know - probably best to post a simple standalone test case we can run and we'll be able to tweak it and get it working for you.

    Comment


      #3
      Thank you for your help!

      The openFolder() approach works, even though it's pretty complicated. I have to find the path to the node I want to select myself, and then open the nodes on the path one by one, each time with an asynchronous callback. This is the critical portion of the code:
      Code:
      m_tree.setAutoFetchData(false);
          // it doesn't work when this is true
      
      String[] ids = {"42", "-1337", "666", "80085"};
          // just an example, any array of node ids works, as long as ids[n] is a parent of ids[n + 1]
      
      m_tree.fetchData(new Criteria(), new DSCallback() {
          public void execute(
              final DSResponse response,
              final Object rawData,
              final DSRequest request)
          {
              final Tree data = m_tree.getData();
              TreeNode node = null;
              int i = ids.length;
              while(i > 0 && node == null) {
                  i -= 1;
                  node = data.findById(ids[i]);
              }
      
              if(node != null) {
                  if(i == ids.length - 1)
                      m_tree.setSelectedState("[{id:" + ids[i] + "}]");
                  else
                      data.openFolder(node);
              }
          }
      });
      I have to admit, I don't 100% understand why this works. Why does this handler get called the second and third time? Why does this only work when autofetch is off? Why does the tree still fetch correctly when I click around in the UI, even though autofetch is off?

      As long as I'm not doing something undocumented that will get broken in the next version, I ask these questions merely out of curiosity, since this solution does everything I wanted to do :-)

      Thank you!

      EDIT: There is one other thing I changed that might have had something to do with it. I changed the type of id and parent id in the datasource from integer to text. I did this for unrelated reasons, so I didn't check if that's the magic that makes it work.
      Last edited by dirkg; 29 Mar 2011, 17:09.

      Comment


        #4
        autoFetchData doesn't refer to the automatic fetches SmartGWT widgets issue when a user is interacting with them; it just refers to an automatic initial fetch of data when the widget is first drawn.

        Comment

        Working...
        X