//v.3.6 build 131108
/*
Copyright DHTMLX LTD. http://www.dhtmlx.com
You allowed to use this component or parts of it under GPL terms
To use it on other terms or get Professional edition of the component please contact us at sales@dhtmlx.com
*/
/****************************************************************************************************************************************************/
/* EXTENDED MODULE INFO */
dhtmlXMenuObject.prototype.extendedModule = "DHXMENUEXT";
/****************************************************************************************************************************************************/
/* ENABLING/DISBLING */
/**
* @desc: enables an item
* @param: id - item's id to enable
* @param: state - true|false
* @type: public
*/
dhtmlXMenuObject.prototype.setItemEnabled = function(id) {
// modified in 0.4
this._changeItemState(id, "enabled", this._getItemLevelType(id));
}
/**
* @desc: disables an item
* @param: id - item's id to disablei
* @type: public
*/
dhtmlXMenuObject.prototype.setItemDisabled = function(id) {
this._changeItemState(id, "disabled", this._getItemLevelType(id));
}
/**
* @desc: returns true if the item is enabled
* @param: id - the item to check
* @type: public
*/
dhtmlXMenuObject.prototype.isItemEnabled = function(id) {
return (this.itemPull[this.idPrefix+id]!=null?(this.itemPull[this.idPrefix+id]["state"]=="enabled"):false);
}
/* enable/disable sublevel item */
dhtmlXMenuObject.prototype._changeItemState = function(id, newState, levelType) {
var t = false;
var j = this.idPrefix + id;
if ((this.itemPull[j] != null) && (this.idPull[j] != null)) {
if (this.itemPull[j]["state"] != newState) {
this.itemPull[j]["state"] = newState;
if (this.itemPull[j]["parent"] == this.idPrefix+this.topId && !this.context) {
this.idPull[j].className = "dhtmlxMenu_"+this.skin+"_TopLevel_Item_"+(this.itemPull[j]["state"]=="enabled"?"Normal":"Disabled");
} else {
this.idPull[j].className = "sub_item"+(this.itemPull[j]["state"]=="enabled"?"":"_dis");
}
this._updateItemComplexState(this.idPrefix+id, this.itemPull[this.idPrefix+id]["complex"], false);
this._updateItemImage(id, levelType);
// if changeItemState attached to onClick event and changing applies to selected item all selection should be reparsed
if ((this.idPrefix + this.menuLastClicked == j) && (levelType != "TopLevel")) {
this._redistribSubLevelSelection(j, this.itemPull[j]["parent"]);
}
if (levelType == "TopLevel" && !this.context) { // rebuild style.left and show nested polygons
// this._redistribTopLevelSelection(id, "parent");
}
}
}
return t;
}
/****************************************************************************************************************************************************/
/* SET/GET TEXT */
/**
* @desc: returns item's text
* @param: id - the item
* @type: public
*/
dhtmlXMenuObject.prototype.getItemText = function(id) {
return (this.itemPull[this.idPrefix+id]!=null?this.itemPull[this.idPrefix+id]["title"]:"");
}
/**
* @desc: sets text for the item
* @param: id - the item
* @param: text - a new text
* @type: public
*/
dhtmlXMenuObject.prototype.setItemText = function(id, text) {
id = this.idPrefix + id;
if ((this.itemPull[id] != null) && (this.idPull[id] != null)) {
this._clearAndHide();
this.itemPull[id]["title"] = text;
if (this.itemPull[id]["parent"] == this.idPrefix+this.topId && !this.context) {
// top level
var tObj = null;
for (var q=0; q 0) this.idPull[id].insertBefore(tObj,this.idPull[id].childNodes[0]); else this.idPull[id].appendChild(tObj);
}
tObj.innerHTML = this.itemPull[id]["title"];
}
} else {
// sub level
var tObj = null;
for (var q=0; q= 0) return;
// get arrow
var ind = (this._rtl?0:2);
if (!this.idPull[id].childNodes[ind]) return;
if (!this.idPull[id].childNodes[ind].childNodes[0]) return;
var aNode = this.idPull[id].childNodes[ind].childNodes[0];
if (String(aNode.className).search("complex_arrow") === 0) aNode.className = "complex_arrow"+(state?"_loading":"");
}
/****************************************************************************************************************************************************/
/* IMAGES */
/**
* @desc: returns item's image - array(img, imgDis)
* @param: id - the item
* @type: public
*/
dhtmlXMenuObject.prototype.getItemImage = function(id) {
var imgs = new Array(null, null);
id = this.idPrefix+id;
if (this.itemPull[id]["type"] == "item") {
imgs[0] = this.itemPull[id]["imgen"];
imgs[1] = this.itemPull[id]["imgdis"];
}
return imgs;
}
/**
* @desc: sets an image for the item
* @param: id - the item
* @param: img - the image for the enabled item (empty string for none)
* @param: imgDis - the image for the disabled item (empty string for none)
* @type: public
*/
dhtmlXMenuObject.prototype.setItemImage = function(id, img, imgDis) {
if (this.itemPull[this.idPrefix+id]["type"] != "item") return;
this.itemPull[this.idPrefix+id]["imgen"] = img;
this.itemPull[this.idPrefix+id]["imgdis"] = imgDis;
this._updateItemImage(id, this._getItemLevelType(id));
}
/**
* @desc: removes both enabled and disabled item images
* @param: id - the item
* @type: public
*/
dhtmlXMenuObject.prototype.clearItemImage = function(id) {
this.setItemImage(id, "", "");
}
/****************************************************************************************************************************************************/
/* CONTEXT STUFF */
/* public: context menu auto open/close enable/disable */
/**
* @desc: sets to false to prevent showing a contextual menu by a click
* @param: mode - true/false
* @type: public
*/
dhtmlXMenuObject.prototype.setAutoShowMode = function(mode) {
this.contextAutoShow = (mode==true?true:false);
}
/**
* @desc: sets to false to prevent hiding a contextual menu by a click
* @param: mode - true/false
* @type: public
*/
dhtmlXMenuObject.prototype.setAutoHideMode = function(mode) {
this.contextAutoHide = (mode==true?true:false);
}
/**
* @desc: sets to true will hide all opened contextual menu polygons on mouseout
* @param: mode - true/false
* @type: public
*/
dhtmlXMenuObject.prototype.setContextMenuHideAllMode = function(mode) {
this.contextHideAllMode = (mode==true?true:false);
}
/**
* @desc: retutn hide all contextual menu mode
* @type: public
*/
dhtmlXMenuObject.prototype.getContextMenuHideAllMode = function() {
return this.contextHideAllMode;
}
/****************************************************************************************************************************************************/
/* VISIBLE AREA */
/**
* @desc: sets the area in which the menu can appear, if the area is not set, the menu will occupy all available visible space
* @param: x1, x2 - int, leftmost and rightmost coordinates by x axis
* @param: y1, y2 - int, topmost and bottommost coordinates by y axis
* @type: public
*/
dhtmlXMenuObject.prototype.setVisibleArea = function(x1, x2, y1, y2) {
this._isVisibleArea = true;
this.menuX1 = x1;
this.menuX2 = x2;
this.menuY1 = y1;
this.menuY2 = y2;
}
/****************************************************************************************************************************************************/
/* TOOLTOPS */
// tooltips, added in 0.4
/**
* @desc: sets tooltip for a menu item
* @param: id - menu item's id
* @param: tip - tooltip
* @type: public
*/
dhtmlXMenuObject.prototype.setTooltip = function(id, tip) {
id = this.idPrefix+id;
if (!(this.itemPull[id] != null && this.idPull[id] != null)) return;
this.idPull[id].title = (tip.length > 0 ? tip : null);
this.itemPull[id]["tip"] = tip;
}
/**
* @desc: returns tooltip of a menu item
* @param: id - menu item's id
* @type: public
*/
dhtmlXMenuObject.prototype.getTooltip = function(id) {
if (this.itemPull[this.idPrefix+id] == null) return null;
return this.itemPull[this.idPrefix+id]["tip"];
}
/****************************************************************************************************************************************************/
/* HOTKEYS */
//#menu_hotkey:06062008#{
// hot-keys, added in 0.4
/**
* @desc: sets menu hot-key (just text label)
* @param: id - menu item's id
* @param: hkey - hot-key text
* @type: public
*/
dhtmlXMenuObject.prototype.setHotKey = function(id, hkey) {
id = this.idPrefix+id;
if (!(this.itemPull[id] != null && this.idPull[id] != null)) return;
if (this.itemPull[id]["parent"] == this.idPrefix+this.topId && !this.context) return;
if (this.itemPull[id]["complex"]) return;
var t = this.itemPull[id]["type"];
if (!(t == "item" || t == "checkbox" || t == "radio")) return;
// retrieve obj
var hkObj = null;
try { if (this.idPull[id].childNodes[this._rtl?0:2].childNodes[0].className == "sub_item_hk") hkObj = this.idPull[id].childNodes[this._rtl?0:2].childNodes[0]; } catch(e){}
if (hkey.length == 0) {
// remove if exists
this.itemPull[id]["hotkey_backup"] = this.itemPull[id]["hotkey"];
this.itemPull[id]["hotkey"] = "";
if (hkObj != null) hkObj.parentNode.removeChild(hkObj);
} else {
// add if needed or change
this.itemPull[id]["hotkey"] = hkey;
this.itemPull[id]["hotkey_backup"] = null;
//
if (hkObj == null) {
hkObj = document.createElement("DIV");
hkObj.className = "sub_item_hk";
var item = this.idPull[id].childNodes[this._rtl?0:2];
while (item.childNodes.length > 0) item.removeChild(item.childNodes[0]);
item.appendChild(hkObj);
}
hkObj.innerHTML = hkey;
}
}
/**
* @desc: returns item's hot-key (just text label)
* @param: id - menu item's id
* @type: public
*/
dhtmlXMenuObject.prototype.getHotKey = function(id) {
if (this.itemPull[this.idPrefix+id] == null) return null;
return this.itemPull[this.idPrefix+id]["hotkey"];
}
/****************************************************************************************************************************************************/
/* MISC */
//#}
/* set toplevel item selected */
dhtmlXMenuObject.prototype.setItemSelected = function(id) {
if (this.itemPull[this.idPrefix+id] == null) return null;
// console.log(this.itemPull[this.idPrefix+id]);
}
/**
* @desc: set top level additional text (in case of usual menubar)
* @param: text - text
* @type: public
*/
dhtmlXMenuObject.prototype.setTopText = function(text) {
if (this.context) return;
if (this._topText == null) {
this._topText = document.createElement("DIV");
this._topText.className = "dhtmlxMenu_TopLevel_Text_"+(this._rtl?"left":(this._align=="left"?"right":"left"));
this.base.appendChild(this._topText);
}
this._topText.innerHTML = text;
}
/**
* @desc: set top level menu align
* @param: align - left|right
* @type: public
*/
dhtmlXMenuObject.prototype.setAlign = function(align) {
if (this._align == align) return;
if (align == "left" || align == "right") {
// if (this.setRTL) this.setRTL(false);
this._align = align;
if (this.cont) this.cont.className = (this._align=="right"?"align_right":"align_left");
if (this._topText != null) this._topText.className = "dhtmlxMenu_TopLevel_Text_"+(this._align=="left"?"right":"left");
}
}
/**
* @desc: set href to item, overwrite old if exists
* @param: itemId
* @param: href - url to open instead of onClik event handling
* @param: target - target attribute
* @type: public
*/
dhtmlXMenuObject.prototype.setHref = function(itemId, href, target) {
if (this.itemPull[this.idPrefix+itemId] == null) return;
this.itemPull[this.idPrefix+itemId]["href_link"] = href;
if (target != null) this.itemPull[this.idPrefix+itemId]["href_target"] = target;
}
/**
* @desc: clears item href and back item to default onClick behavior
* @param: itemId
* @type: public
*/
dhtmlXMenuObject.prototype.clearHref = function(itemId) {
if (this.itemPull[this.idPrefix+itemId] == null) return;
delete this.itemPull[this.idPrefix+itemId]["href_link"];
delete this.itemPull[this.idPrefix+itemId]["href_target"];
}
/*
File [id="file"] -> Open [id="open"] -> Last Save [id="lastsave"]
getCircuit("lastsave") will return Array("file", "open", "lastsave");
*/
/**
* @desc: return array with ids from topmost parent to chosen item
* @param: id - chosen item id
* @type: public
*/
dhtmlXMenuObject.prototype.getCircuit = function(id) {
var parents = new Array(id);
while (this.getParentId(id) != this.topId) {
id = this.getParentId(id);
parents[parents.length] = id;
}
return parents.reverse();
}
/* export to function */
/* WTF?
dhtmlXMenuObject.prototype.generateSQL = function() {
var sql = "INSERT INTO `dhtmlxmenu_demo` (`itemId`, `itemParentId`, `itemOrder`, `itemText`, `itemType`, `itemEnabled`, `itemChecked`, `itemGroup`, `itemImage`, `itemImageDis`) VALUES ";
var values = "";
var q = 0;
for (var a in this.itemPull) {
values += (values.length>0?", ":"")+"('"+a.replace(this.idPrefix,"")+"',"+
"'"+(this.itemPull[a]["parent"]!=null?this.itemPull[a]["parent"].replace(this.idPrefix,""):"")+"',"+
"'"+(q++)+"',"+
"'"+this.itemPull[a]["title"]+"',"+
"'"+(this.itemPull[a]["type"]!="item"?this.itemPull[a]["type"]:"")+"',"+
"'"+(this.itemPull[a]["state"]=="enabled"?"1":"0")+"',"+
"'"+(this.itemPull[a]["checked"]!=null?(this.itemPull[a]["checked"]?"1":"0"):"0")+"',"+
"'"+(this.itemPull[a]["group"]!=null?this.itemPull[a]["group"]:"")+"',"+
"'"+this.itemPull[a]["imgen"]+"',"+
"'"+this.itemPull[a]["imgdis"]+"')";
}
return sql+values;
}
*/
//#menu_overflow:06062008#{
/****************************************************************************************************************************************************/
/* OVERFLOW */
/* clear all selected subitems in polygon, implemented in 0.4 */
dhtmlXMenuObject.prototype._clearAllSelectedSubItemsInPolygon = function(polygon) {
var subIds = this._getSubItemToDeselectByPolygon(polygon);
// hide opened polygons and selected items
for (var q=0; q";
arrow.style.display = "none";
arrow.over = false;
arrow.onselectstart = function(e) { e = e||event; e.returnValue = false; return false; }
arrow.oncontextmenu = function(e) { e = e||event; e.returnValue = false; return false; }
// actions
arrow.onmouseover = function() {
if (main_self.menuMode == "web") { window.clearTimeout(main_self.menuTimeoutHandler); }
main_self._clearAllSelectedSubItemsInPolygon(this.pId);
if (this.className == "dhtmlxMenu_"+main_self.skin+"_SubLevelArea_ArrowUp_Disabled") return;
this.className = "dhtmlxMenu_"+main_self.skin+"_SubLevelArea_ArrowUp_Over";
this.over = true;
main_self._canScrollUp = true;
main_self._doScrollUp(this.pId, true);
}
arrow.onmouseout = function() {
if (main_self.menuMode == "web") {
window.clearTimeout(main_self.menuTimeoutHandler);
main_self.menuTimeoutHandler = window.setTimeout(function(){main_self._clearAndHide();}, main_self.menuTimeoutMsec, "JavaScript");
}
this.over = false;
main_self._canScrollUp = false;
if (this.className == "dhtmlxMenu_"+main_self.skin+"_SubLevelArea_ArrowUp_Disabled") return;
this.className = "dhtmlxMenu_"+main_self.skin+"_SubLevelArea_ArrowUp";
window.clearTimeout(main_self._scrollUpTM);
}
arrow.onclick = function(e) {
e = e||event;
e.returnValue = false;
e.cancelBubble = true;
return false;
}
//
// var polygon = this.idPull["polygon_"+this.idPrefix+id];
// polygon.insertBefore(arrow, polygon.childNodes[0]);
document.body.insertBefore(arrow, document.body.firstChild);
this.idPull[arrow.id] = arrow;
}
dhtmlXMenuObject.prototype._addDownArrow = function(id) {
var main_self = this;
var arrow = document.createElement("DIV");
arrow.pId = this.idPrefix+id;
arrow.id = "arrowdown_"+this.idPrefix+id;
arrow.className = "dhtmlxMenu_"+this.skin+"_SubLevelArea_ArrowDown";
arrow.innerHTML = "";
arrow.style.display = "none";
arrow.over = false;
arrow.onselectstart = function(e) { e = e||event; e.returnValue = false; return false; }
arrow.oncontextmenu = function(e) { e = e||event; e.returnValue = false; return false; }
// actions
arrow.onmouseover = function() {
if (main_self.menuMode == "web") { window.clearTimeout(main_self.menuTimeoutHandler); }
main_self._clearAllSelectedSubItemsInPolygon(this.pId);
if (this.className == "dhtmlxMenu_"+main_self.skin+"_SubLevelArea_ArrowDown_Disabled") return;
this.className = "dhtmlxMenu_"+main_self.skin+"_SubLevelArea_ArrowDown_Over";
this.over = true;
main_self._canScrollDown = true;
main_self._doScrollDown(this.pId, true);
}
arrow.onmouseout = function() {
if (main_self.menuMode == "web") {
window.clearTimeout(main_self.menuTimeoutHandler);
main_self.menuTimeoutHandler = window.setTimeout(function(){main_self._clearAndHide();}, main_self.menuTimeoutMsec, "JavaScript");
}
this.over = false;
main_self._canScrollDown = false;
if (this.className == "dhtmlxMenu_"+main_self.skin+"_SubLevelArea_ArrowDown_Disabled") return;
this.className = "dhtmlxMenu_"+main_self.skin+"_SubLevelArea_ArrowDown";
window.clearTimeout(main_self._scrollDownTM);
}
arrow.onclick = function(e) {
e = e||event;
e.returnValue = false;
e.cancelBubble = true;
return false;
}
document.body.insertBefore(arrow, document.body.firstChild);
this.idPull[arrow.id] = arrow;
}
dhtmlXMenuObject.prototype._removeUpArrow = function(id) {
var fullId = "arrowup_"+this.idPrefix+id;
this._removeArrow(fullId);
}
dhtmlXMenuObject.prototype._removeDownArrow = function(id) {
var fullId = "arrowdown_"+this.idPrefix+id;
this._removeArrow(fullId);
}
dhtmlXMenuObject.prototype._removeArrow = function(fullId) {
var arrow = this.idPull[fullId];
arrow.onselectstart = null;
arrow.oncontextmenu = null;
arrow.onmouseover = null;
arrow.onmouseout = null;
arrow.onclick = null;
if (arrow.parentNode) arrow.parentNode.removeChild(arrow);
arrow = null;
this.idPull[fullId] = null;
try { delete this.idPull[fullId]; } catch(e) {}
}
dhtmlXMenuObject.prototype._isArrowExists = function(id) {
if (this.idPull["arrowup_"+id] != null && this.idPull["arrowdown_"+id] != null) return true;
return false;
}
/* scroll down */
dhtmlXMenuObject.prototype._doScrollUp = function(id, checkArrows) {
var polygon = this.idPull["polygon_"+id];
if (this._canScrollUp && polygon.scrollTop > 0) {
var theEnd = false;
var nextScrollTop = polygon.scrollTop - this._scrollUpTMStep;
if (nextScrollTop < 0) {
theEnd = true;
nextScrollTop = 0;
}
polygon.scrollTop = nextScrollTop;
if (!theEnd) {
var that = this;
this._scrollUpTM = window.setTimeout(function() { that._doScrollUp(id, false); }, this._scrollUpTMTime);
}
} else {
this._canScrollUp = false;
this._checkArrowsState(id);
}
if (checkArrows) {
this._checkArrowsState(id);
}
}
dhtmlXMenuObject.prototype._doScrollDown = function(id, checkArrows) {
var polygon = this.idPull["polygon_"+id];
if (this._canScrollDown && polygon.scrollTop + polygon.offsetHeight <= polygon.scrollHeight) {
var theEnd = false;
var nextScrollTop = polygon.scrollTop + this._scrollDownTMStep;
if (nextScrollTop + polygon.offsetHeight > polygon.scollHeight) {
theEnd = true;
nextScrollTop = polygon.scollHeight - polygon.offsetHeight;
}
polygon.scrollTop = nextScrollTop;
if (!theEnd) {
var that = this;
this._scrollDownTM = window.setTimeout(function() { that._doScrollDown(id, false); }, this._scrollDownTMTime);
}
} else {
this._canScrollDown
this._checkArrowsState(id);
}
if (checkArrows) {
this._checkArrowsState(id);
}
}
//
dhtmlXMenuObject.prototype._countPolygonItems = function(id) {
var count = 0;
for (var a in this.itemPull) {
var par = this.itemPull[a]["parent"];
var tp = this.itemPull[a]["type"];
if (par == this.idPrefix+id && (tp == "item" || tp == "radio" || tp == "checkbox")) { count++; }
}
return count;
}
/* limit maximum items on single polygon, default - 0 = no limit */
/**
* @desc: limits the maximum number of visible items in polygons
* @param: itemsNum - count of the maximum number of visible items
* @type: public
*/
dhtmlXMenuObject.prototype.setOverflowHeight = function(itemsNum) {
// set auto overflow mode
if (itemsNum === "auto") {
this.limit = 0;
this.autoOverflow = true;
return;
}
// no existing limitation, now new limitation
if (this.limit == 0 && itemsNum <= 0) return;
// hide menu to prevent visible changes
this._clearAndHide();
// redefine existing limitation, arrows will added automatically with showPlygon
if (this.limit >= 0 && itemsNum > 0) {
this.limit = itemsNum;
return;
}
// remove existing limitation
if (this.limit > 0 && itemsNum <= 0) {
for (var a in this.itemPull) {
if (this._isArrowExists(a)) {
var b = String(a).replace(this.idPrefix, "");
this._removeUpArrow(b);
this._removeDownArrow(b);
// remove polygon's height
this.idPull["polygon_"+a].style.height = "";
}
}
this.limit = 0;
return;
}
}
//#}
/****************************************************************************************************************************************************/
/* RADIOBUTTONS */
//#menu_radio:06062008{
dhtmlXMenuObject.prototype._getRadioImgObj = function(id) {
try { var imgObj = this.idPull[this.idPrefix+id].childNodes[(this._rtl?2:0)].childNodes[0] } catch(e) { var imgObj = null; }
return imgObj;
}
dhtmlXMenuObject.prototype._setRadioState = function(id, state) {
// if (this.itemPull[this.idPrefix+id]["state"] != "enabled") return;
var imgObj = this._getRadioImgObj(id);
if (imgObj != null) {
// fix, added in 0.4
var rObj = this.itemPull[this.idPrefix+id];
rObj["checked"] = state;
rObj["imgen"] = "rdbt_"+(rObj["checked"]?"1":"0");
rObj["imgdis"] = rObj["imgen"];
imgObj.className = "sub_icon "+rObj["imgen"];
}
}
dhtmlXMenuObject.prototype._radioOnClickHandler = function(id, type, casState) {
if (type.charAt(1)=="d" || this.itemPull[this.idPrefix+id]["group"]==null) return;
// deselect all from the same group
var group = this.itemPull[this.idPrefix+id]["group"];
if (this.checkEvent("onRadioClick")) {
if (this.callEvent("onRadioClick", [group, this.getRadioChecked(group), id, this.contextMenuZoneId, casState])) {
this.setRadioChecked(group, id);
}
} else {
this.setRadioChecked(group, id);
}
// call onClick if exists
if (this.checkEvent("onClick")) this.callEvent("onClick", [id]);
}
/**
* @desc: returns a checked radio button in the group
* @param: group - radio button group
* @type: public
*/
dhtmlXMenuObject.prototype.getRadioChecked = function(group) {
var id = null;
for (var q=0; q';
}
if (this.itemPull[a]["type"] == "separator") {
itemType = ' type="separator"';
} else {
if (this.itemPull[a]["state"] == "disabled") itemState = ' enabled="false"';
}
if (this.itemPull[a]["type"] == "checkbox") {
itemType = ' type="checkbox"'+(this.itemPull[a]["checked"]?' checked="true"':"");
}
if (this.itemPull[a]["type"] == "radio") {
itemType = ' type="radio" group="'+this.itemPull[a]["group"]+'" '+(this.itemPull[a]["checked"]?' checked="true"':"");
}
xml += "- ";
xml += hotKey;
if (this.itemPull[a]["complex"]) xml += this._readLevel(a);
xml += "
";
}
}
return xml;
}
/**
* @desc: serialize menu to xml
* @type: public
*/
dhtmlXMenuObject.prototype.serialize = function() {
var xml = "";
return xml;
}
/****************************************************************************************************************************************************/