Threaded View

  1. #1
    Sencha User
    Join Date
    Mar 2010
    Posts
    83
    Vote Rating
    -1
    daiei27 is an unknown quantity at this point

      0  

    Exclamation [3.x, 3.2.0] RowExpander plugin UPDATED - August 10, 2010

    [3.x, 3.2.0] RowExpander plugin UPDATED - August 10, 2010


    History
    August 10, 2010
    - Added toolbar handling as an example to destroyNestedExtCmp (code below is highlighted in red)
    - Also, if you use the Header for RowExpander extension, see post #10 below...
    April 5, 2010
    - Initial release
    --

    NOTE to all RowExpander plugin users:
    If you use Ext components within expanded rows and are not aware of the memory leak issue, CHECK FOR THEM!


    As a quick check, add this link to your page and keep checking the value as you expand/collapse various components.
    Code:
    <a href="javascript: alert(Ext.ComponentMgr.all.length)" style="color:gray; font-size:smaller">Check ExtJS resources</a>
    --
    This update was made to address that issue, starting from Mikhail's modified RowExpander and running ExtJS 3.2.0.

    I added support to clean up any type of Ext component. I mainly added the cleanup of Ext Panels which covered most of my stuff (charts, etc.), but made it extremely easy for you to add any specific component needs of your own.

    The previous code did not clean up multiple components at the same level so I modified it to cover that scenario.

    It appears to work well in my simple tests (a grid with rows containing multiple charts and multiple grids, with those containing multiple charts and panels in them).

    Cheers,
    Chris

    --
    Attached and posted here:
    Code:
    /*!
     * Ext JS Library 3.2.0
     * Copyright(c) 2006-2009 Ext JS, LLC
     * licensing@extjs.com
     * http://www.extjs.com/license
     * 
     * Modifications by Mykhail Stadnik <http://mikhailstadnik.com>:
     *  - Nesting grids support added
     * Modifications by Chris Newman
     *  - 04/05/2010
     *    - Added support for Ext components in general
     *    - Added support for multiple components at the same level
     *    - Memory-leak fix for Panel-related components
     *      - NOTE: see destroyNestedExtCmp below for adding your own component handling
     *  - 08/10/2010
     *    - As an example, added toolbar to destroyNestedExtCmp
     */
    Ext.ns( 'Ext.ux.grid');
    
    /**
     * @class Ext.ux.grid.RowExpander
     * @extends Ext.util.Observable
     * Plugin (ptype = 'rowexpander') that adds the ability to have a Column in a grid which enables
     * a second row body which expands/contracts.  The expand/contract behavior is configurable to react
     * on clicking of the column, double click of the row, and/or hitting enter while a row is selected.
     *
     * @ptype rowexpander
     */
    Ext.ux.grid.RowExpander = Ext.extend( Ext.util.Observable, {
    
        /**
         * @cfg {Boolean} expandOnEnter
         * <tt>true</tt> to toggle selected row(s) between expanded/collapsed when the enter
         * key is pressed (defaults to <tt>true</tt>).
         */
        expandOnEnter : true,
    
        /**
         * @cfg {Boolean} expandOnDblClick
         * <tt>true</tt> to toggle a row between expanded/collapsed when double clicked
         * (defaults to <tt>true</tt>).
         */
        expandOnDblClick : true,
    
        header           : '',
        width            : 20,
        sortable         : false,
        fixed            : true,
        menuDisabled     : true,
        dataIndex        : '',
        id               : 'expander',
        lazyRender       : true,
        enableCaching    : true,
        actAsTree        : false,
        treeLeafProperty : 'is_leaf',
        appendRowClass   : true,
    
        constructor: function( config){
            if (!config.id) {
                config.id = Ext.id();
            }
    
            Ext.apply( this, config);
    
            var css =
                '.x-' + this.id + '-grid3-row-collapsed .x-grid3-row-expander { background-position:0 0; }' +
                '.x-' + this.id + '-grid3-row-expanded .x-grid3-row-expander { background-position:-25px 0; }' +
                '.x-' + this.id + '-grid3-row-collapsed .x-grid3-row-body { display:none !important; }' +
                '.x-' + this.id + '-grid3-row-expanded .x-grid3-row-body { display:block !important; }' +
                '.x-grid-expander-leaf .x-grid3-row-expander { background: none; }'
            ;
    
            Ext.util.CSS.createStyleSheet( css, Ext.id());
    
            this.expanderClass     = 'x-grid3-row-expander';
            this.rowExpandedClass  = 'x-' + this.id + '-grid3-row-expanded';
            this.rowCollapsedClass = 'x-' + this.id + '-grid3-row-collapsed';
            this.leafClass         = 'x-grid-expander-leaf';
    
            this.addEvents({
                /**
                 * @event beforeexpand
                 * Fires before the row expands. Have the listener return false to prevent the row from expanding.
                 * @param {Object} this RowExpander object.
                 * @param {Object} Ext.data.Record Record for the selected row.
                 * @param {Object} body body element for the secondary row.
                 * @param {Number} rowIndex The current row index.
                 */
                beforeexpand: true,
                /**
                 * @event expand
                 * Fires after the row expands.
                 * @param {Object} this RowExpander object.
                 * @param {Object} Ext.data.Record Record for the selected row.
                 * @param {Object} body body element for the secondary row.
                 * @param {Number} rowIndex The current row index.
                 */
                expand: true,
                /**
                 * @event beforecollapse
                 * Fires before the row collapses. Have the listener return false to prevent the row from collapsing.
                 * @param {Object} this RowExpander object.
                 * @param {Object} Ext.data.Record Record for the selected row.
                 * @param {Object} body body element for the secondary row.
                 * @param {Number} rowIndex The current row index.
                 */
                beforecollapse: true,
                /**
                 * @event collapse
                 * Fires after the row collapses.
                 * @param {Object} this RowExpander object.
                 * @param {Object} Ext.data.Record Record for the selected row.
                 * @param {Object} body body element for the secondary row.
                 * @param {Number} rowIndex The current row index.
                 */
                collapse: true
            });
    
            Ext.ux.grid.RowExpander.superclass.constructor.call(this);
    
            if(this.tpl){
                if(typeof this.tpl == 'string'){
                    this.tpl = new Ext.Template(this.tpl);
                }
                this.tpl.compile();
            }
    
            this.state = {};
            this.bodyContent = {};
        },
    
        getRowClass : function(record, rowIndex, p, ds){
            p.cols = p.cols-1;
            var content = this.bodyContent[record.id];
            if(!content && !this.lazyRender){
                content = this.getBodyContent(record, rowIndex);
            }
            if(content){
                p.body = content;
            }
            var cssClass = this.state[record.id] ? this.rowExpandedClass : this.rowCollapsedClass;
            if (this.actAsTree && record.get( this.treeLeafProperty)) {
                cssClass = this.leafClass;
            }
            return cssClass;
        },
    
        init : function(grid){
            this.grid = grid;
    
            var view = grid.getView();
            view.getRowClass = this.getRowClass.createDelegate( this);
    
            view.enableRowBody = true;
    
            grid.on( 'render',        this.onRender,        this);
            grid.on( 'destroy',       this.onDestroy,       this);
    
            view.on( 'beforerefresh', this.onBeforeRefresh, this);
            view.on( 'refresh',       this.onRefresh,       this);
        },
    
        // @private
        onRender: function() {
            var grid = this.grid;
            var mainBody = grid.getView().mainBody;
            mainBody && mainBody.on( 'mousedown', this.onMouseDown, this, {delegate: '.' + this.expanderClass});
            if (this.expandOnEnter) {
                this.keyNav = new Ext.KeyNav(this.grid.getGridEl(), {
                    'enter' : this.onEnter,
                    scope: this
                });
            }
            if (this.expandOnDblClick) {
                grid.on('rowdblclick', this.onRowDblClick, this);
            }
            if (this.actAsTree) {
                /**
                 * Stop bubbling parent events 
                 */
                grid.getEl().swallowEvent([ 'mouseover', 'mouseout', 'mousedown', 'click', 'dblclick' ]);
            }
        },
    
        // @private
        onBeforeRefresh : function() {
            var rows = this.grid.getEl().select( '.' + this.rowExpandedClass);
            rows.each( function( row) {
                this.collapseRow( row.dom);
            }, this);
        },
    
        // @private
        onRefresh : function() {
            var rows = this.grid.getEl().select( '.' + this.rowExpandedClass);
            rows.each( function( row) {
                Ext.fly( row).replaceClass( this.rowExpandedClass, this.rowCollapsedClass);
            }, this);
        },
    
        // @private    
        onDestroy: function() {
            this.keyNav.disable();
            delete this.keyNav;
            var mainBody = this.grid.getView().mainBody;
            mainBody && mainBody.un( 'mousedown', this.onMouseDown, this);
        },
    
        // @private
        onRowDblClick: function( grid, rowIdx, e) {
            this.toggleRow(rowIdx);
        },
    
        onEnter: function( e) {
            var g = this.grid;
            var sm = g.getSelectionModel();
            var sels = sm.getSelections();
            for (var i = 0, len = sels.length; i < len; i++) {
                var rowIdx = g.getStore().indexOf(sels[i]);
                this.toggleRow(rowIdx);
            }
        },
    
        getBodyContent : function( record, index){
            if (!this.enableCaching) {
                return this.tpl.apply( record.data);
            }
            var content = this.bodyContent[record.id];
            if (!content){
                content = this.tpl.apply( record.data);
                this.bodyContent[record.id] = content;
            }
            return content;
        },
    
        onMouseDown : function(e, t){
            e.stopEvent();
            var row = e.getTarget( '.x-grid3-row');
            this.toggleRow(row);
        },
    
        renderer : function(v, p, record){
            p.cellAttr = 'rowspan="2"';
            return '<div class="' + this.expanderClass + '"> </div>';
        },
    
        beforeExpand : function(record, body, rowIndex){
            if(this.fireEvent('beforeexpand', this, record, body, rowIndex) !== false){
                if(this.tpl && this.lazyRender){
                    body.innerHTML = this.getBodyContent(record, rowIndex);
                }
                return true;
            }else{
                return false;
            }
        },
    
        toggleRow : function(row){
            if(typeof row == 'number'){
                row = this.grid.view.getRow(row);
            }
            if (Ext.fly(row).hasClass( this.leafClass)) {
                return ;
            }
            this[Ext.fly(row).hasClass( this.rowCollapsedClass) ? 'expandRow' : 'collapseRow'](row);
        },
    
        expandRow : function( row){
            if(typeof row == 'number'){
                row = this.grid.view.getRow( row);
            }
            if (Ext.fly(row).hasClass( this.leafClass)) {
                return ;
            }
            var record = this.grid.store.getAt( row.rowIndex);
            var body = Ext.DomQuery.selectNode( 'tr:nth(2) div.x-grid3-row-body', row);
            if (this.beforeExpand(record, body, row.rowIndex)){
                this.state[record.id] = true;
                Ext.fly( row).replaceClass( this.rowCollapsedClass, this.rowExpandedClass);
                this.fireEvent( 'expand', this, record, body, row.rowIndex);
            }
        },
    
        /**
         * Avoid memory leaks by destroying all nested grids recursively
         * - Added handling of multiple children and panels (for charts)
         * @param {Ext.Element} - grid element to destroy
         */
        destroyNestedExtCmp : function( gridRow) {
            var gridEl;
            var bSearch = 1;
            while (bSearch) {
                bSearch = 0;
                // Grids
                if (gridEl = gridRow.child('.x-grid-panel')) {
                    this.destroyNestedExtCmp( gridEl);
                    var grid = Ext.getCmp( gridEl.id);
                    if (grid && (grid != this.grid)) {
                        if (grid instanceof Ext.grid.EditorGridPanel) {
                            var cm = grid.getColumnModel();
                            for (var i = 0, s = cm.getColumnCount(); i < s; i++) {
                                for (var ii = 0, ss = grid.getStore().getCount(); ii < ss; ii++) {
                                    if (editor = cm.getCellEditor( i, ii)) {
                                        editor.destroy();
                                    }
                                }
                            }
                                cm.destroy();
                            }
                        grid.destroy();
                        bSearch = 1;
                    }
                }
                // Panels, toolbars, etc.
                // (x-panel covers many other components that come wrapped in panels, including charts)
                if ((gridEl = gridRow.child('.x-panel')) ||
                    (gridEl = gridRow.child('.x-toolbar')) ) {  // <-- Add simple ExtJS component here
                    var cmp = Ext.getCmp( gridEl.id); // Grab component
                    cmp.destroy(); // Destroy component
                    bSearch = 1; // Search for more
                }
                /**
                ***  ADD more complex ExtJS component handling requirements here!!!
                **/
            } ;// end while - Ext components are found
        },
    
        collapseRow : function( row){
            if (typeof row == 'number'){
                row = this.grid.view.getRow( row);
            }
            if (Ext.fly( row).hasClass( this.leafClass)) {
                return ;
            }
            var record = this.grid.store.getAt( row.rowIndex);
            var body = Ext.fly( row).child( 'tr:nth(1) div.x-grid3-row-body', true);
            if (this.fireEvent( 'beforecollapse', this, record, body, row.rowIndex) !== false) {
                this.destroyNestedExtCmp( Ext.get( row));
                if (record) this.state[record.id] = false;
                Ext.fly( row).replaceClass( this.rowExpandedClass, this.rowCollapsedClass);
                this.fireEvent( 'collapse', this, record, body, row.rowIndex);
            }
        }
    });
    
    Ext.preg( 'rowexpander', Ext.ux.grid.RowExpander);
    
    //backwards compatibility
    Ext.grid.RowExpander = Ext.ux.grid.RowExpander;
    Attached Files

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..." hd porno faketaxi