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

Expandable DataTable unsortable?

Expand Messages
  • Christian Tiberg
    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
    Message 1 of 10 , Oct 30, 2009
    • 0 Attachment
      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
    • Christian Tiberg
      The line below YAHOO.widget.DataTable.superclass.initAttributes.call( this, oConfigs ); tries to do something nice, i.e. call the inherited method to init
      Message 2 of 10 , Oct 30, 2009
      • 0 Attachment
        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@...>
        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

      • Christian Tiberg
        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,
        Message 3 of 10 , Oct 30, 2009
        • 0 Attachment
          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@...>
          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@...>

          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


        • 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 4 of 10 , Oct 30, 2009
          • 0 Attachment
            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 5 of 10 , Oct 30, 2009
            • 0 Attachment
              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 6 of 10 , Nov 1, 2009
              • 0 Attachment
                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 7 of 10 , Nov 1, 2009
                • 0 Attachment
                  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 8 of 10 , Nov 1, 2009
                  • 0 Attachment
                    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 9 of 10 , Nov 3, 2009
                    • 0 Attachment
                      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 10 of 10 , Nov 3, 2009
                      • 0 Attachment
                        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.