// TemplateName=list_component.js
// $Header: /home/cvs/cvsroot/site_data/001/00000001/static_data/js/list_component.js,v 1.2 2004/06/11 18:37:42 kimberly Exp $

// The lc_* functions support the list component ability to hide or show columns.
// As soon as all customized page wrappers get upgraded to 3.8, then this section
// (which is duplicated in user_wrapper.js) should be separated out into a new
// 'list_component.js' file.

// The lcColFilter objects are created in the template for each table
// and have information specific to each instance.
function lcColFilter (table_id, param_name, hidden_cols, has_extra_col) {
   this.tableId = table_id;
   this.paramName = param_name;
   this.hiddenCols = (hidden_cols != null) ? hidden_cols.split ('_') : new String[0];
   this.hasExtraCol = has_extra_col;
}

// This is the main entry point to hide or show a column.
// It can be called in response to users' actions.
//
//    colFilter is the lcColFilter instance for the table
//    origin is the element within the table initiating the invocation
//    colNum is the index of the column to be hidden or shown
//    hideIt indicates whether to hide or show the column
function lc_hideOrShowCol (colFilter, origin, colNum, hideIt) {
   var table = null;
   var parent = origin;

   if (colNum == '')
      return;

   if (hideIt == null)
      hideIt = true;

   // Search up the DOM to find enclosing lc_Table
   while ((parent != null) && (table == null)) {
      if (parent.nodeName == 'TABLE') {
         var att = parent.attributes;
         var cls = (att != null) ? att.getNamedItem ('class') : null;

         if ((cls != null) && (cls.nodeValue == 'lc_Table'))
            table = parent;
         else
            parent = parent.parentNode;
      }
      else
         parent = parent.parentNode;
   }

   // If table not found, look for it by ID.
   if (table == null) {
      table = document.getElementById (colFilter.tableId);
   }

   // If the table was found, hide or show the column
   if (table != null) {

      // column header
      var ths = table.getElementsByTagName ('TH');
      var hdrNum = ((colNum - 1) * 2);

      if (colFilter.hasExtraCol)
         hdrNum--;

      lc_hideOrShowNode (ths, hdrNum, hideIt);
      lc_toggleHdr (ths, (hdrNum + 1), hideIt);

      // I first found the TDs to hide by going through the rows, getting the
      // array of TDs for each row, and then invoking the lc_hideOrShowNode
      // method using the colNum index.  But that failed with IE6 on the initial
      // load of the page (it worked when the user clicked on the hide or show
      // icons).
      // So this approach of getting all TDs and finding the appropriate ones
      // based on their ID fixed that.
      var tds = table.getElementsByTagName ('TD');
      var cellIdRegex = 'lc_cell_[0-9]*_' + (colNum - 1);

      for (var t = 0; t < tds.length; t++) {
         var td = tds.item(t);

         if (td != null) {
            var tdAttrs = td.attributes;

            if (tdAttrs != null) {
               var idAttr = (tdAttrs != null) ? tdAttrs.getNamedItem ('id') : null;

               if ((idAttr != null) && (idAttr.value != null) && idAttr.value.match (cellIdRegex))
                  lc_hideOrShowNode (tds, t, hideIt);
            }
         }
      }

      // Update the variables that track which columns are hidden.
      // Also update any links in the page that contain the column filter.
      if (hideIt) {
         var found = false;

         // First, make sure it isn't already in the list of hidden columns.
         // It shouldn't be, but this helps prevent unnecessary processing.
         for (var c = 0; ((found == false) && (c < colFilter.hiddenCols .length)); c++) {
            if (colFilter.hiddenCols[c] == colNum)
               found = true;
         }

         if (found == false) {
            colFilter.hiddenCols[colFilter.hiddenCols.length] = colNum;
            lc_update_filter_in_links (colFilter.paramName, colFilter.hiddenCols);
         }
      }
      // Show the column (remove it from the filter)
      else {
         // Remove all references to this column number in the list of hidden
         // columns.  There should just be one.
         for (var c = 0; (c < colFilter.hiddenCols.length); ) {
            if (colFilter.hiddenCols[c] == colNum)
               colFilter.hiddenCols.splice (c, 1);
            else
               c++;
         }

         lc_update_filter_in_links (colFilter.paramName, colFilter.hiddenCols);
      }
   }
}

// This method updates the visual elements in the column header to reflect
// the new state (shown / hidden) of the column.
//   hdrList is a list of all header items.
//   hdrNum is the index of the header item to be changed.
//   hideIt indicates whether the column is being hidden or shown.
function lc_toggleHdr (hdrList, hdrNum, hideIt) {
   if (hdrList.length > hdrNum) {
      var hdr = hdrList.item(hdrNum);

      if (hdr != null) {
         // This is a dependency on list_component_header.tpt.
         // The hide / show images are within anchors ('<a ...>') to trick
         // NS & Mozilla into rendering their ALT text as fly-over text.
         var imgs = hdr.getElementsByTagName ('A');

         for (var i = 0; (i < imgs.length); i++) {
            var img = imgs.item(i);

            if (img != null) {
               // When hiding, show the link/image for showing and hide everything else.
               var name = img.getAttribute ('name');

               if ((name != null) && (name == 'lc_open')) {
                  if (hideIt)
                     lc_showNode (img);
                  else
                     lc_hideNode (img);
               }
               // When showing, hide the link/image for showing and show everything else.
               else {
                  if (hideIt)
                     lc_hideNode (img);
                  else
                     lc_showNode (img);
               }
            }
         }
      }
   }
}

// This method hides or shows a DOM node by hiding or showing all of the
// children of the node.  The node itself is not changed so that its
// background, borders, etc. are not removed.
//   nodeList is a list of all nodes.
//   nodeNum is the index of the node to be changed.
//   hideIt indicates whether the column is being hidden or shown.
function lc_hideOrShowNode (nodeList, nodeNum, hideIt) {
   if (nodeList.length > nodeNum) {
      var node = nodeList.item(nodeNum);

      if (node != null) {
         var children = node.childNodes;

         for (var n = 0; n < children.length; n++) {
            var child = children.item(n);

            if (child != null) {
               var attrs = child.attributes;
               var attrClass = (attrs != null) ? attrs.getNamedItem ('class') : null;

               if ((attrClass != null) && (attrClass.nodeValue == 'lc_empty')) {
                  if (hideIt)
                     lc_showNode (child);
                  else
                     lc_hideNode (child);
               }
               else {
                  if (hideIt)
                     lc_hideNode (child);
                  else
                     lc_showNode (child);
               }
            }
         }
      }
   }
}

// This hides a node by setting its 'display' style to 'none'.
function lc_hideNode (node) {
   if ((node != null) && (node.style != null)) {
      if ((node.style.display == null) || (node.style.display == ''))
         node.style.display = 'none';
   }
}

// This shows a node by setting its 'display' style to '' if it is 'none'.
function lc_showNode (node) {
   if ((node != null) && (node.style != null)) {
      if (node.style.display == 'none')
         node.style.display = '';
   }
}

// This method updates all links in the page that contain the column filter
// parameter.
// It also updates the similarly named hidden field, if it exists.
function lc_update_filter_in_links (param_name, col_f_array) {
   var links = document.getElementsByTagName ('A');
   var regex = new RegExp ("(" + param_name + "=)[0-9_]*");
   var filter_string = col_f_array.join ('_');

   for (var a = 0; (a < links.length); a++) {
      var href = links[a].getAttribute ('HREF');

      if (href != null) {
         // If the filter parameter is already in the URL,
         // then change its value.
         if (href.match (regex))
            href = href.replace (regex, '$1' + filter_string);

         // otherwise, add the parameter and value to the URL
         else if (href.match ('^http'))
            href = appendToUrl (href, param_name, filter_string);
         else
            href = null;

         // Mozilla doesn't care about case, but IE6 seems to.
         if (href != null) {
            links[a].setAttribute ('HREF', href);
            links[a].setAttribute ('href', href);
         }
      }
   }

   // Update the hidden field
   var hidden = document.getElementById (param_name);

   if (hidden != null) {
      hidden.value = filter_string;
   }
}

// This method is for initializing the columns according to the current
// filter.  It assumes that all columns are displayed and only takes action
// to hide the ones that are supposed to be hidden.
function lc_init_cols (colFilter) {
   if (colFilter.hiddenCols != null) {
      var tbl = document.getElementById (colFilter.tableId);

      for (var c = 0; (c < colFilter.hiddenCols.length); c++) {
         lc_hideOrShowCol (colFilter, tbl, colFilter.hiddenCols[c], true);
      }
   }
}

// Returns the HTML for the expand/collapse images to be inserted into the
// document.
function lc_write_toggle_images (openTitle, closeTitle, filterSuffix, columnNumber) {
   var str = '';

   // the anchors around the images are a trick to make NS render the tool tips -->
   if (openTitle != null) {
      str += '<a class="TableImageLinks" name="lc_open" title="'
             + openTitle
             + '" style="display: none;"><img src="../images/open_pane2.gif" border="0" alt="'
             + openTitle
             + '" onClick="lc_hideOrShowCol(lc_col_filter_'
             + filterSuffix
             + ', this, '
             + columnNumber
             + ', false); return false;" /></a>\n';
   }

   if (closeTitle != null) {
      str += '<a class="TableImageLinks" name="lc_close" title="'
            + closeTitle
            + '"><img src="../images/close_pane2.gif" border="0" alt="'
            + closeTitle
            + '" onClick="lc_hideOrShowCol(lc_col_filter_'
            + filterSuffix
            + ', this, '
            + columnNumber
            + ', true); return false;" /></a>\n';
   }

   return str;
}

