Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Add a Tree Menu to DataGrid Header Text

, 9 Nov 2005
This article shows how to add a JavaScript tree menu to a DataGrid head text.
/*
This version of jsDomenu downloaded from Dynamic Drive (http://www.dynamicdrive.com)
Modified by DD to auto detect doctype mode in IE and adjust webPageMode variable
Visit http://www.dynamicdrive.com for full script
*/

var menuCount = 0;
var itemCount = 0;

if (disallowedTags == undefined) {
  var disallowedTags = ["A", "BUTTON", "IMG", "INPUT", "OBJECT", "OPTION", "SELECT", "TEXTAREA", "FONT"];
}

if (menuClass == undefined) {
  var menuClass = "jsdomenudiv";
}

if (itemClass == undefined) {
  var itemClass = "jsdomenuitem";
}

if (itemClassOver == undefined) {
  var itemClassOver = "jsdomenuitemover";
}

if (hrClass == undefined) {
  var hrClass = "jsdomenuhr";
}

if (arrowClass == undefined) {
  var arrowClass = "jsdomenuarrow";
}

if (imgSrc == undefined) {
  var imgSrc = "SCRIPT/arrowLTR.gif";
}

if (imgSrcOver == undefined) {
  var imgSrcOver = "SCRIPT/arrowLTR.gif";
 // alert(imgSrcOver);
}

if (webPageMode == undefined) {
	var webPageMode=(document.all && !window.opera && document.compatMode && document.compatMode!="BackCompat")? 1 : 0 //DD added line
}

function getElm(id) {
  return document.getElementById(id);
}

function getTags(tagName) {
  return document.getElementsByTagName(tagName);
}

function createElm(tagName) {
  return document.createElement(tagName);
}

function appendChild(id, elm) {
  var divElm = getElm(id);
  divElm.appendChild(elm);
}

function isIE() {
  return (navigator.userAgent.indexOf("MSIE") > -1);
}

function isGecko() {
  return (navigator.userAgent.indexOf("Gecko") > -1);
}

function getX(e) {
  if (isGecko()) {
    return e.clientX;
  }
  else {
    return window.event.x;
  }
}

function getY(e) {
  if (isGecko()) {
    return e.clientY;
  }
  else {
    return window.event.y;
  }
}

function checkTag(tagName) {
  for (i = 0; i < disallowedTags.length; i++) {
    if (tagName == disallowedTags[i]) {
      return true;
    }
  }
  return false;
}

function getBorderOffset(elm) {
  return (parseInt(elm.style.borderTopWidth.slice(0, -2)) + parseInt(elm.style.borderBottomWidth.slice(0, -2)))
}

function getScrollLeft() {
  switch (webPageMode) {
    case 0:
      return document.body.scrollLeft;
    case 1:

      if (isIE()) {
        return document.documentElement.scrollLeft;
      }
      else {
        return document.body.scrollLeft;
      }
    case 2:
      return document.body.scrollLeft;
  }
}

function getScrollTop() {
  switch (webPageMode) {
    case 0:
      return document.body.scrollTop;
    case 1:
      if (isIE()) {
        return document.documentElement.scrollTop;
      }
      else {
        return document.body.scrollTop;
      }
    case 2:
      return document.body.scrollTop;
  }
}

function getClientHeight() {
  switch (webPageMode) {
    case 0:
      return document.body.clientHeight;
    case 1:
      if (isIE()) {
        return document.documentElement.clientHeight;
      }
      else {
        return document.body.clientHeight;
      }
    case 2:
      return document.body.clientHeight;
  }
}

function getClientWidth() {
  switch (webPageMode) {
    case 0:
      return document.body.clientWidth;
    case 1:
      if (isIE()) {
        return document.documentElement.clientWidth;
      }
      else {
        return document.body.clientWidth;
      }
    case 2:
      return document.body.clientWidth;
  }
}

function getMainLeftPos(divElm, x) {
  if ((x + divElm.offsetWidth) <= getClientWidth()) {
    return x;
  }
  else {
    if (x <= getClientWidth()) {
      return (x - divElm.offsetWidth);
    }
    else {
      return (getClientWidth() - divElm.offsetWidth);
    }
  }
}

function getMainTopPos(divElm, y) {
  if ((y + divElm.offsetHeight) <= getClientHeight()) {
    return y;
  }
  else {
    if (y <= getClientHeight()) {
      return (y - divElm.offsetHeight);
    }
    else {
      return (getClientHeight() - divElm.offsetHeight);
    }
  }
}

function getSubLeftPos(divElm, x, offset) {
  if ((x + divElm.offsetWidth - 3) <= getClientWidth()) {
    return (x - 3);
  }
  else {
    if (x <= getClientWidth()) {
      return (x - divElm.offsetWidth - offset);
    }
    else {
      return (getClientWidth() - divElm.offsetWidth);
    }
  }
}

function getSubTopPos(divElm, y, offset) {
  if ((y + divElm.offsetHeight) <= getClientHeight()) {
    return y;
  }
  else {
    if (y <= getClientHeight()) {
      return (y - divElm.offsetHeight + offset);
    }
    else {
      return (getClientHeight() - divElm.offsetHeight + offset);
    }
  }
}

function popUpMainMenu(e, divElm) {
  divElm.style.left = (getMainLeftPos(divElm, getX(e)) + getScrollLeft()) + "px";
  divElm.style.top = (getMainTopPos(divElm, getY(e)) + getScrollTop()) + "px";
}

function popUpSubMenu(parent, menuItem, divElm) {
  divElm.style.left = (getSubLeftPos(divElm, (parent.offsetLeft + parent.offsetWidth - getScrollLeft()), menuItem.offsetWidth) + getScrollLeft()) + "px";
  divElm.style.top = (getSubTopPos(divElm, (parent.offsetTop + menuItem.offsetTop - getScrollTop()), (getBorderOffset(divElm) + menuItem.offsetHeight)) + getScrollTop()) + "px";
}

function showSubMenu() {
  popUpSubMenu(arguments[0].parent.properties, arguments[0], arguments[0].subMenu.properties);
  arguments[0].subMenu.properties.style.visibility = "visible";
}

function menuItemOver() {
  if (this.parent.previousItem) {
    if (this.parent.previousItem.className == this.parent.previousItem.classNameOver) {
        this.parent.previousItem.className = this.parent.previousItem.itemClass;
    }
    var divAll = getTags("div");    
    if (this.parent.previousItem.hasSubMenu) {
      this.parent.previousItem.className = this.parent.previousItem.itemClass;
      var imgElm = getElm(this.parent.previousItem.id + "Arrow");
      imgElm.src = this.parent.previousItem.imgSrc;
    }
    for (i = 0; i < divAll.length; i++) {
      if (divAll[i].id.indexOf("DOMenu") > -1) {
        if (divAll[i].level > this.parent.level) {
          with (divAll[i].style) {
            left = "0px";
            top = "0px";
            visibility = "hidden";
          }
          for (j = 0; j < divAll[i].childNodes.length; j++) {
            if (divAll[i].childNodes[j].enabled) {
              divAll[i].childNodes[j].className = divAll[i].childNodes[j].itemClass;
              if (divAll[i].childNodes[j].hasSubMenu) {
                var imgElm = getElm(divAll[i].childNodes[j].id + "Arrow");
                imgElm.src = divAll[i].childNodes[j].imgSrc;
              }
            }
          }
        }
      }
    }
  }
  if (this.enabled) {
    this.className = this.classNameOver;
    if (this.hasSubMenu) {
      var imgElm = getElm(this.id + "Arrow");
      imgElm.src = this.imgSrcOver;
      showSubMenu(this);
    }
  }
  this.parent.previousItem = this;
}

function menuItemOut() {
  if (this.enabled) {
    if (!((this.hasSubMenu) && (this.subMenu.properties.style.visibility == "visible"))) {
      this.className = this.itemClass;
    }
    if (this.hasSubMenu) {
      var imgElm = getElm(this.id + "Arrow");
      if (this.subMenu.properties.style.visibility == "visible") {
        imgElm.src = this.imgSrcOver;
      }
      else {
        imgElm.src = this.imgSrc;
      }
    }
  }
}

  

function menuItemClick() {
	//alert(this.displayText  + ' ' + this.target);
  if ((!this.hasSubMenu) && (this.enabled) && (this.target)) {
    var txtRange = window.document.body.createTextRange();
    txtRange = (txtRange.text).substring(0, (txtRange.text).length - 50);
    doClass(this.displayText,this.target);
  }
}
 
 
function setClassName(className) {
  if (this.itemClass) {
    this.itemClass = className;
    this.className = this.itemClass;
    return;
  }
  if (this.menuClass) {
    this.menuClass = className;
    this.properties.className = this.menuClass;
    return;
  }
}

function setArrowClassName(className) {
  if (this.subMenuItem) {
    this.arrowClass = className;
    this.subMenuItem.className = this.arrowClass;
    return
  }
}

function setImgSrc(imgSrc) {
  if (this.arrowItem) {
    this.imgSrc = imgSrc;
    this.arrowItem.src = this.imgSrc
  }
}

function setSubMenu() {
  var imgElm = createElm("img");
  imgElm.src = this.imgSrc;
  imgElm.id = this.id + "Arrow";
  var divElm = createElm("div");
  divElm.className = this.arrowClass;
  divElm.appendChild(imgElm);
  this.appendChild(divElm);
  this.hasSubMenu = true;
  this.subMenu = arguments[0];
  this.subMenuItem = divElm;
  this.arrowItem = imgElm
  this.setArrowClassName = setArrowClassName;
  this.setImgSrc = setImgSrc;
  arguments[0].properties.style.zIndex = this.parent.level + 1;
  arguments[0].level = this.parent.level + 1;
  arguments[0].properties.level = arguments[0].level;
}

function addMenuItem() {
  if (arguments[0].displayText == "-") {
    var hrElm = createElm("hr");
    hrElm.id = arguments[0].id;
    if (arguments[0].className.length > 0) {
      hrElm.hrClass = arguments[0].className;
    }
    else 
      if (arguments[0].hrClass.length > 0) {
        hrElm.hrClass = arguments[0].hrClass;
      }
      else {
        hrElm.hrClass = hrClass;
      }
    hrElm.className = hrElm.hrClass;
    appendChild(this.id, hrElm);
    hrElm.parent = this;
    hrElm.onmouseover = menuItemOver;
    if (arguments[0].itemName.length > 0) {
      this.items[arguments[0].itemName] = hrElm;
    }
    else {
      this.items[this.items.length] = hrElm;
    }
  }
  else {	 
    var divElm = createElm("div");
    divElm.id = arguments[0].id;
    divElm.target = arguments[0].target;
    divElm.enabled = arguments[0].enabled;
    divElm.itemClass = arguments[0].className;
    divElm.classNameOver = arguments[0].classNameOver;
    divElm.className = divElm.itemClass;
    divElm.hasSubMenu = false;
    divElm.subMenu = null;
    divElm.arrowClass = arrowClass;
    divElm.imgSrc = imgSrc;
    divElm.imgSrcOver = imgSrcOver;
    appendChild(this.id, divElm);
    var textNode = document.createTextNode(arguments[0].displayText);
    divElm.displayText = arguments[0].displayText; 
    appendChild(arguments[0].id, textNode);
    divElm.parent = this;
    divElm.setSubMenu = setSubMenu;
    divElm.setClassName = setClassName;
    divElm.onclick = menuItemClick;
    divElm.onmouseover = menuItemOver;
    divElm.onmouseout = menuItemOut;
    if (arguments[0].itemName.length > 0) {
      this.items[arguments[0].itemName] = divElm;
    }
    else {
      this.items[this.items.length] = divElm;
    }
  }
}

function menuItem() {
  this.id = "Item" + (++itemCount);
  this.displayText = arguments[0];
  this.itemName = "";
  this.target = "";
  this.enabled = true;
  if (this.displayText == "-") {
    this.className = hrClass;
  }
  else {
    this.className = itemClass;
  }
  //alert(this.displayText);
  this.hrClass = hrClass;
  this.classNameOver = itemClassOver;
  var length = arguments.length;
  if (length > 0) {
    if (arguments[0].length > 0) {
      this.displayText = arguments[0];
    }    
  } 
  if (length > 1) {
    if (arguments[1].length > 0) {
      this.itemName = arguments[1];
    }
  }
  if (length > 2) {
    if (arguments[2].length > 0) {
      this.target = arguments[2];
    }
  } 
 
}

function jsDOMenu() {
  this.id = "DOMenu" + (++menuCount);
  this.level = 10;
  this.items = new Array;
  this.previousItem = null;
  this.menuClass = menuClass;
  if (arguments.length > 1) {
    if (arguments[1].length > 0) {
      this.menuClass = arguments[1];
    }
  }
  var divElm = createElm("div");
  divElm.id = this.id;
  divElm.mainMenu = (menuCount == 1);
  divElm.level = this.level;
  divElm.className = this.menuClass;
  with (divElm.style) {
    width = arguments[0] + "px";
    left = "0px";
    top = "0px";
    borderWidth = "2px";
  }
  document.body.appendChild(divElm);
  this.properties = divElm;
  this.setClassName = setClassName;
  this.addMenuItem = addMenuItem;
}

function activatejsDOMenu(e) {
  if ((isIE()) && (checkTag(event.srcElement.tagName))) {
    return;
  }
  if ((isGecko()) && (checkTag(e.target.tagName))) {
    return;
  }
  var divAll = getTags("div");
  for (i = 0; i < divAll.length; i++) {
    if ((divAll[i].id.indexOf("DOMenu") > -1) && (divAll[i].mainMenu)) {
      var state = divAll[i].style.visibility;
      break;
    }
  }
  if (state == "visible") {
    for (i = 0; i < divAll.length; i++) {
      for (j = 0; j < divAll[i].childNodes.length; j++) {
        if (divAll[i].childNodes[j].enabled) {
          divAll[i].childNodes[j].className = divAll[i].childNodes[j].itemClass;
          if (divAll[i].childNodes[j].hasSubMenu) {
            var imgElm = getElm(divAll[i].childNodes[j].id + "Arrow");
            imgElm.src = divAll[i].childNodes[j].imgSrc;
          }
        }
      }
    }
  }
  for (i = 0; i < divAll.length; i++) {
    if (divAll[i].id.indexOf("DOMenu") > -1) {
      if (state == "visible") {
        divAll[i].style.visibility = "hidden";
      }
      else {
        if (divAll[i].mainMenu) {
          popUpMainMenu(e, divAll[i]);
          divAll[i].style.visibility = "visible";
          break;
        }
      }
    }
  }
  return false;
}

function adjustArrowPos() {
  if (isIE() && !window.opera) {
    divAll = getTags("div");
    for (i = 0; i < divAll.length; i++) {
      if (divAll[i].subMenuItem) {
        divAll[i].subMenuItem.style.marginTop = (parseInt(divAll[i].subMenuItem.currentStyle.marginTop.slice(0, -2)) + 3) + "px";
        divAll[i].subMenuItem.style.left = (parseInt(divAll[i].subMenuItem.currentStyle.left.slice(0, -2)) + (-5)) + "px";
      }
    }
  }
  if ((isGecko()) && (webPageMode == 2)) {
    divAll = getTags("div");
    for (i = 0; i < divAll.length; i++) {
      if (divAll[i].subMenuItem) {
        divAll[i].subMenuItem.style.marginTop = (-10) + "px";
      }
    }
  }
}

function activatejsDOMenuBy(value) {
  adjustArrowPos();
  switch (value) {
    case 0:
      document.onclick = activatejsDOMenu;
      break;
    case 1:
      document.oncontextmenu = activatejsDOMenu;
      break;
    case 2:
      document.onclick = activatejsDOMenu;
      document.oncontextmenu = activatejsDOMenu;
      break;
  }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Florence FZ Li
Web Developer
United States United States
M.S.: Computer Science, B.S.: Physics, MCSD: .NET, MCSD: VS 6
 
Florence currently works at Confident Software, Inc. Atlanta, U.S.A. Besides programming, during her spare time she enjoys opera.

| Advertise | Privacy | Mobile
Web04 | 2.8.140721.1 | Last Updated 9 Nov 2005
Article Copyright 2005 by Florence FZ Li
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid