DataTable Row Expansion was developed by Eric Gelinas. This was originally a concept for Yahoo! APT by Ryan Leffel with designs by Edward Zee.
    
	
		
	
Custom CSS for this Example
DataTable RowExpansion extension code:
Also available here.
 ';
                    new_row.appendChild( new_column );
                    var liner_element = new_row.firstChild.firstChild;
                    if( YAHOO.lang.isString( template ) ){
                        liner_element.innerHTML = YAHOO.lang.substitute( 
                            template, 
                            expanded_data
                        );
                    } else if( YAHOO.lang.isFunction( template ) ) {
                        template( {
                            row_element : new_row,
                            liner_element : liner_element,
                            data : row_data, 
                            state : state 
                        } );
                    } else {
                        return false;
                    }
                    //Insert new row
                    newRow = Dom.insertAfter( new_row, row );
                    if (newRow.innerHTML.length) {
                        this._setRecordState( record_id, 'expanded', true );
                        if( !restore ){
                            this.a_rowExpansions.push( this.getRecord( record_id ).getId() );
                        }
                        Dom.removeClass( row, CLASS_COLLAPSED );
                        Dom.addClass( row, CLASS_EXPANDED );
                        //Fire custom event
                        this.fireEvent( "rowExpandEvent", { record_id : row_data.getId() } );
                        return true;
                    } else {
                        return false;
                    } 
                }
            },
            /**
             * Sets the expansion state of a row to collapsed
             * @method collapseRow
             * @param {Mixed} record_id Record / Row / or Index id
             * @return {Boolean} successful
            **/
            collapseRow : function( record_id ){
                var row_data = this.getRecord( record_id ),
                    row      = Dom.get( row_data.getId() ),
                    state    = row_data.getData( STRING_STATENAME );
                if( state && state.expanded ){
                    var next_sibling = Dom.getNextSibling( row ),
                        hash_index   = indexOf( this.a_rowExpansions, record_id );
                    if( Dom.hasClass( next_sibling, CLASS_EXPANSION ) ) {
                        next_sibling.parentNode.removeChild( next_sibling );
                        this.a_rowExpansions.splice( hash_index, 1 );
                        this._setRecordState( record_id, 'expanded', false );
                        Dom.addClass( row, CLASS_COLLAPSED );
                        Dom.removeClass( row, CLASS_EXPANDED );
                        //Fire custom event
                        this.fireEvent("rowCollapseEvent", { record_id : row_data.getId() } );
                        return true;
                    } else {
                        return false;
                    }
                }
            },
            /**
             * Collapses all expanded rows. This should be called before any
             * action where the row expansion markup would interfear with
             * normal DataTable markup handling. This method does not remove
             * exents attached during implementation. All event handlers should
             * be removed separately.
             *
             * @method collapseAllRows
            **/
            collapseAllRows : function(){
                var rows = this.a_rowExpansions;
                for( var i = 0, l = rows.length; l > i; i++ ){
                    //Always pass 0 since collapseRow removes item from the a_rowExpansions array
                    this.collapseRow( rows[ 0 ] );
                }
                this.a_rowExpansions = [];
            },
            /**
             * Restores rows which have an expanded state but no markup. This
             * is to be called to restore row expansions after the DataTable
             * renders or the collapseAllRows is called.
             *
             * @method collapseAllRows
            **/
            restoreExpandedRows : function(){
                var expanded_rows = this.a_rowExpansions;
                if( !expanded_rows.length ){
                    return;
                }
                if( this.a_rowExpansions.length ){
                    for( var i = 0, l = expanded_rows.length; l > i; i++ ){
                        this.expandRow( expanded_rows[ i ] , true );
                    }
                }
            },
            /**
             * Abstract method which restores row expansion for subscribing to
             * the DataTable postRenderEvent.
             *
             * @method onEventRestoreRowExpansion
             * @param {Object} oArgs context of a subscribed event
            **/
            onEventRestoreRowExpansion : function( oArgs ){
                this.restoreExpandedRows();
            },
            /**
             * Abstract method which toggles row expansion for subscribing to
             * the DataTable postRenderEvent.
             *
             * @method onEventToggleRowExpansion
             * @param {Object} oArgs context of a subscribed event
            **/
            onEventToggleRowExpansion : function( oArgs ){
                if( YAHOO.util.Dom.hasClass( oArgs.target, 'yui-dt-expandablerow-trigger' ) ){
                    this.toggleRowExpansion( oArgs.target );
                }
            }
        });
})();
JavaScript to run this example