1. #1
    Ext User MuratCorlu's Avatar
    Join Date
    Oct 2007
    Location
    Istanbul, Turkey
    Posts
    30
    Vote Rating
    0
    MuratCorlu is on a distinguished road

      0  

    Default Ext.ux.tree.JsonTreeLoader

    Ext.ux.tree.JsonTreeLoader


    Hi everyone!

    When I was trying to use TreePanel, I needed some extra works about parsing of dynamic tree data. I'm using JSON that created with PHP. But I wanted to change structure of TreeNode attributes. For example, I don't like send a "leaf" attributes because of I already knew "children" attribute.

    So, I implemented a small plugin named JsonTreeLoader. Maybe somebody needs a plugin like this.

    Plugin code:

    Code:
    Ext.ns('Ext.ux.tree');
    
    /**
     * @class Ext.ux.tree.JsonTreeLoader
     * @extends Ext.tree.TreeLoader
     * <p>A TreeLoader that gives chance to specify a root path of data source, change node attributes
     * names.</p>
     *
     * Creates a new JsonTreeloader.
     * @param {Object} config A config object containing config properties.
     * @author Murat Corlu
     * @link http://muratcorlu.com
     */
    
    
    Ext.ux.tree.JsonTreeLoader = Ext.extend(Ext.tree.TreeLoader, {
        
        // Nodes array root path
        root:undefined,
    
        // To specify different attribute names for TreeNode
        attrNames:{},
    
        // You don't have to send a leaf attribute. If your node has children, leaf is false, otherwise true
        // You can set this property false to use standart way
        leafFromChildrenCount: true,
        
        // private. to handle children attribute name
        childrenAttrName: 'children',
    
        // private override
        processResponse : function(response, node, callback){
            var data = Ext.decode(response.responseText);
            
            // if root property set then use given path as root
            if (this.root) {
                var rootPath = this.root.split('.');
    
                Ext.each(rootPath, function(path) {
                    data = data[path];
                }); 
            }
    
            // get custom children attribute name
            for(customName in this.attrNames) {
                if (this.attrNames[customName] = 'children') {
                    this.childrenAttrName = customName;
                }
            }
            try{
                node.beginUpdate();
                node.appendChild(this.parseData(data));
                node.endUpdate();
    
                if(typeof callback == "function"){
                    callback(this, node);
                }
            }catch(e){
                this.handleFailure(response);
            }
        },
    
        // private
        parseData : function(data) {
            var nodes = [];
            Ext.each(data, function(n){
                var treeNode = this.createNode(n);
    
                if(n[this.childrenAttrName]){
                    var child = this.parseData(n[this.childrenAttrName]);
                    treeNode.appendChild(child);
                }
                nodes.push(treeNode);
            }, this);
    
            return nodes;
        },
    
    
        // private override
        createNode : function(node){
            
            this.defaultProcessAttributes(node);
    
            // Make optional manipulations if it set
            this.processAttributes(node);
    
            return Ext.ux.tree.JsonTreeLoader.superclass.createNode.call(this, node);
        },
        
        defaultProcessAttributes : function(attr) {
            // Replace custom attributes with standart ones
            for(item in attr) {
                if (this.attrNames[item]) {
                    attr[this.attrNames[item]] = attr[item];
                    attr[item] = undefined;
                }
            }
            // Automatic leaf calculation
            if(this.leafFromChildrenCount) {
                attr.leaf = attr.children ? !(attr.children.length > 0) : true;
            }
        },
    
        // override this method if you want
        processAttributes : Ext.emptyFn
    });
    Usage:

    An example of sent data from PHP:

    Code:
    {
        "success":true,
        "data": [{                        // I can use treenodes array at different path from root
              "id":12,
              "textData":"First Item",      // I used textData key instead of text
              "items":[{                        // I used items key instead of children
                     "id":2312,
                     "textData":"Leaf Item"   // I don't have to use leaf key
              }]
        }]
    }
    And Ext side:

    Code:
    new Ext.tree.TreePanel({
        ........
        loader: new Ext.ux.tree.JsonTreeLoader({
             dataUrl:"http://example.com/api/",
             root:'data',             // Setting rootpath
             attrNames:{
                  'textData':'text',       // I say: use "textData" for "text"
                  'items':'children'      //  and use "items" instead of "children"
             }
        }), 
        .......
    I hope it will help you...
    Last edited by MuratCorlu; 31 Mar 2010 at 6:04 AM. Reason: Added feature ability to setting root path nested

  2. #2
    Sencha User
    Join Date
    Mar 2008
    Posts
    566
    Vote Rating
    0
    moegal is on a distinguished road

      0  

    Default


    this looks very interesting, I will try it today.

    Thanks, Marty

  3. #3
    Sencha User
    Join Date
    Mar 2008
    Posts
    566
    Vote Rating
    0
    moegal is on a distinguished road

      0  

    Default


    I am having some problems with the treeloader. When I change textData to text in the json it mostly works.

    Shouldn't the attributes look more like:

    Code:
    attrNames:{
                  text: 'textData',       // I say: use "textData" for "text"
                  children: 'items'      //  and use "items" instead of "children"
             }
    You currently have:

    Code:
    attrNames:{
                  'textData':'text',       // I say: use "textData" for "text"
                  'items':'children'      //  and use "items" instead of "children"
             }
    Thanks, Marty

  4. #4
    Ext User MuratCorlu's Avatar
    Join Date
    Oct 2007
    Location
    Istanbul, Turkey
    Posts
    30
    Vote Rating
    0
    MuratCorlu is on a distinguished road

      0  

    Default


    Hi Marty,

    Your feedback is interesting. attrNames property get attritbute name mapping with a structure "newAttributeName : standartName". I couldn't realize your problem. Sorry...

    By the way, I updated the code. I added ability to mapping root path nested. So you can give rootPath like "data.list.categories". This will get response's data.list.categories property.

    Murat

  5. #5
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,498
    Vote Rating
    46
    Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    If you use different property names in the JSON to that which the TreeNode constructor uses, then simply configure your own implementation of createNode into the loader.

    http://www.extjs.com/deploy/dev/docs...ber=createNode

  6. #6
    Ext User MuratCorlu's Avatar
    Join Date
    Oct 2007
    Location
    Istanbul, Turkey
    Posts
    30
    Vote Rating
    0
    MuratCorlu is on a distinguished road

      0  

    Default


    Quote Originally Posted by Animal View Post
    If you use different property names in the JSON to that which the TreeNode constructor uses, then simply configure your own implementation of createNode into the loader.

    http://www.extjs.com/deploy/dev/docs...ber=createNode
    That seems good. But I couldn't understand exactly how to use it. How can I use "items" instead of "children" with this method? Can you give an example?

  7. #7
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,498
    Vote Rating
    46
    Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    create the new node using children, but use the items property.?

  8. #8
    Ext User MuratCorlu's Avatar
    Join Date
    Oct 2007
    Location
    Istanbul, Turkey
    Posts
    30
    Vote Rating
    0
    MuratCorlu is on a distinguished road

      0  

    Default


    Like this?:

    Code:
    createNode: function(attr) {
       attr.children = attr.items;
       return Ext.tree.TreeLoader.prototype.createNode.call(this, attr)
    }
    I couldn't run this truely.

    My data store sends a json like this:

    Code:
    {
       "success":true,
       "data": [{
          "id":1,
          "text":"Main menu",
          "items":[{
              "id":11,
              "text":"Sub menu"
          }]
       }]
    }
    So, data store don't give mi a leaf attribute. And give me child attributes with "items" property. Now, I want to show a treepanel using this store.

    Sorry for my poor English..

Thread Participants: 2

Tags for this Thread

Turkiyenin en sevilen filmlerinin yer aldigi xnxx internet sitemiz olan ve porn sex tarzi bir site olan mobil porno izle sitemiz gercekten dillere destan bir durumda herkesin sevdigi bir site olarak tarihe gececege benziyor. Sitenin en belirgin ozelliklerinden birisi de Turkiyede gercekten kaliteli ve muntazam, duzenli porno izle siteleri olmamasidir. Bu yuzden iste. Ayrica en net goruntu kalitesine sahip adresinde yayinlanmaktadir. Mesela diğer sitelerimizden bahsedecek olursak, en iyi hd porno video arşivine sahip bir siteyiz. "The Best anal porn videos and slut anus, big asses movies set..."