Announcement

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

    Tree with all nodes open

    I need to make a menu which looks like a TreeGrid, but I need to load all the data on the page load (from an xml data source) and I need all of the nodes to be open and they should not be collapsible. It would be best not to even have any icons next to the nodes.


    Is this possible with TreeGrid control?

    #2
    Sure. This example shows loading a Tree from XML. Starting from this:

    1) call treeGrid.data.openAll() from the callback of fetchData() to open the whole tree

    2) override treeGrid.getIcon() to return nothing for icons

    3) overide treeGrid.mouseDown and treeGrid.click to do nothing

    Comment


      #3
      OK I've pretty much got it working, but I am having no luck in attaching a callback to the dsRequest of the Datasource.
      Also, if I have a field called id in the fields array, it displays the ID as the name even if it is hidden.




      Code:
      isc.DataSource.create({
              ID:"adminMenuDS",
              showPrompt: true,
              dataFormat: "xml",
              dataURL:"/browse/isotest/AdminTree.ashx",
              recordXPath : "/menuItems/menuItem",
              fields:[
                  {type:"text", length:128, required:true, title: "label", name:"label"},
                  {type:"text", name:"path", hidden: true},
                  {type:"integer", name:"dynasty", hidden: true},
      //            {type:"integer", rootValue:"0", name:"parentid"},
      //            {type:"integer", title: "id", name:"id", hidden: true},
                  {childrenProperty:true, name:"childmenuitems"}
              ]
                  ,
               transformRequest: function (dsRequest) {
                
                      var params = {callback: "treeFetchCallback(rpcResponse)"};
                      return isc.addProperties({}, dsRequest.data, params);
                
              }
          });
      
      
              
          isc.TreeGrid.create({
      	ID:"adminMenuTree",
              dataSource:"adminMenuDS",
              height: "100%",
              showHeader:false,
              autoFetchData: true,
              leaveScrollbarGap:false,
              animateFolders:true,
      	canAcceptDroppedRecords:false,
              canReparentNodes:false,
              selectionType:"single",
              animateRowsMaxTime:750,
              getIcon: function (parms){}
          });
      
         function treeFetchCallback(parms){
              //adminMenuTree.data.openAll();
              alert('HELLO!!!');
          }

      Also, Here's some sample XML data:

      Code:
      <menuItems>
      −
      	<menuItem>
      <label>Division</label>
      <id>1</id>
      <parentid>0</parentid>
      <path>~/Admin/Default.aspx?menu=Division</path>
      <dynasty>1</dynasty>
      <sort>10</sort>
      −
      	<childmenuitems>
      −
      	<menuItem>
      <label>Settings</label>
      <id>6</id>
      <parentid>1</parentid>
      <path>~/Admin/DivisionSettings</path>
      <dynasty>1</dynasty>
      <sort>60</sort>
      <childmenuitems/>
      </menuItem>
      −
      	<menuItem>
      <label>Reports</label>
      <id>7</id>
      <parentid>1</parentid>
      <path>~/Admin/ReportList.aspx</path>
      <dynasty>1</dynasty>
      <sort>70</sort>
      <childmenuitems/>
      </menuItem>
      −
      	<menuItem>
      <label>Email List</label>
      <id>8</id>
      <parentid>1</parentid>
      <path>~/Admin/EmailList.aspx</path>
      <dynasty>1</dynasty>
      <sort>80</sort>
      <childmenuitems/>
      </menuItem>
      −
      	<menuItem>
      <label>External Links</label>
      <id>9</id>
      <parentid>1</parentid>
      <path>~/Admin/ExternalLinks.aspx</path>
      <dynasty>1</dynasty>
      <sort>90</sort>
      <childmenuitems/>
      </menuItem>
      −
      	<menuItem>
      <label>Thumbnailer</label>
      <id>10</id>
      <parentid>1</parentid>
      <path>~/Admin/thumbnail.aspx</path>
      <dynasty>1</dynasty>
      <sort>100</sort>
      <childmenuitems/>
      </menuItem>
      </childmenuitems>
      </menuItem>
      −
      	<menuItem>
      <label>Users</label>
      <id>2</id>
      <parentid>0</parentid>
      <path>~/Admin/Default.aspx?menu=Users</path>
      <dynasty>1</dynasty>
      <sort>20</sort>
      −
      	<childmenuitems>
      −
      	<menuItem>
      <label>Registrations</label>
      <id>11</id>
      <parentid>2</parentid>
      <path>#Registrations</path>
      <dynasty>0</dynasty>
      <sort>110</sort>
      <childmenuitems/>
      </menuItem>
      −
      	<menuItem>
      <label>User List</label>
      <id>12</id>
      <parentid>2</parentid>
      <path>~/Admin/UserList.aspx</path>
      <dynasty>1</dynasty>
      <sort>120</sort>
      <childmenuitems/>
      </menuItem>
      −
      	<menuItem>
      <label>User Groups</label>
      <id>13</id>
      <parentid>2</parentid>
      <path>~/Admin/UsergroupList.aspx</path>
      <dynasty>1</dynasty>
      <sort>130</sort>
      <childmenuitems/>
      </menuItem>
      </childmenuitems>
      </menuItem>
      −
      	<menuItem>
      <label>Shows</label>
      <id>3</id>
      <parentid>0</parentid>
      <path>~/Admin/Default.aspx?menu=Shows</path>
      <dynasty>1</dynasty>
      <sort>30</sort>
      −
      	<childmenuitems>
      −
      	<menuItem>
      <label>Categories</label>
      <id>14</id>
      <parentid>3</parentid>
      <path>~/Admin/CategoryList.aspx</path>
      <dynasty>1</dynasty>
      <sort>140</sort>
      <childmenuitems/>
      </menuItem>
      −
      	<menuItem>
      <label>Show Titles</label>
      <id>15</id>
      <parentid>3</parentid>
      <path>~/Admin/ShowList.aspx</path>
      <dynasty>1</dynasty>
      <sort>150</sort>
      <childmenuitems/>
      </menuItem>
      −
      	<menuItem>
      <label>Incoming Shares</label>
      <id>16</id>
      <parentid>3</parentid>
      <path>~/Admin/ShareList.aspx</path>
      <dynasty>1</dynasty>
      <sort>160</sort>
      <childmenuitems/>
      </menuItem>
      −
      	<menuItem>
      <label>Trash</label>
      <id>17</id>
      <parentid>3</parentid>
      <path>~/Admin/Trash.aspx</path>
      <dynasty>1</dynasty>
      <sort>170</sort>
      <childmenuitems/>
      </menuItem>
      </childmenuitems>
      </menuItem>
      −
      	<menuItem>
      <label>Marketing</label>
      <id>4</id>
      <parentid>0</parentid>
      <path>~/Admin/Default.aspx?menu=Marketing</path>
      <dynasty>1</dynasty>
      <sort>40</sort>
      −
      	<childmenuitems>
      −
      	<menuItem>
      <label>Affiliate News</label>
      <id>18</id>
      <parentid>4</parentid>
      <path>~/Admin/AffiliateNewsList.aspx?showid=0</path>
      <dynasty>1</dynasty>
      <sort>180</sort>
      <childmenuitems/>
      </menuItem>
      </childmenuitems>
      </menuItem>
      </menuItems>

      Comment


        #4
        You just want dsRequest.callback = callback.

        You can explicitly mark the tree field by setting treeField:true - look at the docs for treeField for how it gets chosen by default.

        Comment


          #5
          The callback fires, but it is obviously firing before the tree loads, so the nodes do not open.

          Also, setting treeField: true/false or TreeGridField: true/false does not prevent the integer field from showing up as the name of the node.



          Code:
          isc.DataSource.create({
                  ID:"adminMenuDS",
                  showPrompt: true,
                  dataFormat: "xml",
                  dataURL:"/browse/isotest/AdminTree.ashx",
                  recordXPath : "/menuItems/menuItem",
                  fields:[
                      {type:"text", length:128, TreeGridField:true, required:true, title: "label", name:"label"},
                      {type:"text", name:"path", TreeGridField:false},
                      {type:"integer", name:"dynasty",TreeGridField:false},
                      {type:"integer", rootValue:"0", name:"parentid",TreeGridField:false},
                      {type:"integer", title: "id", name:"id", TreeGridField:false},
                      {childrenProperty:true, name:"childmenuitems"}
                  ]
                      ,
                   transformRequest: function (dsRequest) {
                          dsRequest.callback = treeFetchCallback();
                          return dsRequest;
                  }
              });
          
              isc.TreeGrid.create({
          	    ID:"adminMenuTree",
                  dataSource:"adminMenuDS",
                  height: "100%",
                  showHeader:false,
                  autoFetchData: true,
                  leaveScrollbarGap:false,
                  animateFolders:true,
          	    canAcceptDroppedRecords:false,
                  canReparentNodes:false,
                  selectionType:"single",
                  animateRowsMaxTime:750,
                  getIcon: function (parms){}
              });
              
              adminMenuTree.getIcon() = function(){};
              
              function treeFetchCallback(parms){
                  adminMenuTree.data.openAll();
              }

          Comment


            #6
            Originally posted by Isomorphic
            You just want dsRequest.callback = callback.

            You can explicitly mark the tree field by setting treeField:true - look at the docs for treeField for how it gets chosen by default.
            By the way, whenever I have posted questions in this forum, The answerws given by Isomorphic staff always point me to the documentation as above. If I look up treeField in the Smartclient reference, this is what I get:

            Originally posted by Reference
            treeField

            Methods and Properties referencing group treeField

            TreeGridField.treeField
            TreeGrid.treeFieldTitle
            TreeGrid.showRoot
            TreeGrid.separateFolders
            TreeGrid.displayNodeType
            If I click on TreeGridField.treeField I get:
            Originally posted by Reference
            treeField [IRW] type:Boolean, defaultValue: see below

            The field containing treeField: true will display the Tree. If no field specifies this property, the first field in TreeGrid.fields is assigned to display the Tree.
            This is not occurring. Here is the code I am using:

            Code:
            isc.DataSource.create({
                    ID:"adminMenuDS",
                    showPrompt: true,
                    dataFormat: "xml",
                    dataURL:"/browse/isotest/AdminTree.ashx",
                    recordXPath : "/menuItems/menuItem",
                    fields:[
                        {type:"text", length:128, treeField:true, required:true, title: "label", name:"label"},
                        {type:"text", name:"path"},
                        {type:"integer", name:"dynasty"},
                        {type:"integer", rootValue:"0", name:"parentid"},
                        {type:"integer", title: "id", name:"id"},
                        {childrenProperty:true, name:"childmenuitems"}
                    ]
                        ,
                     transformRequest: function (dsRequest) {
                            dsRequest.callback = treeFetchCallback();
                            return dsRequest;
                    }
                });
            The field being used as the treeField by the Treegrid is "id."


            I don't see how this documentation is descriptive of anything helpful. If I knew how the Tree Grid class was constructed (I suppose I can go through the source, now that it's been open-sourced) it would be quite easy for me to construct exactly what I want. Since the source is fairly complex, I would think that there would be some better explanations in the docs.

            Comment


              #7
              Hi picasso,

              You're actually calling the callback yourself, because of the parens:

              Code:
              dsRequest.callback = treeFetchCallback[b]()[/b];
              You want:

              Code:
              dsRequest.callback = treeFetchCallback;
              We're looking at why treeField isn't behaving as expected. At a glance, the docs are right and the behavior is wrong, but we'll let you know definitively shortly.

              Comment


                #8
                Originally posted by Isomorphic
                Hi picasso,

                You're actually calling the callback yourself, because of the parens:

                Code:
                dsRequest.callback = treeFetchCallback[b]()[/b];
                You want:

                Code:
                dsRequest.callback = treeFetchCallback;
                We're looking at why treeField isn't behaving as expected. At a glance, the docs are right and the behavior is wrong, but we'll let you know definitively shortly.
                LOL, thanks

                Comment


                  #9
                  Still doesn't work (nodes don't open and the field being displayed is the id integer field):

                  Code:
                  isc.DataSource.create({
                          ID:"adminMenuDS",
                          showPrompt: true,
                          dataFormat: "xml",
                          dataURL:"/browse/isotest/AdminTree.ashx",
                          recordXPath : "/menuItems/menuItem",
                          fields:[
                              {type:"text", length:128, treeField:true, required:true, title: "label", name:"label"},
                              {type:"text", name:"path"},
                              {type:"integer", name:"dynasty"},
                              {type:"integer", rootValue:"0", name:"parentid"},
                              {type:"integer", title: "id", name:"id"},
                              {childrenProperty:true, name:"childmenuitems"}
                          ]
                              ,
                           transformRequest: function (dsRequest) {
                                  dsRequest.callback = treeFetchCallback;
                                  return dsRequest;
                          }
                      });
                  
                      isc.TreeGrid.create({
                  	    ID:"adminMenuTree",
                          dataSource:"adminMenuDS",
                          height: "100%",
                          showHeader:false,
                          autoFetchData: true,
                          leaveScrollbarGap:false,
                          animateFolders:true,
                  	    canAcceptDroppedRecords:false,
                          canReparentNodes:false,
                          selectionType:"single",
                          animateRowsMaxTime:750,
                          getIcon: function (parms){}
                      });
                      
                      adminMenuTree.getIcon() = function(){};
                      
                      function treeFetchCallback(parms){
                          adminMenuTree.data.openAll();
                      }

                  Comment


                    #10
                    Hi Picasso,

                    The docs and behavior for treeField are actually correct - treeField is a property on a TreeGridField, not a DataSourceField. So, you could add this to your TreeGrid to use the indicated field:

                    Code:
                        fields : [
                            { name : "label", treeField:true }
                        ],
                    You could, alternatively, add the following to your DataSource:

                    Code:
                        titleField:"label"
                    This declaration indicates that "label" is the best field to use when only a single field is going to be shown that describes the object as a whole, and TreeGrids will use this.

                    There is a gotcha here in that in many cases you can put ListGridField or TreeGridField properties directly on DataSourceField and they work anyway. We'll look at supporting DataSourceField.treeField as an alternative.

                    On the callback: the simpler and cleaner way to do this is:
                    Code:
                        isc.TreeGrid.create({
                           ID:"theTree",
                           ...
                        }).fetchData(null, "theTree.data.openAll()");
                    Your approach of using transformRequest() to set a callback is a bit strange because transformRequest() is designed for transforming outbound data, and also because you have made this DataSource specific to a particular UI component, whereas DataSources are meant to be purely a data model, used by multiple UI components.

                    The actual reason it didn't work is that when you set autoFetchData, the TreeGrid is calling DataSource.fetchData() on your behalf and specifies it's own callback, which you clobbered. This is a subtle interaction (it didn't immediately occur to us to guide you away from transformRequest()), but, it's hard to see what SmartClient could do differently here. SmartClient is a layered architecture for maximum flexibility, and the higher-level layers do use the functionality offered by the lower-level layers.

                    Comment


                      #11
                      Thank you, I've got it all working now. I really appreciate your help.

                      By the way, is there a way to hide or get rid of the node expander (plus/minus or arrow heads) next to the folder nodes?

                      I want it so that the user cannot collapse the nodes.

                      Thanks

                      paul

                      Comment


                        #12
                        Yes, like your getIcon() override, you'll want a getOpenIcon() override that also returns nothing. However you'll still need to add no-op implementations of mouseDown() and click() to disable opening and closing of folders.

                        Comment


                          #13
                          Hi,

                          I'm trying to do the same thing with SmartGWT, that is, get rid of the node expander icon. I tried to override getOpenIcon() with the following code
                          Code:
                          final TreeGrid tg = new TreeGrid() {
                          	public String getOpenIcon(TreeNode node) {return null;}
                          };
                          but I the expander icon is still there :-(

                          Any suggestions? Thank you!

                          Comment

                          Working...
                          X