Page 2 of 2 FirstFirst 12
Results 11 to 20 of 20

Thread: Ext 4 trees a step forward?

  1. #11
    Sencha User
    Join Date
    May 2010
    Posts
    53

    Default

    >>>>(whilst we're at it how about using the Ext 4 way in all your examples? Seriously, throw away all the ones that use Ext 3 class syntax...)

    this is a good point - hopefully all the examples will be fully converted to the ext4 "way"

  2. #12
    Sencha Premium Member steffenk's Avatar
    Join Date
    Jul 2007
    Location
    Haan, Germany
    Posts
    2,676

    Default

    i think it's too early for support more than one model to a tree. Think of the TreeWriter - on change, to which model belongs the change? The complexity just multiplies.

    But i see the usecases, and a tree is just another way of a view presenting existing data.
    As far as i see, i would write a connector store which build the data from the given models and handles the connections. It's not possible to define this inside the models.
    I may be wrong, but we got promised to get better documentation of the tree classes to understand how the tree works and how the underlaying classes interact.
    Tree on store base is great, but definitive adds more complexity, which can't be done the way you handle data in grids or other views.
    vg Steffen
    --------------------------------------
    Release Manager of TYPO3 4.5

  3. #13
    Ext JS Premium Member rstuart's Avatar
    Join Date
    Jan 2008
    Location
    Brisbane, Australia
    Posts
    140

    Default

    I'm in agreement with most people there. The first thing I thought of when I saw the new data package was representing a subsection of my model hierarchy with a Tree. This was particularly exiting for me because I have for a long time written truly RESTful applications where you can navigate the entire resource hierarchy from one starting URL without any prior knowledge.

    If it isn't going to be supported then some examples of the workarounds that you talk about would be good. I look forward to the day the Ext JS supports RESTful applications properly. It is such a large topic I will start a new thread.

  4. #14
    Ext JS Premium Member
    Join Date
    Jan 2011
    Location
    Austin, TX
    Posts
    112

    Default Link up Tree Node to Store to Model

    I have a pretty basic tree. I use a model and a tree store and I'm able to populate the data. I have a method handler that can give me the node - but this is only part of the equation. From what I can tell the Nodes are not populated with the data from my model that is fed into the TreeStore. I wouldn't necessarily expect this to be. But how can I determine by the node clicked what record it is in the data store and then how can I get that record so I can have access to all the properties in my model. Can someone help with this? I'm fairly new to Ext and I'm making headway but this has got me stumped for a couple of days now.

    this is the method handler I got from another example:

    Code:
    this.treePanel.getSelectionModel().on('select', function (sm, node, index) {
    }
    Also, where are these parameters documented. Other than finding this snippet somewhere I can't
    tell what events have what parameters and what they are. "node" and "index" are fairly obvious
    but what is "sm"? SelectionModel maybe? Any help would be appreciated.

  5. #15
    Ext JS Premium Member stevil's Avatar
    Join Date
    Nov 2007
    Location
    Denver, CO
    Posts
    1,045

    Default

    Quote Originally Posted by westy View Post
    I issue I'm having at the moment is the difficulty in extending some of the core classes that make up the tree support.

    For example, I want to add data to each node in the tree, effectively attaching an instance of a tree config class to each one that provides handlers and additional data to be used by them, so need to hook into the node creation process ideally.
    For my application, I needed to get information into the markup to help me style it by node depth, specifically to get the depth on the markup as a class. What I had to do was something like this:


    1) Create a copy of Ext.view.TableChunker - this produces the wrapper for rows
    2) Copy it because it's a singleton and I think extending a singleton is kinda screwy (but that's another topic)
    3) Modify the metaRowTpl and metaTableTpl to put in additional properties you need in the markup.
    4) Add "embed" functions because you're creating a template that creates templates, and that's the only way to get {variables} in the template.
    5) Modify getTableTpl to expose your variable functions in tableTplMemberFns and/or memberFns
    6) Extend Ext.tree.View
    7) Set the view's chunker config to an instance of your TableChunker copy
    8) Override collectData to get any information you need (like depth) into the row
    9) Modify your TreePanel to use the new View

    Mine looked (roughly, not a full working example), like:

    PHP Code:
    Ext.define('My.TreeChunker', {
        
    requires: ['Ext.XTemplate'],
     
       
    // see this.embedDepth in the template
        
    metaRowTpl: [
            
    '<tr class="' Ext.baseCSSPrefix 'grid-row {addlSelector} {[this.embedRowCls()]} tree-depth-{[this.embedDepth()]}">',
                
    '<tpl for="columns">',
                    
    '<td class="' Ext.baseCSSPrefix 'grid-cell ' Ext.baseCSSPrefix 'grid-cell-{id} {{id}-modified} {{id}-tdCls}" {{id}-tdAttr}><div unselectable="on" class="' Ext.baseCSSPrefix 'grid-cell-inner ' Ext.baseCSSPrefix 'unselectable" style="{{id}-style}; text-align: {align};">{{id}}</div></td>',
                
    '</tpl>',
            
    '</tr>'
        
    ],
        
    metaTableTpl: [
            
    '{[this.openTableWrap()]}',
            
    '<table class="' Ext.baseCSSPrefix 'grid-table ' Ext.baseCSSPrefix 'grid-table-resizer" border="0" cellspacing="0" cellpadding="0" {[this.embedFullWidth()]}>',
                
    '<tbody>',
                
    '<tr>',
                
    '<tpl for="columns">',
                    
    '<th class="' Ext.baseCSSPrefix 'grid-col-resizer-{id}" style="width: {width}px; height: 0px;"></th>',
                
    '</tpl>',
                
    '</tr>',
                
    '{[this.openRows()]}',
                    
    '{row}',
                    
    '<tpl for="features">',
                        
    '{[this.embedFeature(values, parent, xindex, xcount)]}',
                    
    '</tpl>',
                
    '{[this.closeRows()]}',
                
    '</tbody>',
            
    '</table>',
            
    '{[this.closeTableWrap()]}'
        
    ],
        
    constructor: function () {
            
    Ext.XTemplate.prototype.recurse = function (valuesreference) {
                return 
    this.apply(reference values[reference] : values);
            };
        },
        
    // My function to support depth in the template
        
    embedDepth: function (valuesparentxxcount) {
            return 
    '{depth}';
        },
        
    embedFeature: function (valuesparentxxcount) {
            var 
    tpl '';
            if (!
    values.disabled) {
                
    tpl values.getFeatureTpl(valuesparentxxcount);
            }
            return 
    tpl;
        },
        
    embedFullWidth: function () {
            return 
    'style="width: {fullWidth}px;"';
        },
        
    openRows: function () {
            return 
    '<tpl for="rows">';
        },
        
    closeRows: function () {
            return 
    '</tpl>';
        },
        
    embedRowCls: function () {
            return 
    '{rowCls}';
        },
        
    openTableWrap: function () {
            return 
    '';
        },
        
    closeTableWrap: function () {
            return 
    '';
        },
        
    getTableTpl: function (cfgtextOnly) {
            var 
    tpl,
                
    tableTplMemberFns = {
                    
    openRowsthis.openRows,
                    
    closeRowsthis.closeRows,
                    
    embedFeaturethis.embedFeature,
                    
    embedFullWidththis.embedFullWidth,
                    
    openTableWrapthis.openTableWrap,
                    
    closeTableWrapthis.closeTableWrap
                
    },
                
    tplMemberFns = {},
                
    features cfg.features || [],
                
    ln features.length,
                
    0,
                
    memberFns = {
                    
    embedDepththis.embedDepth// add my embedder to the row template
                    
    embedRowClsthis.embedRowCls
                
    },
                
    metaRowTpl = Array.prototype.slice.call(this.metaRowTpl0),
                
    metaTableTpl;
            for (; 
    lni++) {
                if (!
    features[i].disabled) {
                    
    features[i].mutateMetaRowTpl(metaRowTpl);
                    
    Ext.apply(memberFnsfeatures[i].getMetaRowTplFragments());
                    
    Ext.apply(tplMemberFnsfeatures[i].getTplFragments());
                    
    Ext.apply(tableTplMemberFnsfeatures[i].getTableFragments());
                }
            }
            
    metaRowTpl = new Ext.XTemplate(metaRowTpl.join(''), memberFns);
            
    cfg.row metaRowTpl.applyTemplate(cfg);
            
    metaTableTpl = new Ext.XTemplate(this.metaTableTpl.join(''), tableTplMemberFns);
            
    tpl metaTableTpl.applyTemplate(cfg);
     
            if (!
    textOnly) {
                
    tpl = new Ext.XTemplate(tpltplMemberFns);
            }
            return 
    tpl;
        }
    });
     
    Ext.define('My.TreeView', {
        
    extend'Ext.tree.View',
        
    alias'widget.mytreeview',
     
        
    chunker: new My.TreeChunker(),
        
    collectData: function (records) {
            var 
    data this.callParent(arguments),
                
    rows data.rows,
                
    ln rows.length,
                
    i;
            for (
    0lni++) {
                
    // set depth on row data to that of tree node
                // this assumes, of course that your data source
                // doesn't provide depth, in which case you 
                // wouldn't need this
                
    rows[i].depth records[i].getDepth();
            }
            return 
    data;
        }
    });
     
    var 
    tree = new Ext.tree.Panel( {
      
    view'My.TreeView',
      ... 
    rest of your config
    }); 
    Note that, if I could extend Ext.view.TableChunker via Ext.define (which I can't because it wants a class name, not an Ext.getClass of a singleton instance), I would have, so it would have been much smaller.

    stevil
    And remember, it's better with CHUNKS!
    Last edited by stevil; 19 Apr 2011 at 6:15 AM. Reason: "Go advanced" posts, doesn't let you edit

  6. #16
    Sencha Premium User westy's Avatar
    Join Date
    Feb 2009
    Location
    Bath, UK
    Posts
    1,035

    Default

    Thanks Stevil, I hope to get back to trees this afternoon, after finally getting my app all wired up with beta3.

    Will take a look at the chunker to see if it helps my case

  7. #17
    Ext JS Premium Member stevil's Avatar
    Join Date
    Nov 2007
    Location
    Denver, CO
    Posts
    1,045

    Default

    @westy - one last thing - the chunker I supplied overrides the overall ROW structure - it does NOT handle the actual node rendering - for that, you'll need to override TreeColumn, like:

    PHP Code:
    Ext.define(My.TreeColumn', {
        extend: '
    Ext.grid.column.Column',
        alias: '
    widget.mytreecolumn',
        initComponent: function () {
            var origRenderer = this.renderer || this.defaultRenderer,
                origScope = this.scope || window;
            this.renderer = function (value, metaData, record, rowIdx, colIdx, store, view) {
                var buf = [],
                    format = Ext.String.format,
                    depth = record.getDepth(),
                    treePrefix = Ext.baseCSSPrefix + '
    tree-',
                    elbowPrefix = treePrefix + '
    elbow-',
                    expanderCls = treePrefix + '
    expander',
                    imgText = '
    <img src="{1}" class="{0}" />',
                    checkboxText = '
    <input type="checkbox" class="{0}" {1} />',
                    formattedValue = origRenderer.apply(origScope, arguments),
                    href = record.get('
    href'),
                    target = record.get('
    hrefTarget');
                while (record) {
                    if (!record.isRoot() || (record.isRoot() && view.rootVisible)) {
                        if (record.getDepth() === depth) {
                            buf.unshift(format(imgText,
                                treePrefix + '
    icon ' +
                                treePrefix + '
    icon' + (record.get('icon') ? '-inline ' : (record.isLeaf() ? '-leaf ' : '-parent ')) +
                                (record.get('
    iconCls') || ''),
                                record.get('
    icon') || Ext.BLANK_IMAGE_URL
                            ));
                            if (record.get('
    checked') !== null) {
                                buf.unshift(format(checkboxText, (treePrefix + '
    checkbox'), record.get('checked') ? 'checked="checked"' : ''));
                                if (record.get('
    checked')) {
                                    metaData.tdCls += (' ' + Ext.baseCSSPrefix + '
    tree-checked');
                                }
                            }
                            if (record.isLast()) {
                                if (record.isLeaf()) {
                                    buf.unshift(format(imgText, (elbowPrefix + '
    end'), Ext.BLANK_IMAGE_URL));
                                } else {
                                    buf.unshift(format(imgText, (elbowPrefix + '
    end-plus ' + expanderCls), Ext.BLANK_IMAGE_URL));
                                }
                            } else {
                                if (record.isLeaf()) {
                                    buf.unshift(format(imgText, (treePrefix + '
    elbow'), Ext.BLANK_IMAGE_URL));
                                } else {
                                    buf.unshift(format(imgText, (elbowPrefix + '
    plus ' + expanderCls), Ext.BLANK_IMAGE_URL));
                                }
                            }
                        } else {
                            if (record.isLast() || record.getDepth() === 0) {
                                buf.unshift(format(imgText, (elbowPrefix + '
    empty'), Ext.BLANK_IMAGE_URL));
                            } else if (record.getDepth() !== 0) {
                                buf.unshift(format(imgText, (elbowPrefix + '
    line'), Ext.BLANK_IMAGE_URL));
                            }
                        }
                    }
                    record = record.parentNode;
                }
    // I commented this out in mine, as href is returned in my payload, and I want that
    // handled in the itemclick and itemcontextmenu events, so can'
    t have Ext making 
    // an anchor tag!

    //            if (href) {
    //                formattedValue = format('<a href="{0}" target="{1}">{2}</a>', href, target, formattedValue);
    //            }
                
    return buf.join("") + formattedValue;
            };
            
    this.callParent(arguments);
        },
        
    defaultRenderer: function (value) {
            return 
    value;
        }
    }); 
    and in the tree panel config that needs it:

    PHP Code:
    ...
    hideHeaderstrue,    
    columns : [ 
    xtype'mytreecolumn'flex1sortablefalsedataIndex'text' }
    ],
    ... 

  8. #18
    Ext JS Premium Member stevil's Avatar
    Join Date
    Nov 2007
    Location
    Denver, CO
    Posts
    1,045

    Default

    As a postscript, I'm not really sure how much I like having to extend/override one part of the framework to get my node to render, and ANOTHER part of the framework to render its HTML container!

  9. #19
    Sencha Premium User
    Join Date
    May 2009
    Posts
    157

    Default

    Please Sencha, could you give us an update on 4.1 plans and the support of multiple models? At least when decorating child elements with TreeNode behaviour, it would be nice if you could follow the associations set in models and apply correct fields/properties for each node?

    The current TreeStore/TreePanel might be usefull for manual data setups with all TreeNode properties coming from your proxy resource. But many data sources don't provide Node properties at all, so it would be great if this information could be created on the fly according to the associations set in the models!

  10. #20
    Ext JS Premium Member stevil's Avatar
    Join Date
    Nov 2007
    Location
    Denver, CO
    Posts
    1,045

    Default

    Quote Originally Posted by DiscoBoy View Post
    Please Sencha, could you give us an update on 4.1 plans and the support of multiple models? At least when decorating child elements with TreeNode behaviour, it would be nice if you could follow the associations set in models and apply correct fields/properties for each node?

    The current TreeStore/TreePanel might be usefull for manual data setups with all TreeNode properties coming from your proxy resource. But many data sources don't provide Node properties at all, so it would be great if this information could be created on the fly according to the associations set in the models!
    It's SenchaCon week, I wouldn't be surprised if not too many thread update requests like this got updates... If you don't, you might want to ping them at the end of the week... I only say this because 4.0 was released a couple of days before they went to SenchaCon (Split), and they were mostly, but not completely, off the radar.

    stevil

Page 2 of 2 FirstFirst 12

Similar Threads

  1. Step by step tutorial Desktop
    By blow in forum Ext 2.x: Help & Discussion
    Replies: 2
    Last Post: 14 Oct 2009, 3:40 PM
  2. Step-by-step instructions for running Explorer demo. . .
    By dmdabbs in forum Ext GWT: Discussion
    Replies: 0
    Last Post: 14 Sep 2009, 12:12 PM
  3. step by step configuration
    By baksheen in forum Community Discussion
    Replies: 0
    Last Post: 6 Jul 2009, 6:51 AM
  4. AJAX PHP Step by Step example
    By bluesapphire in forum Ext 2.x: Help & Discussion
    Replies: 2
    Last Post: 20 Jun 2008, 4:44 PM
  5. Portal Drag&Drop step by step
    By Evolic in forum Ext 2.x: Help & Discussion
    Replies: 0
    Last Post: 10 Apr 2008, 7:12 AM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •