Jump to content

User:Icqa/Collapsing.js

From Wikipedia, the free encyclopedia
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/*
== Actual code ==
<source lang="javascript">
*/
function collapseTable( tableIndex ) {
  var Button = document.getElementById( 'collapseButton' + tableIndex );
  var Table = document.getElementById( 'collapsibleTable' + tableIndex );
  if ( !Table || !Button ) {
    return false;
  }

  var collapseColsOptin  = hasCollapsibleCol( tableIndex ); // new
  var collapseColsOptout = hasNoncollapsibleCol( tableIndex ); // new
  var Cols = Table.rows[0].cells; // new
  var CollapseCols = new Array(Cols.length); // new; has to be larger if there are colspans

  if ( collapseColsOptin || collapseColsOptout ) {// new
    //  @colspan currently not handled
    // the following two if-for-if constructs could be combined
    if ( collapseColsOptin ) {
      for ( var i = 0; i < Cols.length; i++ ) {
        if ( CollapseCols[i] == null || !hasClass( Cols[i], 'collapsible' ) ) {
          CollapseCols[i] = !collapseColsOptin;
        } else {
          CollapseCols[i] = collapseColsOptin;
        }
      }
    }
    // 'nocollapse' takes precedence over 'collapsible', i.e.
    // default columns are not collapsible when both types exist
    if ( collapseColsOptout ) {
      for ( var i = 0; i < Cols.length; i++ ) {
        if ( CollapseCols[i] == null || !hasClass( Cols[i], 'nocollapse' ) ) {
          CollapseCols[i] = collapseColsOptout;
        } else {
          CollapseCols[i] = !collapseColsOptout;
        }
      }
    }

    // column with first |th| should be excluded, because it holds the show/hide button
    var Header = Table.rows[0].getElementsByTagName( 'th' )[0];
    CollapseCols[Header.cellIndex] = false;// cellIndex doesn’t handle @colspan
  }

  var Rows = Table.rows;

  // insert check for @colspan here, change CollapseCols accordingly

  if ( Button.firstChild.data == collapseCaption ) {// hide

    if ( collapseColsOptin || collapseColsOptout ) {// new
      for ( var i = 0; i < Rows.length; i++ ) {
        var Cells = Rows[i].cells;
        for ( var j = 0; j < CollapseCols.length; j++) {
          // if we used Cells.length the handling of rows with empty cells at the end should improve
          // this would be a problem if the header row had empty cells at the end
          // we could also do CollapseCols.length-Cells.length times Rows[i].insertCell(-1) 
          if ( CollapseCols[j] ) {
            Cells[j].style.display = 'none';// needs to take @colspan into account
          }
        }
      }
    }

    var collapseRowsOptin = hasCollapsibleRow( tableIndex );// new
    // @rowspan currently not handled
    for ( var i = 1; i < Rows.length; i++ ) {
      if ( collapseRowsOptin ) {// new
        if ( hasClass( Rows[i], 'collapsible' ) ) {
          Rows[i].style.display = 'none';
        }
       } else if ( !collapseColsOptin && !collapseColsOptout ) {
        if ( !hasClass( Rows[i], 'nocollapse' ) &&
             !( hasClass( Rows[i], 'sortbottom' ) && !hasClass( Rows[i], 'collapsible' ) )
           ) { // new condition to exclude certain rows from collapsing
          Rows[i].style.display = 'none';
        }
      }
    }

    Button.firstChild.data = expandCaption;

  } else {// show

    for ( var i = 0; i < Rows.length; i++ ) {

      if ( collapseColsOptin || collapseColsOptout ) {// new
        var Cells = Rows[i].cells;
        for ( var j = 0; j < CollapseCols.length; j++) {
          if ( CollapseCols[j] ) {
            Cells[j].style.display = Rows[0].style.display;
          }
        }
      }

      Rows[i].style.display = Rows[0].style.display;
    }

    Button.firstChild.data = collapseCaption;

  }
}

/* new function to check whether the collapsible table has 
 * any column with the class 'collapsible'
 */
function hasCollapsibleCol( tableIndex ) {
  var Table = document.getElementById( 'collapsibleTable' + tableIndex );
  if ( !Table ) {
    return false;
  }
  var Cols = Table.rows[0].cells;

  for ( var i = 0; i < Cols.length; i++ ) {
    if ( hasClass( Cols[i], 'collapsible' ) ) {
      return true;
    }
  }
  return false;
}

/* new function to check whether the collapsible table has 
 * any column with the class 'nocollapse'
 */
function hasNoncollapsibleCol( tableIndex ) {
  var Table = document.getElementById( 'collapsibleTable' + tableIndex );
  if ( !Table ) {
    return false;
  }
  var Cols = Table.rows[0].cells;

  for ( var i = 0; i < Cols.length; i++ ) {
    if ( hasClass( Cols[i], 'nocollapse' ) ) {
      return true;
    }
  }
  return false;
}

/* new function to check whether the collapsible table has 
 * any row (except the header) with the class 'collapsible'
 */
function hasCollapsibleRow( tableIndex ) {
  var Table = document.getElementById( 'collapsibleTable' + tableIndex );
  if ( !Table ) {
    return false;
  }
  var Rows = Table.rows;

  for ( var i = 1; i < Rows.length; i++ ) {
    if ( hasClass( Rows[i], 'collapsible' ) ) {
      return true;
    }
  }
  return false;
}
// </source>