views:

281

answers:

3

Ok so, i have this site that i am putting together in the play framework. It basically connects to an FTP site on the back end, retrieves a list of folders/files and sends that to a basic ExtJS front-end as JSON.

I have it working so that the Tree Panel gets populated correctly, but it doesn't seem to be doing anything special when i expand a non-leaf node.

Based on what i've read, it should use the data url, and pass a node parameter with the id of the node to that data url to get the data for the child nodes, but in firebug i don't see any requests being sent for that data.

What do i need to do to allow the ajax calls to fire so that nodes that have children will get them dynamically when the node is expanded?

Here is the relevant code for reference:

Ext.onReady(function() {



   new Ext.Viewport({
       layout: 'border',
       defaults: {
         height: 100,
         width: 250,
         collapseMode: 'mini'
       },
       items : [
           {
               region: 'center',
               margins: '5 5 0 0',
               contentEl: 'center-content'
           },
           {
               id: 'file-tree',
               region: 'west',
               title: 'Files',
               split: true,
               collapsible: true,
               xtype: 'treepanel',
               autoScroll: true,
               loader: new Ext.tree.TreeLoader({
                    dataUrl: 'http://localhost:9000/application/listFiles',


                }),

               root: new Ext.tree.AsyncTreeNode({
                   expand: true,
                   text: "/",
                   id: "/"
               }),
               rootVisibile: true,
               listeners: {
                   click: function(n) {
                       Ext.Msg.alert('File Tree Click', 'You clicked: ' + n.attributes.id);
                   }
               }
           }
       ]
   });
});

The id returned in the JSON is the complete path to sub directory i would like to expand, and the listfiles action will take that parameter and return the appropriate files.

As requested, here is a snippet of the JSON output:

[
      {
          id: "/./",
          text: "./",
          leaf: false,
          children: [ ]
      },
      {
          id: "/../",
          text: "../",
          leaf: false,
          children: [ ]
      },
      {
          id: "/.ftpquota",
          text: ".ftpquota",
          leaf: true,
          children: [ ]
      },
      {
          id: "/.htaccess",
          text: ".htaccess",
          leaf: true,
          children: [ ]
      },
      {
          id: "/022610.html",
          text: "022610.html",
          leaf: true,
          children: [ ]
      },
      {
          id: "/Gail/",
          text: "Gail/",
          leaf: false,
          children: [ ]
      }
]

That last item is an example of the folder that i am looking to dynamically load the children to.

A: 

Can you show the JSON output you are getting from that data url?

Swar
see updated question
Jason Miesionczek
+2  A: 

It is not populating the non-leaf treenodes because in your JSON, there are no children.

What you can do is reload the root node, passing additional parameters (ID's) for the subfolders you would like to get results for.

on the click or expand events for the AsyncTreeNode, you will need to reload the root. Feed the reload method the ID subfolder (clickedVal) you'd like to reload the tree with.

myTreePanel.loader = new Ext.tree.TreeLoader({
    dataUrl:  'http://localhost:9000/application/listFiles',
    requestMethod: 'POST',
    listeners: {
        beforeload: function() {
        this.baseParams.subFolderID = clickedVal;
            }
    }
});
myTreePanel.root.reload({baseParams: {subFolderID: clickedVal});

Addtional Notes: You'll probably need to build in some navigation controls to move back up the tree using this method.

It Grunt
ok i will give this a try, see if i can get it to work. thanks for your response.
Jason Miesionczek
i think i'm going to go in a slightly different direction, but as you provided the best answer for what i was trying to accomplish, i will award you the bounty.
Jason Miesionczek
+1  A: 

As mentioned by the previous poster, the returned JSON, as written, would NOT return any children (no apparent hierarchy/referencing is present). To explain what is happening, it may help for me to take you through a simple treepanel example.

First things first- the ExtJS component, the treepanel itself. At its simplest level, you can set un up thus:

    MYtreepanel=new Ext.tree.TreePanel({
        dataUrl: 'sourceofnodestructure.php',
        root: {
            nodeType: 'async',
            id:'root-node'
            }
        }
    });

Taking you through this code, what this does is create the treepanel component at the most basic level (you will need to add additional settings concerning layout, format, etc etc- as per the code in your original post so it fits with your setup), and add only the minimum settings required to work.

The root node is set to asynchronous (i.e. when you click it, it will load its children dynamically from an external source), and given the id value 'root-node' (or whatever you wish). This id is important. When understanding the operation of async treepanels, you should note that when a node is expanded, by default a POST request is sent to the panels loader/dataurl (in this case 'sourceofnodestructure.php') containing the id of the node clicked, this id is passed in a variable called 'node'. The server side script then needs to read this (i.e. in php using $_REQUEST['node']) and serve up the respective JSON denoting the childeren for the clicked node.

i.e. (again, in PHP):

switch($_REQUEST['node']){
case "root-node":
// output JSON for child nodes under the root node
break;
case "child node 1":
// output JSON for child nodes under the first child node under the root
break;
}
etc etc...

The second part of any treepanel is the node structure. In the above example, this is fed by a server side script- sourceofnodestructure.php. PHP is my preferred way of serving up nodes as it lets me apply my own processing rules and assign additional attributes to nodes in a more flexible way. As I am not sure whether you are using php or not ('http://localhost:9000/application/listFiles'), I wont go into detail regarding it - however, you should go through how your script identifies the clicked node and ensure you remember that the id of the clicked node is sent to the script in the POST variable 'node', you need to trap this and output children as appropriate.

Let me know if you would like an example of the PHP one may use to handle this.

Ergo Summary
so basically because i am not specifying any child elements, when i expand the node, it doesn't think it needs to make an async call? for me to populate the children of each parent node would be a massive waste of bandwidth on the server as the contents of the tree are pulled from an FTP server. I think what i need to do is separate the folders from the files into two tree panels, and hook into the selected event on the folder tree, and fire an ajax call that would retrieve the files for that folder and populate the file tree.
Jason Miesionczek
Yes- because no child elements are specified- none are found when expanding any parent node. As for bandwidth- I know in PHP you can make a directory scraper pretty easily, when the root node is expanded it calls the PHP which scrapes files/folders at the top level, when child folders are expanded the PHP file then scrapes that level and so forth...ultimately it depends how many files/folders you have at each level, but this should be OK for up to a few thousand....though ultimately, treepanels arent designed to show large amounts of data, you may want to combine a treeview and a dataview..
Ergo Summary