Loading ...
Sorry, an error occurred while loading the content.
 

Re: [ydn-javascript] Re: Expandable DataTable unsortable?

Expand Messages
  • Satyam
    The superclass of the DataTable is Element so the call will succeed, but it is not going to call DataTable s own initAttributes so none of the configuration
    Message 1 of 10 , Oct 30, 2009
      The superclass of the DataTable is Element so the call will succeed, but
      it is not going to call DataTable's own initAttributes so none of the
      configuration attributes on a regular DataTable will show. In fact,
      myDataTable._configs which would contain those attributes only lists the
      two that Element declares (element and id) and the one the example
      declares, the rest are gone for good.

      Satyam

      Christian Tiberg escribió:
      >
      >
      > The line below
      >
      > YAHOO.widget.DataTable.superclass.initAttributes.call( this,
      > oConfigs );
      >
      > tries to do something nice, i.e. call the inherited method to init
      > attributes. But the whole code is setup *WITHOUT* inheritance, so it
      > falls flat on it's face. Check this space later, and I just might have
      > a treat for you :)
      >
      > Best regards,
      > Christian Tiberg
      >
      >
      > 2009/10/30 Christian Tiberg <ctiberg@... <mailto:ctiberg@...>>
      >
      > Hello everyone, but maybe Satyam in particular :)
      >
      > We're adapting the example
      > at http://developer.yahoo.com/yui/examples/datatable/dt_rowexp_basic.html to
      > our needs, which unfortunately is a little more complex than
      > what's shown in the example.
      >
      > Our table is sortable, and that shows up correctly in that there's
      > a hand at the column titles. But the table stubbornly refuses to
      > display or react to sorting, despite being setup show sorting on
      > load. Removing the link to the expandable talbe (in a separate JS
      > file) remedies the issue, but also removes the feature of expansion.
      >
      > Any help? Our page is
      > at http://commsoft.nu/demo/ktb/avgangar.php and we need help bad :)
      >
      > Best regards,
      > Christian Tiberg
      >
      >
      >
      >
      >
      > ------------------------------------------------------------------------
      >
      >
      > No virus found in this incoming message.
      > Checked by AVG - www.avg.com
      > Version: 8.5.423 / Virus Database: 270.14.39/2468 - Release Date: 10/29/09 19:49:00
      >
      >
    • Satyam
      So, first you declare the constructor of your new table, say: YAHOO.widget.ExpandableDataTable = function () {
      Message 2 of 10 , Oct 30, 2009
        So, first you declare the constructor of your new table, say:

        YAHOO.widget.ExpandableDataTable = function () {

        YAHOO.widget.ExpandableDataTable.superclass.constructor.apply(this,arguments);

        };


        If you want to manipulate any of the arguments, name them and use call
        instead of apply providing your altered arguments. The example code
        does not do anything with the initial arguments. Then:

        YAHOO.lang.extend(YAHOO.widget.ExpandableDataTable, YAHOO.widget.DataTable, {

        initAttributes: function (oConfigs ) {

        oConfigs = oConfigs || {};

        YAHOO.widget.ExpandableDataTable.superclass.initAttributes.call(this, oConfigs);

        // add your own attributes here

        },

        // add your own methods and properties here

        // for methods, remember to call the superclass method, unless you really don't want it

        });


        Satyam


        Christian Tiberg escribió:
        >
        >
        > The only thing you might see is my head explode. I'm either too stupid
        > or too tired to understand how to make what I want.
        >
        > To make the superclass call work, I'd need to make a new class called
        > ExpandableDataTable, derived from YAHOO.widget.DataTable. That much is
        > clear. So could someone please write up a simple snippet of how to do
        > that, preferrably before my head goes supernova?
        >
        > Best regards,
        > Christian Tiberg
        >
        >
        > 2009/10/30 Christian Tiberg <ctiberg@... <mailto:ctiberg@...>>
        >
        > The line below
        >
        > YAHOO.widget.DataTable.superclass.initAttributes.call( this,
        > oConfigs );
        >
        > tries to do something nice, i.e. call the inherited method to init
        > attributes. But the whole code is setup *WITHOUT* inheritance, so
        > it falls flat on it's face. Check this space later, and I just
        > might have a treat for you :)
        >
        > Best regards,
        > Christian Tiberg
        >
        >
        > 2009/10/30 Christian Tiberg <ctiberg@...
        > <mailto:ctiberg@...>>
        >
        > Hello everyone, but maybe Satyam in particular :)
        >
        > We're adapting the example
        > at http://developer.yahoo.com/yui/examples/datatable/dt_rowexp_basic.html to
        > our needs, which unfortunately is a little more complex than
        > what's shown in the example.
        >
        > Our table is sortable, and that shows up correctly in that
        > there's a hand at the column titles. But the table stubbornly
        > refuses to display or react to sorting, despite being setup
        > show sorting on load. Removing the link to the expandable
        > talbe (in a separate JS file) remedies the issue, but also
        > removes the feature of expansion.
        >
        > Any help? Our page is
        > at http://commsoft.nu/demo/ktb/avgangar.php and we need help
        > bad :)
        >
        > Best regards,
        > Christian Tiberg
        >
        >
        >
        >
        >
        >
        > ------------------------------------------------------------------------
        >
        >
        > No virus found in this incoming message.
        > Checked by AVG - www.avg.com
        > Version: 8.5.423 / Virus Database: 270.14.39/2468 - Release Date: 10/29/09 19:49:00
        >
        >
      • Christian Tiberg
        Thanks a lot Satyam, that s exactly what I needed! Best regards, Christian Tiberg 2009/10/30 Satyam
        Message 3 of 10 , Nov 1, 2009
          Thanks a lot Satyam, that's exactly what I needed!

          Best regards,
           Christian Tiberg


          2009/10/30 Satyam <satyam@...>

          So, first you declare the constructor of your new table, say:

          YAHOO.widget.ExpandableDataTable = function () {

          YAHOO.widget.ExpandableDataTable.superclass.constructor.apply(this,arguments);

          };

          If you want to manipulate any of the arguments, name them and use call
          instead of apply providing your altered arguments. The example code
          does not do anything with the initial arguments. Then:

          YAHOO.lang.extend(YAHOO.widget.ExpandableDataTable, YAHOO.widget.DataTable, {

          initAttributes: function (oConfigs ) {

          oConfigs = oConfigs || {};

          YAHOO.widget.ExpandableDataTable.superclass.initAttributes.call(this, oConfigs);

          // add your own attributes here

          },

          // add your own methods and properties here

          // for methods, remember to call the superclass method, unless you really don't want it

          });


        • Christian Tiberg
          Here s the finished class, perhaps someone could update the example? Then other people won t have to go through this :) (function(){ var Dom = YAHOO.util.Dom,
          Message 4 of 10 , Nov 1, 2009
            Here's the finished class, perhaps someone could update the example? Then other people won't have to go through this :)

            (function(){
            var Dom = YAHOO.util.Dom,
            STRING_STATENAME  = 'yui_dt_state',
            CLASS_EXPANDED    = 'yui-dt-expanded',
            CLASS_COLLAPSED   = 'yui-dt-collapsed',
            CLASS_EXPANSION   = 'yui-dt-expansion',
            CLASS_LINER       = 'yui-dt-liner',

            //From YUI 3
            indexOf = function(a, val) {
            for (var i=0; i<a.length; i=i+1) {
            if (a[i] === val) {
            return i;
            }
            }

            return -1;
            };

            YAHOO.widget.ExpandableDataTable = function()
            {
            YAHOO.widget.ExpandableDataTable.superclass.constructor.apply(this,arguments);
            }

            YAHOO.lang.extend(YAHOO.widget.ExpandableDataTable, YAHOO.widget.DataTable, {

            /////////////////////////////////////////////////////////////////////////////
            //
            // Private members
            //
            /////////////////////////////////////////////////////////////////////////////

            /**
            * Gets state object for a specific record associated with the DataTable.
            * @method _getRecordState
            * @param {Mixed} record_id Record / Row / or Index id
            * @param {String} key Key to return within the state object. Default is to
            * return all as a map
            * @return {Object} State data object
            * @type mixed
            * @private
            **/
            _getRecordState : function( record_id, key ){

            var row_data    = this.getRecord( record_id ),
            row_state   = row_data.getData( STRING_STATENAME ),
            state_data  = ( row_state && key ) ? row_state[ key ] : row_state;

            return state_data || {};

            },

            /**
            * Sets a value to a state object with a unique id for a record which
            * is associated with the DataTable
            * @method _setRecordState
            * @param {Mixed} record_id Record / Row / or Index id
            * @param {String} key Key to use in map
            * @param {Mixed} value Value to assign to the key
            * @return {Object} State data object
            * @type mixed
            * @private
            **/
            _setRecordState : function( record_id, key, value ){

            var row_data      = this.getRecord( record_id ).getData(),
            merged_data   = row_data[ STRING_STATENAME ] || {};

            merged_data[ key ] = value;

            this.getRecord( record_id ).setData( STRING_STATENAME, merged_data );

            return merged_data;

            },

            /////////////////////////////////////////////////////////////////////////////
            //
            // Public methods
            //
            /////////////////////////////////////////////////////////////////////////////

            /**
            * Over-ridden initAttributes method from DataTable
            * @method initAttributes
            * @param {Mixed} record_id Record / Row / or Index id
            * @param {String} key Key to use in map
            * @param {Mixed} value Value to assign to the key
            * @return {Object} State data object
            * @type mixed
            **/
            initAttributes : function( oConfigs ) {

            oConfigs = oConfigs || {};

            YAHOO.widget.ExpandableDataTable.superclass.initAttributes.call(this, oConfigs);

            /**
            * @attribute rowExpansionTemplate
            * @description Value for the rowExpansionTemplate attribute.
            * @type {Mixed}
            * @default ""
            **/
            this.setAttributeConfig("rowExpansionTemplate", {
            value: "",
            validator: function( template ){
            return (
            YAHOO.lang.isString( template ) ||
            YAHOO.lang.isFunction( template )
            );
            },
            method: this.initRowExpansion
            });

            },

            /**
            * Initializes row expansion on the DataTable instance
            * @method initRowExpansion
            * @param {Mixed} template a string template or function to be called when
            * Row is expanded
            * @type mixed
            **/
            initRowExpansion : function( template ){

            //Set subscribe restore method
            this.subscribe( 'postRenderEvent', this.onEventRestoreRowExpansion );

            //Setup template
            this.rowExpansionTemplate = template;

            //Set table level state
            this.a_rowExpansions = [];

            },

            /**
            * Toggles the expansion state of a row
            * @method toggleRowExpansion
            * @param {Mixed} record_id Record / Row / or Index id
            * @type mixed
            **/
            toggleRowExpansion : function( record_id ){

            var state = this._getRecordState( record_id );

            if( state && state.expanded ){

            this.collapseRow( record_id );

            } else {

            this.expandRow( record_id );

            }

            },

            /**
            * Sets the expansion state of a row to expanded
            * @method expandRow
            * @param {Mixed} record_id Record / Row / or Index id
            * @param {Boolean} restore will restore an exisiting state for a
            * row that has been collapsed by a non user action
            * @return {Boolean} successful
            * @type mixed
            **/
            expandRow : function( record_id, restore ){

            var state = this._getRecordState( record_id );

            if( !state.expanded || restore ){

            var row_data          = this.getRecord( record_id ),
            row               = this.getRow( row_data ),
            new_row           = document.createElement('tr'),
            column_length     = this.getFirstTrEl().childNodes.length,
            expanded_data     = row_data.getData(),
            expanded_content  = null,
            template          = this.rowExpansionTemplate,
            next_sibling      = Dom.getNextSibling( row );

            //Construct expanded row body
            new_row.className = CLASS_EXPANSION;
            var new_column = document.createElement( 'td' );
            new_column.colSpan = column_length;

            new_column.innerHTML = '<div class="'+ CLASS_LINER +'"></div>';
            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
            * @type mixed
            **/
            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
            * @type mixed
            **/
            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 ] );

            }

            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
            * @type mixed
            **/
            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
            * @type mixed
            **/
            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
            * @type mixed
            **/
            onEventToggleRowExpansion : function( oArgs ){

            //if( YAHOO.util.Dom.hasClass( oArgs.target, 'yui-dt-expandablerow-trigger' ) ){

            this.toggleRowExpansion( oArgs.target );

            //}

            }

            }, true //This boolean is needed to override members of the original object
            );

            })();

            Best regards,
             Christian Tiberg


            2009/11/1 Christian Tiberg <ctiberg@...>
            Thanks a lot Satyam, that's exactly what I needed!

            Best regards,
             Christian Tiberg


            2009/10/30 Satyam <satyam@...>

            So, first you declare the constructor of your new table, say:

            YAHOO.widget.ExpandableDataTable = function () {

            YAHOO.widget.ExpandableDataTable.superclass.constructor.apply(this,arguments);

            };

            If you want to manipulate any of the arguments, name them and use call
            instead of apply providing your altered arguments. The example code
            does not do anything with the initial arguments. Then:

            YAHOO.lang.extend(YAHOO.widget.ExpandableDataTable, YAHOO.widget.DataTable, {

            initAttributes: function (oConfigs ) {

            oConfigs = oConfigs || {};

            YAHOO.widget.ExpandableDataTable.superclass.initAttributes.call(this, oConfigs);

            // add your own attributes here

            },

            // add your own methods and properties here

            // for methods, remember to call the superclass method, unless you really don't want it

            });



          • Satyam
            I filed a ticket for the example: http://yuilibrary.com/projects/yui2/ticket/2528595 Why don t you upload your code to GIST (or any other way to make it
            Message 5 of 10 , Nov 1, 2009
              I filed a ticket for the example:

              http://yuilibrary.com/projects/yui2/ticket/2528595

              Why don't you upload your code to GIST (or any other way to make it
              public) and make a reference to it from this same ticket.

              Thanks for your help

              Satyam


              Christian Tiberg escribió:
              >
              >
              > Here's the finished class, perhaps someone could update the example?
              > Then other people won't have to go through this :)
              >
              > (function(){
              > var Dom = YAHOO.util.Dom,
              > STRING_STATENAME = 'yui_dt_state',
              > CLASS_EXPANDED = 'yui-dt-expanded',
              > CLASS_COLLAPSED = 'yui-dt-collapsed',
              > CLASS_EXPANSION = 'yui-dt-expansion',
              > CLASS_LINER = 'yui-dt-liner',
              >
              > //From YUI 3
              > indexOf = function(a, val) {
              > for (var i=0; i<a.length; i=i+1) {
              > if (a[i] === val) {
              > return i;
              > }
              > }
              >
              > return -1;
              > };
              >
              > YAHOO.widget.ExpandableDataTable = function()
              > {
              > YAHOO.widget.ExpandableDataTable.superclass.constructor.apply(this,arguments);
              > }
              >
              > YAHOO.lang.extend(YAHOO.widget.ExpandableDataTable,
              > YAHOO.widget.DataTable, {
              >
              > /////////////////////////////////////////////////////////////////////////////
              > //
              > // Private members
              > //
              > /////////////////////////////////////////////////////////////////////////////
              >
              > /**
              > * Gets state object for a specific record associated with the DataTable.
              > * @method _getRecordState
              > * @param {Mixed} record_id Record / Row / or Index id
              > * @param {String} key Key to return within the state object. Default is to
              > * return all as a map
              > * @return {Object} State data object
              > * @type mixed
              > * @private
              > **/
              > _getRecordState : function( record_id, key ){
              >
              > var row_data = this.getRecord( record_id ),
              > row_state = row_data.getData( STRING_STATENAME ),
              > state_data = ( row_state && key ) ? row_state[ key ] : row_state;
              >
              > return state_data || {};
              >
              > },
              >
              > /**
              > * Sets a value to a state object with a unique id for a record which
              > * is associated with the DataTable
              > * @method _setRecordState
              > * @param {Mixed} record_id Record / Row / or Index id
              > * @param {String} key Key to use in map
              > * @param {Mixed} value Value to assign to the key
              > * @return {Object} State data object
              > * @type mixed
              > * @private
              > **/
              > _setRecordState : function( record_id, key, value ){
              >
              > var row_data = this.getRecord( record_id ).getData(),
              > merged_data = row_data[ STRING_STATENAME ] || {};
              >
              > merged_data[ key ] = value;
              >
              > this.getRecord( record_id ).setData( STRING_STATENAME, merged_data );
              >
              > return merged_data;
              >
              > },
              >
              > /////////////////////////////////////////////////////////////////////////////
              > //
              > // Public methods
              > //
              > /////////////////////////////////////////////////////////////////////////////
              >
              > /**
              > * Over-ridden initAttributes method from DataTable
              > * @method initAttributes
              > * @param {Mixed} record_id Record / Row / or Index id
              > * @param {String} key Key to use in map
              > * @param {Mixed} value Value to assign to the key
              > * @return {Object} State data object
              > * @type mixed
              > **/
              > initAttributes : function( oConfigs ) {
              >
              > oConfigs = oConfigs || {};
              >
              > YAHOO.widget.ExpandableDataTable.superclass.initAttributes.call(this,
              > oConfigs);
              >
              > /**
              > * @attribute rowExpansionTemplate
              > * @description Value for the rowExpansionTemplate attribute.
              > * @type {Mixed}
              > * @default ""
              > **/
              > this.setAttributeConfig("rowExpansionTemplate", {
              > value: "",
              > validator: function( template ){
              > return (
              > YAHOO.lang.isString( template ) ||
              > YAHOO.lang.isFunction( template )
              > );
              > },
              > method: this.initRowExpansion
              > });
              >
              > },
              >
              > /**
              > * Initializes row expansion on the DataTable instance
              > * @method initRowExpansion
              > * @param {Mixed} template a string template or function to be called when
              > * Row is expanded
              > * @type mixed
              > **/
              > initRowExpansion : function( template ){
              >
              > //Set subscribe restore method
              > this.subscribe( 'postRenderEvent', this.onEventRestoreRowExpansion );
              >
              > //Setup template
              > this.rowExpansionTemplate = template;
              >
              > //Set table level state
              > this.a_rowExpansions = [];
              >
              > },
              >
              > /**
              > * Toggles the expansion state of a row
              > * @method toggleRowExpansion
              > * @param {Mixed} record_id Record / Row / or Index id
              > * @type mixed
              > **/
              > toggleRowExpansion : function( record_id ){
              >
              > var state = this._getRecordState( record_id );
              >
              > if( state && state.expanded ){
              >
              > this.collapseRow( record_id );
              >
              > } else {
              >
              > this.expandRow( record_id );
              >
              > }
              >
              > },
              >
              > /**
              > * Sets the expansion state of a row to expanded
              > * @method expandRow
              > * @param {Mixed} record_id Record / Row / or Index id
              > * @param {Boolean} restore will restore an exisiting state for a
              > * row that has been collapsed by a non user action
              > * @return {Boolean} successful
              > * @type mixed
              > **/
              > expandRow : function( record_id, restore ){
              >
              > var state = this._getRecordState( record_id );
              >
              > if( !state.expanded || restore ){
              >
              > var row_data = this.getRecord( record_id ),
              > row = this.getRow( row_data ),
              > new_row = document.createElement('tr'),
              > column_length = this.getFirstTrEl().childNodes.length,
              > expanded_data = row_data.getData(),
              > expanded_content = null,
              > template = this.rowExpansionTemplate,
              > next_sibling = Dom.getNextSibling( row );
              >
              > //Construct expanded row body
              > new_row.className = CLASS_EXPANSION;
              > var new_column = document.createElement( 'td' );
              > new_column.colSpan = column_length;
              >
              > new_column.innerHTML = '<div class="'+ CLASS_LINER +'"></div>';
              > 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
              > * @type mixed
              > **/
              > 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
              > * @type mixed
              > **/
              > 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 ] );
              >
              > }
              >
              > 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
              > * @type mixed
              > **/
              > 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
              > * @type mixed
              > **/
              > 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
              > * @type mixed
              > **/
              > onEventToggleRowExpansion : function( oArgs ){
              >
              > //if( YAHOO.util.Dom.hasClass( oArgs.target,
              > 'yui-dt-expandablerow-trigger' ) ){
              >
              > this.toggleRowExpansion( oArgs.target );
              >
              > //}
              >
              > }
              >
              > }, true //This boolean is needed to override members of the original
              > object
              > );
              >
              > })();
              >
              > Best regards,
              > Christian Tiberg
              >
              >
              > 2009/11/1 Christian Tiberg <ctiberg@... <mailto:ctiberg@...>>
              >
              > Thanks a lot Satyam, that's exactly what I needed!
              >
              > Best regards,
              > Christian Tiberg
              >
              >
              > 2009/10/30 Satyam <satyam@...
              > <mailto:satyam@...>>
              >
              > So, first you declare the constructor of your new table, say:
              >
              > YAHOO.widget.ExpandableDataTable = function () {
              >
              > YAHOO.widget.ExpandableDataTable.superclass.constructor.apply(this,arguments);
              >
              > };
              >
              > If you want to manipulate any of the arguments, name them and
              > use call
              > instead of apply providing your altered arguments. The example
              > code
              > does not do anything with the initial arguments. Then:
              >
              > YAHOO.lang.extend(YAHOO.widget.ExpandableDataTable,
              > YAHOO.widget.DataTable, {
              >
              > initAttributes: function (oConfigs ) {
              >
              > oConfigs = oConfigs || {};
              >
              > YAHOO.widget.ExpandableDataTable.superclass.initAttributes.call(this,
              > oConfigs);
              >
              > // add your own attributes here
              >
              > },
              >
              > // add your own methods and properties here
              >
              > // for methods, remember to call the superclass method, unless
              > you really don't want it
              >
              > });
              >
              >
              >
              >
              >
              >
              > ------------------------------------------------------------------------
              >
              >
              > No virus found in this incoming message.
              > Checked by AVG - www.avg.com
              > Version: 8.5.423 / Virus Database: 270.14.40/2471 - Release Date: 10/31/09 07:53:00
              >
              >
            • Christian Tiberg
              That s now done. Did I put the URL in the right place? Best regards, Christian Tiberg 2009/11/1 Satyam ... That s now done. Did I put
              Message 6 of 10 , Nov 3, 2009
                That's now done. Did I put the URL in the right place?

                Best regards,
                 Christian Tiberg


                2009/11/1 Satyam <satyam@...>
                 

                I filed a ticket for the example:

                http://yuilibrary.com/projects/yui2/ticket/2528595

                Why don't you upload your code to GIST (or any other way to make it
                public) and make a reference to it from this same ticket.

                Thanks for your help

                Satyam

                Christian Tiberg escribió:


                >
                >
                > Here's the finished class, perhaps someone could update the example?
                > Then other people won't have to go through this :)
                >
                > (function(){
                > var Dom = YAHOO.util.Dom,
                > STRING_STATENAME = 'yui_dt_state',
                > CLASS_EXPANDED = 'yui-dt-expanded',
                > CLASS_COLLAPSED = 'yui-dt-collapsed',
                > CLASS_EXPANSION = 'yui-dt-expansion',
                > CLASS_LINER = 'yui-dt-liner',
                >
                > //From YUI 3
                > indexOf = function(a, val) {
                > for (var i=0; i<a.length; i=i+1) {
                > if (a[i] === val) {
                > return i;
                > }
                > }
                >
                > return -1;
                > };
                >
                > YAHOO.widget.ExpandableDataTable = function()
                > {
                > YAHOO.widget.ExpandableDataTable.superclass.constructor.apply(this,arguments);
                > }
                >
                > YAHOO.lang.extend(YAHOO.widget.ExpandableDataTable,
                > YAHOO.widget.DataTable, {
                >
                > /////////////////////////////////////////////////////////////////////////////
                > //
                > // Private members
                > //
                > /////////////////////////////////////////////////////////////////////////////
                >
                > /**
                > * Gets state object for a specific record associated with the DataTable.
                > * @method _getRecordState
                > * @param {Mixed} record_id Record / Row / or Index id
                > * @param {String} key Key to return within the state object. Default is to
                > * return all as a map
                > * @return {Object} State data object
                > * @type mixed
                > * @private
                > **/
                > _getRecordState : function( record_id, key ){
                >
                > var row_data = this.getRecord( record_id ),
                > row_state = row_data.getData( STRING_STATENAME ),
                > state_data = ( row_state && key ) ? row_state[ key ] : row_state;
                >
                > return state_data || {};
                >
                > },
                >
                > /**
                > * Sets a value to a state object with a unique id for a record which
                > * is associated with the DataTable
                > * @method _setRecordState
                > * @param {Mixed} record_id Record / Row / or Index id
                > * @param {String} key Key to use in map
                > * @param {Mixed} value Value to assign to the key
                > * @return {Object} State data object
                > * @type mixed
                > * @private
                > **/
                > _setRecordState : function( record_id, key, value ){
                >
                > var row_data = this.getRecord( record_id ).getData(),
                > merged_data = row_data[ STRING_STATENAME ] || {};
                >
                > merged_data[ key ] = value;
                >
                > this.getRecord( record_id ).setData( STRING_STATENAME, merged_data );
                >
                > return merged_data;
                >
                > },
                >
                > /////////////////////////////////////////////////////////////////////////////
                > //
                > // Public methods
                > //
                > /////////////////////////////////////////////////////////////////////////////
                >
                > /**
                > * Over-ridden initAttributes method from DataTable
                > * @method initAttributes
                > * @param {Mixed} record_id Record / Row / or Index id
                > * @param {String} key Key to use in map
                > * @param {Mixed} value Value to assign to the key
                > * @return {Object} State data object
                > * @type mixed
                > **/
                > initAttributes : function( oConfigs ) {
                >
                > oConfigs = oConfigs || {};
                >
                > YAHOO.widget.ExpandableDataTable.superclass.initAttributes.call(this,
                > oConfigs);
                >
                > /**
                > * @attribute rowExpansionTemplate
                > * @description Value for the rowExpansionTemplate attribute.
                > * @type {Mixed}
                > * @default ""
                > **/
                > this.setAttributeConfig("rowExpansionTemplate", {
                > value: "",
                > validator: function( template ){
                > return (
                > YAHOO.lang.isString( template ) ||
                > YAHOO.lang.isFunction( template )
                > );
                > },
                > method: this.initRowExpansion
                > });
                >
                > },
                >
                > /**
                > * Initializes row expansion on the DataTable instance
                > * @method initRowExpansion
                > * @param {Mixed} template a string template or function to be called when
                > * Row is expanded
                > * @type mixed
                > **/
                > initRowExpansion : function( template ){
                >
                > //Set subscribe restore method
                > this.subscribe( 'postRenderEvent', this.onEventRestoreRowExpansion );
                >
                > //Setup template
                > this.rowExpansionTemplate = template;
                >
                > //Set table level state
                > this.a_rowExpansions = [];
                >
                > },
                >
                > /**
                > * Toggles the expansion state of a row
                > * @method toggleRowExpansion
                > * @param {Mixed} record_id Record / Row / or Index id
                > * @type mixed
                > **/
                > toggleRowExpansion : function( record_id ){
                >
                > var state = this._getRecordState( record_id );
                >
                > if( state && state.expanded ){
                >
                > this.collapseRow( record_id );
                >
                > } else {
                >
                > this.expandRow( record_id );
                >
                > }
                >
                > },
                >
                > /**
                > * Sets the expansion state of a row to expanded
                > * @method expandRow
                > * @param {Mixed} record_id Record / Row / or Index id
                > * @param {Boolean} restore will restore an exisiting state for a
                > * row that has been collapsed by a non user action
                > * @return {Boolean} successful
                > * @type mixed
                > **/
                > expandRow : function( record_id, restore ){
                >
                > var state = this._getRecordState( record_id );
                >
                > if( !state.expanded || restore ){
                >
                > var row_data = this.getRecord( record_id ),
                > row = this.getRow( row_data ),
                > new_row = document.createElement('tr'),
                > column_length = this.getFirstTrEl().childNodes.length,
                > expanded_data = row_data.getData(),
                > expanded_content = null,
                > template = this.rowExpansionTemplate,
                > next_sibling = Dom.getNextSibling( row );
                >
                > //Construct expanded row body
                > new_row.className = CLASS_EXPANSION;
                > var new_column = document.createElement( 'td' );
                > new_column.colSpan = column_length;
                >
                > new_column.innerHTML = '<div class="'+ CLASS_LINER +'"></div>';
                > 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
                > * @type mixed
                > **/
                > 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
                > * @type mixed
                > **/
                > 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 ] );
                >
                > }
                >
                > 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
                > * @type mixed
                > **/
                > 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
                > * @type mixed
                > **/
                > 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
                > * @type mixed
                > **/
                > onEventToggleRowExpansion : function( oArgs ){
                >
                > //if( YAHOO.util.Dom.hasClass( oArgs.target,
                > 'yui-dt-expandablerow-trigger' ) ){
                >
                > this.toggleRowExpansion( oArgs.target );
                >
                > //}
                >
                > }
                >
                > }, true //This boolean is needed to override members of the original
                > object
                > );
                >
                > })();
                >
                > Best regards,
                > Christian Tiberg
                >
                >
                > 2009/11/1 Christian Tiberg <ctiberg@... <mailto:ctiberg@...>>

                >
                > Thanks a lot Satyam, that's exactly what I needed!
                >
                > Best regards,
                > Christian Tiberg
                >
                >
                > 2009/10/30 Satyam <satyam@...
                > <mailto:satyam@...>>

                >
                > So, first you declare the constructor of your new table, say:
                >
                > YAHOO.widget.ExpandableDataTable = function () {
                >
                > YAHOO.widget.ExpandableDataTable.superclass.constructor.apply(this,arguments);
                >
                > };
                >
                > If you want to manipulate any of the arguments, name them and
                > use call
                > instead of apply providing your altered arguments. The example
                > code
                > does not do anything with the initial arguments. Then:
                >
                > YAHOO.lang.extend(YAHOO.widget.ExpandableDataTable,
                > YAHOO.widget.DataTable, {
                >
                > initAttributes: function (oConfigs ) {
                >
                > oConfigs = oConfigs || {};
                >
                > YAHOO.widget.ExpandableDataTable.superclass.initAttributes.call(this,
                > oConfigs);
                >
                > // add your own attributes here
                >
                > },
                >
                > // add your own methods and properties here
                >
                > // for methods, remember to call the superclass method, unless
                > you really don't want it
                >
                > });
                >
                >
                >
                >
                >
                >
                > ----------------------------------------------------------
                >
                >
                > No virus found in this incoming message.
                > Checked by AVG - www.avg.com
                > Version: 8.5.423 / Virus Database: 270.14.40/2471 - Release Date: 10/31/09 07:53:00
                >
                >


              • Satyam
                Not quite, that one is meant for a test case showing the bug, if that were the case. Anyway, I added a comment with the same URL. Thanks Satyam
                Message 7 of 10 , Nov 3, 2009
                  Not quite, that one is meant for a test case showing the bug, if that
                  were the case. Anyway, I added a comment with the same URL.

                  Thanks

                  Satyam

                  Christian Tiberg escribió:
                  >
                  >
                  > That's now done. Did I put the URL in the right place?
                  >
                  > Best regards,
                  > Christian Tiberg
                  >
                  >
                  > 2009/11/1 Satyam <satyam@... <mailto:satyam@...>>
                  >
                  >
                  >
                  > I filed a ticket for the example:
                  >
                  > http://yuilibrary.com/projects/yui2/ticket/2528595
                  >
                  > Why don't you upload your code to GIST (or any other way to make it
                  > public) and make a reference to it from this same ticket.
                  >
                  > Thanks for your help
                  >
                  > Satyam
                  >
                  > Christian Tiberg escribió:
                  >
                  >
                  > >
                  > >
                  > > Here's the finished class, perhaps someone could update the
                  > example?
                  > > Then other people won't have to go through this :)
                  > >
                  > > (function(){
                  > > var Dom = YAHOO.util.Dom,
                  > > STRING_STATENAME = 'yui_dt_state',
                  > > CLASS_EXPANDED = 'yui-dt-expanded',
                  > > CLASS_COLLAPSED = 'yui-dt-collapsed',
                  > > CLASS_EXPANSION = 'yui-dt-expansion',
                  > > CLASS_LINER = 'yui-dt-liner',
                  > >
                  > > //From YUI 3
                  > > indexOf = function(a, val) {
                  > > for (var i=0; i<a.length; i=i+1) {
                  > > if (a[i] === val) {
                  > > return i;
                  > > }
                  > > }
                  > >
                  > > return -1;
                  > > };
                  > >
                  > > YAHOO.widget.ExpandableDataTable = function()
                  > > {
                  > >
                  > YAHOO.widget.ExpandableDataTable.superclass.constructor.apply(this,arguments);
                  > > }
                  > >
                  > > YAHOO.lang.extend(YAHOO.widget.ExpandableDataTable,
                  > > YAHOO.widget.DataTable, {
                  > >
                  > >
                  > /////////////////////////////////////////////////////////////////////////////
                  > > //
                  > > // Private members
                  > > //
                  > >
                  > /////////////////////////////////////////////////////////////////////////////
                  > >
                  > > /**
                  > > * Gets state object for a specific record associated with the
                  > DataTable.
                  > > * @method _getRecordState
                  > > * @param {Mixed} record_id Record / Row / or Index id
                  > > * @param {String} key Key to return within the state object.
                  > Default is to
                  > > * return all as a map
                  > > * @return {Object} State data object
                  > > * @type mixed
                  > > * @private
                  > > **/
                  > > _getRecordState : function( record_id, key ){
                  > >
                  > > var row_data = this.getRecord( record_id ),
                  > > row_state = row_data.getData( STRING_STATENAME ),
                  > > state_data = ( row_state && key ) ? row_state[ key ] : row_state;
                  > >
                  > > return state_data || {};
                  > >
                  > > },
                  > >
                  > > /**
                  > > * Sets a value to a state object with a unique id for a record which
                  > > * is associated with the DataTable
                  > > * @method _setRecordState
                  > > * @param {Mixed} record_id Record / Row / or Index id
                  > > * @param {String} key Key to use in map
                  > > * @param {Mixed} value Value to assign to the key
                  > > * @return {Object} State data object
                  > > * @type mixed
                  > > * @private
                  > > **/
                  > > _setRecordState : function( record_id, key, value ){
                  > >
                  > > var row_data = this.getRecord( record_id ).getData(),
                  > > merged_data = row_data[ STRING_STATENAME ] || {};
                  > >
                  > > merged_data[ key ] = value;
                  > >
                  > > this.getRecord( record_id ).setData( STRING_STATENAME,
                  > merged_data );
                  > >
                  > > return merged_data;
                  > >
                  > > },
                  > >
                  > >
                  > /////////////////////////////////////////////////////////////////////////////
                  > > //
                  > > // Public methods
                  > > //
                  > >
                  > /////////////////////////////////////////////////////////////////////////////
                  > >
                  > > /**
                  > > * Over-ridden initAttributes method from DataTable
                  > > * @method initAttributes
                  > > * @param {Mixed} record_id Record / Row / or Index id
                  > > * @param {String} key Key to use in map
                  > > * @param {Mixed} value Value to assign to the key
                  > > * @return {Object} State data object
                  > > * @type mixed
                  > > **/
                  > > initAttributes : function( oConfigs ) {
                  > >
                  > > oConfigs = oConfigs || {};
                  > >
                  > >
                  > YAHOO.widget.ExpandableDataTable.superclass.initAttributes.call(this,
                  > > oConfigs);
                  > >
                  > > /**
                  > > * @attribute rowExpansionTemplate
                  > > * @description Value for the rowExpansionTemplate attribute.
                  > > * @type {Mixed}
                  > > * @default ""
                  > > **/
                  > > this.setAttributeConfig("rowExpansionTemplate", {
                  > > value: "",
                  > > validator: function( template ){
                  > > return (
                  > > YAHOO.lang.isString( template ) ||
                  > > YAHOO.lang.isFunction( template )
                  > > );
                  > > },
                  > > method: this.initRowExpansion
                  > > });
                  > >
                  > > },
                  > >
                  > > /**
                  > > * Initializes row expansion on the DataTable instance
                  > > * @method initRowExpansion
                  > > * @param {Mixed} template a string template or function to be
                  > called when
                  > > * Row is expanded
                  > > * @type mixed
                  > > **/
                  > > initRowExpansion : function( template ){
                  > >
                  > > //Set subscribe restore method
                  > > this.subscribe( 'postRenderEvent',
                  > this.onEventRestoreRowExpansion );
                  > >
                  > > //Setup template
                  > > this.rowExpansionTemplate = template;
                  > >
                  > > //Set table level state
                  > > this.a_rowExpansions = [];
                  > >
                  > > },
                  > >
                  > > /**
                  > > * Toggles the expansion state of a row
                  > > * @method toggleRowExpansion
                  > > * @param {Mixed} record_id Record / Row / or Index id
                  > > * @type mixed
                  > > **/
                  > > toggleRowExpansion : function( record_id ){
                  > >
                  > > var state = this._getRecordState( record_id );
                  > >
                  > > if( state && state.expanded ){
                  > >
                  > > this.collapseRow( record_id );
                  > >
                  > > } else {
                  > >
                  > > this.expandRow( record_id );
                  > >
                  > > }
                  > >
                  > > },
                  > >
                  > > /**
                  > > * Sets the expansion state of a row to expanded
                  > > * @method expandRow
                  > > * @param {Mixed} record_id Record / Row / or Index id
                  > > * @param {Boolean} restore will restore an exisiting state for a
                  > > * row that has been collapsed by a non user action
                  > > * @return {Boolean} successful
                  > > * @type mixed
                  > > **/
                  > > expandRow : function( record_id, restore ){
                  > >
                  > > var state = this._getRecordState( record_id );
                  > >
                  > > if( !state.expanded || restore ){
                  > >
                  > > var row_data = this.getRecord( record_id ),
                  > > row = this.getRow( row_data ),
                  > > new_row = document.createElement('tr'),
                  > > column_length = this.getFirstTrEl().childNodes.length,
                  > > expanded_data = row_data.getData(),
                  > > expanded_content = null,
                  > > template = this.rowExpansionTemplate,
                  > > next_sibling = Dom.getNextSibling( row );
                  > >
                  > > //Construct expanded row body
                  > > new_row.className = CLASS_EXPANSION;
                  > > var new_column = document.createElement( 'td' );
                  > > new_column.colSpan = column_length;
                  > >
                  > > new_column.innerHTML = '<div class="'+ CLASS_LINER +'"></div>';
                  > > 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
                  > > * @type mixed
                  > > **/
                  > > 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
                  > > * @type mixed
                  > > **/
                  > > 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 ] );
                  > >
                  > > }
                  > >
                  > > 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
                  > > * @type mixed
                  > > **/
                  > > 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
                  > > * @type mixed
                  > > **/
                  > > 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
                  > > * @type mixed
                  > > **/
                  > > onEventToggleRowExpansion : function( oArgs ){
                  > >
                  > > //if( YAHOO.util.Dom.hasClass( oArgs.target,
                  > > 'yui-dt-expandablerow-trigger' ) ){
                  > >
                  > > this.toggleRowExpansion( oArgs.target );
                  > >
                  > > //}
                  > >
                  > > }
                  > >
                  > > }, true //This boolean is needed to override members of the
                  > original
                  > > object
                  > > );
                  > >
                  > > })();
                  > >
                  > > Best regards,
                  > > Christian Tiberg
                  > >
                  > >
                  > > 2009/11/1 Christian Tiberg <ctiberg@...
                  > <mailto:ctiberg%40gmail.com> <mailto:ctiberg@...
                  > <mailto:ctiberg%40gmail.com>>>
                  >
                  > >
                  > > Thanks a lot Satyam, that's exactly what I needed!
                  > >
                  > > Best regards,
                  > > Christian Tiberg
                  > >
                  > >
                  > > 2009/10/30 Satyam <satyam@...
                  > <mailto:satyam%40satyam.com.ar>
                  > > <mailto:satyam@... <mailto:satyam%40satyam.com.ar>>>
                  >
                  > >
                  > > So, first you declare the constructor of your new table, say:
                  > >
                  > > YAHOO.widget.ExpandableDataTable = function () {
                  > >
                  > >
                  > YAHOO.widget.ExpandableDataTable.superclass.constructor.apply(this,arguments);
                  > >
                  > > };
                  > >
                  > > If you want to manipulate any of the arguments, name them and
                  > > use call
                  > > instead of apply providing your altered arguments. The example
                  > > code
                  > > does not do anything with the initial arguments. Then:
                  > >
                  > > YAHOO.lang.extend(YAHOO.widget.ExpandableDataTable,
                  > > YAHOO.widget.DataTable, {
                  > >
                  > > initAttributes: function (oConfigs ) {
                  > >
                  > > oConfigs = oConfigs || {};
                  > >
                  > >
                  > YAHOO.widget.ExpandableDataTable.superclass.initAttributes.call(this,
                  > > oConfigs);
                  > >
                  > > // add your own attributes here
                  > >
                  > > },
                  > >
                  > > // add your own methods and properties here
                  > >
                  > > // for methods, remember to call the superclass method, unless
                  > > you really don't want it
                  > >
                  > > });
                  > >
                  > >
                  > >
                  > >
                  > >
                  > >
                  > > ----------------------------------------------------------
                  > >
                  > >
                  > > No virus found in this incoming message.
                  > > Checked by AVG - www.avg.com <http://www.avg.com>
                  > > Version: 8.5.423 / Virus Database: 270.14.40/2471 - Release
                  > Date: 10/31/09 07:53:00
                  > >
                  > >
                  >
                  >
                  >
                  >
                  >
                  > ------------------------------------------------------------------------
                  >
                  >
                  > No virus found in this incoming message.
                  > Checked by AVG - www.avg.com
                  > Version: 9.0.698 / Virus Database: 270.14.46/2477 - Release Date: 11/02/09 20:39:00
                  >
                  >
                Your message has been successfully submitted and would be delivered to recipients shortly.