4
Copyright DHTMLX LTD. http://www.dhtmlx.com
5
You allowed to use this component or parts of it under GPL terms
6
To use it on other terms or get Professional edition of the component please contact us at sales@dhtmlx.com
9
* @desc: a constructor, creates a new dhtmlxMenu object, baseId defines a base object for the top menu level
10
* @param: baseId - id of the html element to which a menu will be attached, in case of a contextual menu - if specified, will used as a contextual zone
13
function dhtmlXMenuObject(baseId, skin) {
16
this.addBaseIdAsContextZone = null;
19
this.skin = (skin!=null?skin:"dhx_blue");
20
this.skinPath = "imgs/"+this.skin;
21
this.imagePath = this.skinPath;
23
if (_isIE) { this._isIE6 = (window.XMLHttpRequest==null?true:false); }
25
this.base = document.body;
27
if (document.getElementById(baseId) != null) {
28
this.base = document.getElementById(baseId);
29
while (this.base.childNodes.length > 0) { this.base.removeChild(this.base.childNodes[0]); }
30
this.base.className += " dhtmlxMenu_"+this.skin+"_Middle";
31
this.base._autoSkinUpdate = true;
32
this.addBaseIdAsContextZone = baseId;
34
this.base = document.body;
37
// this.topId = topId;
38
this.topId = "dhxWebMenuTopId";
40
this.menu = new Array();
41
this.subMenuData = new Array();
42
this.menuSelected = -1;
43
this.menuLastClicked = -1;
45
this.itemTagName = "item";
46
this.itemTextTagName = "itemtext";
47
this.userDataTagName = "userdata";
48
this.itemTipTagName = "tooltip";
49
this.itemHotKeyTagName = "hotkey";
50
this.dirTopLevel = "bottom";
51
this.dirSubLevel = "right";
56
this.menuMode = "web";
57
this.menuTimeoutMsec = 400;
58
this.menuTimeoutHandler = null;
64
this.menuTouched = false;
67
this.zInd = this.zIndInit;
70
this.menuModeTopLevelTimeout = true; // shows sublevel polygons from toplevel items with delay
71
this.menuModeTopLevelTimeoutTime = 200; // msec
74
// this.skin = "Standard";
75
// this.imagePath = "imgs/standard/";
78
this.topLevelItemPaddingIconExists = 27;
79
this.topLevelItemPaddingIconNotExists = 6;
80
this._topLevelBottomMargin = 1;
81
this._topLevelRightMargin = 0;
82
this._arrowFFFix = (_isIE ? 0 : -4); // border fixer for FF for arrows polygons
85
this.setSkin = function(skin) {
86
var oldSkin = this.skin;
90
this._topLevelBottomMargin = 1;
91
this._arrowFFFix = (_isIE ? 0 : -4);
96
this._topLevelBottomMargin = 3;
97
this._arrowFFFix = (_isIE ? 0 : -4);
102
this._topLevelBottomMargin = 1;
103
this._arrowFFFix = (_isIE ? 0 : -2);
108
this._topLevelBottomMargin = 3;
109
this._arrowFFFix = (_isIE ? 0 : -2);
112
this._topLevelBottomMargin = 0;
116
this._topLevelBottomMargin = 2;
117
this._topLevelRightMargin = 1;
120
if (this.base._autoSkinUpdate) {
121
this.base.className = this.base.className.replace("dhtmlxMenu_"+oldSkin+"_Middle", "")+" dhtmlxMenu_"+this.skin+"_Middle";
124
this.setSkin(this.skin);
128
this.loaderIcon = false;
131
this._scrollUpTM = null;
132
this._scrollUpTMTime = 20;
133
this._scrollUpTMStep = 3;
134
this._scrollDownTM = null;
135
this._scrollDownTMTime = 20;
136
this._scrollDownTMStep = 3;
138
this.context = false;
139
this.contextZones = {};
140
this.contextMenuZoneId = false;
141
this.contextAutoShow = true; /* default open action */
142
this.contextAutoHide = true; /* default close action */
144
this.sxDacProc = null;
147
for (var q=0; q<10; q++) { this.dacCycles[q] = q; }
148
this.dacSpeedIE = 60;
149
this.dacCyclesIE = [];
150
for (var q=0; q<3; q++) { this.dacCyclesIE[q] = q*2+1; }
151
/* version 0.2 features: selected items and polygond for quick deselect */
152
/* sxDac feature, implemented in version 0.4 */
153
this._enableDacSupport = function(dac) { this.sxDacProc = dac; }
154
this._selectedSubItems = new Array();
155
this._openedPolygons = new Array();
156
this._addSubItemToSelected = function(item, polygon) {
158
for (var q=0; q<this._selectedSubItems.length; q++) { if ((this._selectedSubItems[q][0] == item) && (this._selectedSubItems[q][1] == polygon)) { t = false; } }
159
if (t == true) { this._selectedSubItems.push(new Array(item, polygon)); }
162
this._removeSubItemFromSelected = function(item, polygon) {
165
for (var q=0; q<this._selectedSubItems.length; q++) { if ((this._selectedSubItems[q][0] == item) && (this._selectedSubItems[q][1] == polygon)) { t = true; } else { m[m.length] = this._selectedSubItems[q]; } }
166
if (t == true) { this._selectedSubItems = m; }
169
this._getSubItemToDeselectByPolygon = function(polygon) {
171
for (var q=0; q<this._selectedSubItems.length; q++) {
172
if (this._selectedSubItems[q][1] == polygon) {
173
m[m.length] = this._selectedSubItems[q][0];
174
m = m.concat(this._getSubItemToDeselectByPolygon(this._selectedSubItems[q][0]));
176
for (var w=0; w<this._openedPolygons.length; w++) { if (this._openedPolygons[w] == this._selectedSubItems[q][0]) { t = false; } }
177
if (t == true) { this._openedPolygons[this._openedPolygons.length] = this._selectedSubItems[q][0]; }
178
this._selectedSubItems[q][0] = -1;
179
this._selectedSubItems[q][1] = -1;
185
/* define polygon's position for dinamic content rendering and shows it, added in version 0.3 */
186
this._hidePolygon = function(id) {
187
if (this.idPull["polygon_" + id] != null) {
188
if ((this.sxDacProc != null) && (this.idPull["sxDac_" + id] != null)) {
189
this.idPull["sxDac_"+id]._hide();
191
this.idPull["polygon_"+id].style.display = "none";
192
if (this.idPull["arrowup_"+id] != null) { this.idPull["arrowup_"+id].style.display = "none"; }
193
if (this.idPull["arrowdown_"+id] != null) { this.idPull["arrowdown_"+id].style.display = "none"; }
194
this._updateItemComplexState(id, true, false);
196
if (this._isIE6) { if (this.idPull["polygon_"+id+"_ie6cover"] != null) { this.idPull["polygon_"+id+"_ie6cover"].style.display = "none"; } }
200
this._showPolygon = function(id, openType) {
201
var itemCount = this._countVisiblePolygonItems(id);
202
if (itemCount == 0) { return; }
203
var pId = "polygon_"+id;
204
if ((this.idPull[pId] != null) && (this.idPull[id] != null)) {
205
if (this.menuModeTopLevelTimeout && this.menuMode == "web" && !this.context) {
206
if (!this.idPull[id]._mouseOver && openType == this.dirTopLevel) { return; }
213
var arrowDown = null;
214
//#menu_overflow:06062008#{
215
if (this.limit > 0 && this.limit < itemCount) {
216
var auId = "arrowup_"+id;
217
var adId = "arrowdown_"+id;
218
if (this.idPull["arrowup_"+id] != null) {
219
arrowUp = this.idPull["arrowup_"+id];
220
arrowUp.style.visibility = "hidden";
221
arrowUp.style.display = "";
222
arrowUp.style.zIndex = this.zInd;
223
arrUpH = arrowUp.offsetHeight;
225
if (this.idPull["arrowdown_"+id] != null) {
226
arrowDown = this.idPull["arrowdown_"+id];
227
arrowDown.style.visibility = "hidden";
228
arrowDown.style.display = "";
229
arrowDown.style.zIndex = this.zInd;
230
arrDownH = arrowDown.offsetHeight;
235
this.idPull[pId].style.visibility = "hidden";
236
this.idPull[pId].style.display = "";
237
this.idPull[pId].style.zIndex = this.zInd;
239
if (this.limit > 0 && this.limit < itemCount) {
241
this.idPull[pId].style.height = this.idPull[pId].childNodes[0].offsetHeight*this.limit;// + arrUpH + arrDownH;
242
this.idPull[pId].scrollTop = 0;
245
this.zInd += this.zIndStep;
247
// console.log(this.idPull)
248
if (this.itemPull[id] != null) {
249
var parPoly = "polygon_"+this.itemPull[id]["parent"];
250
} else if (this.context) {
251
var parPoly = this.idPull[this.idPrefix+this.topId];
255
if (parPoly == null) {
256
alert("Implementation error. Please report support@dhtmlx.com");
259
var scrTp = (this.idPull[parPoly] != null ? this.idPull[parPoly].scrollTop : 0);
262
var srcX = (this.idPull[id].tagName != null ? getAbsoluteLeft(this.idPull[id]) : this.idPull[id][0]);
264
var srcY = (this.idPull[id].tagName != null ? getAbsoluteTop(this.idPull[id]) : this.idPull[id][1]) - scrTp;
265
var srcW = (this.idPull[id].tagName != null ? this.idPull[id].offsetWidth : 0);
266
var srcH = (this.idPull[id].tagName != null ? this.idPull[id].offsetHeight + arrUpH + arrDownH : 0);
269
var w = this.idPull[pId].offsetWidth;
270
var h = this.idPull[pId].offsetHeight;
273
if (openType == "bottom") { x = srcX - 1 + (openType==this.dirTopLevel?this._topLevelRightMargin:0); y = srcY - 1 + srcH - arrUpH - arrDownH + this._topLevelBottomMargin; }
274
if (openType == "right") { x = srcX + srcW - 1; y = srcY + 2; }
275
if (openType == "top") { x = srcX - 1; y = srcY - h + 2; }
278
var mx = (this.menuX2!=null?this.menuX2:0);
279
var my = (this.menuY2!=null?this.menuY2:0);
281
if (window.innerWidth) {
282
mx = window.innerWidth;
283
my = window.innerHeight;
285
mx = document.body.offsetWidth;
286
my = document.body.scrollHeight;
289
if (x+w > mx) { x = srcX - w + 2; }
290
if (y+h > my && this.menuY2 != null) { y = srcY + srcH - h + 2; }
292
this.idPull[pId].style.left = x+"px";
293
this.idPull[pId].style.top = y+arrUpH+"px";
295
if ((this.sxDacProc != null) && (this.idPull["sxDac_" + id] != null)) {
296
this.idPull["sxDac_"+id]._show();
298
this.idPull[pId].style.visibility = "";
299
//#menu_overflow:06062008#{
300
if (this.limit > 0 && this.limit < itemCount) {
301
// this.idPull[pId].scrollTop = 0;
302
arrowUp.style.left = x+"px";
303
arrowUp.style.top = y+"px";
304
arrowUp.style.width = w+this._arrowFFFix+"px";
305
arrowUp.style.visibility = "";
307
arrowDown.style.left = x+"px";
308
arrowDown.style.top = y+arrUpH+h+"px";
309
arrowDown.style.width = w+this._arrowFFFix+"px";
310
arrowDown.style.visibility = "";
312
this._checkArrowsState(id);
317
var pIdIE6 = pId+"_ie6cover";
318
if (this.idPull[pIdIE6] == null) {
319
var ifr = document.createElement("IFRAME");
320
ifr.className = "dhtmlxMenu_IE6CoverFix_"+this.skin;
322
document.body.appendChild(ifr)
323
this.idPull[pIdIE6] = ifr;
325
this.idPull[pIdIE6].style.left = this.idPull[pId].style.left;
326
this.idPull[pIdIE6].style.top = this.idPull[pId].style.top;
327
this.idPull[pIdIE6].style.width = this.idPull[pId].offsetWidth+"px";
328
this.idPull[pIdIE6].style.height = this.idPull[pId].offsetHeight+"px";
329
this.idPull[pIdIE6].style.zIndex = this.idPull[pId].style.zIndex-1;
330
this.idPull[pIdIE6].style.display = "";
332
this.callEvent("_onPolyShow",[id.replace(this.idPrefix,"")]);
336
/* redistrib sublevel selection: select id and deselect other, added in version 0.3 */
337
this._redistribSubLevelSelection = function(id, parentId) {
338
// clear previosly selected items
339
while (this._openedPolygons.length > 0) { this._openedPolygons.pop(); }
340
// this._openedPolygons = new Array();
341
var i = this._getSubItemToDeselectByPolygon(parentId);
342
this._removeSubItemFromSelected(-1, -1);
343
for (var q=0; q<i.length; q++) { if ((this.idPull[i[q]] != null) && (i[q] != id)) { if (this.itemPull[i[q]]["state"] == "enabled") { this.idPull[i[q]].className = "dhtmlxMenu_"+this.skin+"_SubLevelArea_Item_Normal"; } } }
345
for (var q=0; q<this._openedPolygons.length; q++) { if (this._openedPolygons[q] != parentId) { this._hidePolygon(this._openedPolygons[q]); } }
346
// add new selection into list new
347
if (this.itemPull[id]["state"] == "enabled") {
348
this.idPull[id].className = "dhtmlxMenu_"+this.skin+"_SubLevelArea_Item_Selected";
349
if (this.itemPull[id]["complex"] && this.dLoad && (this.itemPull[id]["loaded"]=="no")) {
350
if (this.loaderIcon == true) { this._updateLoaderIcon(id, true); }
351
var xmlLoader = new dtmlXMLLoaderObject(this._xmlParser, window);
352
this.itemPull[id]["loaded"] = "get";
353
this.callEvent("onXLS", []);
354
xmlLoader.loadXML(this.dLoadUrl+"?action=loadMenu&parentId="+id.replace(this.idPrefix,"")+"&etc="+new Date().getTime());
357
if (this.itemPull[id]["complex"] || (this.dLoad && (this.itemPull[id]["loaded"] == "yes"))) {
359
if ((this.itemPull[id]["complex"]) && (this.idPull["polygon_" + id] != null)) {
360
this._updateItemComplexState(id, true, true);
361
this._showPolygon(id, this.dirSubLevel);
364
this._addSubItemToSelected(id, parentId);
365
this.menuSelected = id;
368
/* onClickMenu action (click on any end item to perform some actions)
369
optimized in version 0.3 added type feature (click on disabled items, click on complex nodes)
370
attachEvent feature from 0.4 */
371
this._doOnClick = function(id, type) {
372
this.menuLastClicked = id;
375
if (type.charAt(0)=="c") { return; } // can't click on complex item
376
if (type.charAt(1)=="d") { return; } // can't click on disabled item
377
if (type.charAt(2)=="s") { return; } // can't click on separator
379
if (this.checkEvent("onClick")) {
380
// this.callEvent("onClick", [id, type, this.contextMenuZoneId]);
381
this._clearAndHide();
382
if (this._isContextMenuVisible() && this.contextAutoHide) { this._hideContextMenu(); }
383
this.callEvent("onClick", [id, this.contextMenuZoneId]);
385
if ((type.charAt(1) == "d") || (this.menuMode == "win" && type.charAt(2) == "t")) { return; }
386
this._clearAndHide();
387
if (this._isContextMenuVisible() && this.contextAutoHide) { this._hideContextMenu(); }
390
/* onTouchMenu action (select topLevel item), attachEvent added in 0.4 */
391
this._doOnTouchMenu = function(id) {
392
if (this.menuTouched == false) {
393
this.menuTouched = true;
394
if (this.checkEvent("onTouch")) {
395
this.callEvent("onTouch", [id]);
399
// this._onTouchHandler = function(id) { }
400
// this._setOnTouchHandler = function(handler) { this._onTouchHandler = function(id) { handler(id); } }
401
/* return menu array of all nested objects */
402
this._searchMenuNode = function(node, menu) {
404
for (var q=0; q<menu.length; q++) {
405
if (typeof(menu[q]) == "object") {
406
if (menu[q].length == 5) { if (typeof(menu[q][0]) != "object") { if ((menu[q][0].replace(this.idPrefix, "") == node) && (q == 0)) { m = menu; } } }
407
var j = this._searchMenuNode(node, menu[q]);
408
if (j.length > 0) { m = j; }
413
/* return array of subitems for single menu object */
414
/* modified in version 0.3 */
415
this._getMenuNodes = function(node) {
417
for (var a in this.itemPull) { if (this.itemPull[a]["parent"] == node) { m[m.length] = a; } }
420
/* generate random string with specified length */
421
this._genStr = function(w) {
422
var s = ""; var z = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
423
for (var q=0; q<w; q++) { s = s + z.charAt(Math.round(Math.random() * z.length)); }
427
* @desc: return item type by id
431
this.getItemType = function(id) {
432
id = this.idPrefix+id;
433
if (this.itemPull[id] == null) { return null; }
434
return this.itemPull[id]["type"];
437
* @desc: iterator, calls user-defined handler for each existing item and pass item id into it
438
* @param: handler - user-defined handler
441
this.forEachItem = function(handler) {
442
for (var a in this.itemPull) { handler(String(a).replace(this.idPrefix, "")); }
444
/* clear selection and hide menu on onbody click event, optimized in version 0.3 */
445
this._clearAndHide = function() {
446
main_self.menuSelected = -1;
447
main_self.menuLastClicked = -1;
448
while (main_self._openedPolygons.length > 0) { main_self._openedPolygons.pop(); }
449
for (var q=0; q<main_self._selectedSubItems.length; q++) {
450
var id = main_self._selectedSubItems[q][0];
451
// clear all selection
452
if (main_self.idPull[id] != null) {
453
if (main_self.itemPull[id]["state"] == "enabled") {
454
if (main_self.idPull[id].className == "dhtmlxMenu_"+main_self.skin+"_SubLevelArea_Item_Selected") { main_self.idPull[id].className = "dhtmlxMenu_"+main_self.skin+"_SubLevelArea_Item_Normal"; }
455
if (main_self.idPull[id].className == "dhtmlxMenu_"+main_self.skin+"_TopLevel_Item_Selected") {
456
// main_self.idPull[id].className = "dhtmlxMenu_"+main_self.skin+"_TopLevel_Item_Normal";
458
// console.log(main_self.itemPull[this.id])
459
if (main_self.itemPull[id]["cssNormal"] != null) {
461
main_self.idPull[id].className = main_self.itemPull[id]["cssNormal"];
464
main_self.idPull[id].className = "dhtmlxMenu_"+main_self.skin+"_TopLevel_Item_Normal";
469
main_self._hidePolygon(id);
472
// main_self._hidePolygon(main_self.idPrefix+main_self.topId);
473
main_self.menuTouched = false;
475
main_self.zInd = main_self.zIndInit;
477
/* loading and parsing through xml, optimized in version 0.3 */
478
this._doOnLoad = function() {}
480
* @desc: loads menu data from an xml file and calls onLoadFunction when loading is done
481
* @param: xmlFile - an xml file with webmenu data
482
* @param: onLoadFunction - a function that is called after loading is done
485
this.loadXML = function(xmlFile, onLoadFunction) {
486
if (onLoadFunction) this._doOnLoad = function() { onLoadFunction(); };
487
this.callEvent("onXLS", []);
488
this._xmlLoader.loadXML(xmlFile);
491
* @desc: loads menu data from an xml string and calls onLoadFunction when loading is done
492
* @param: xmlFile - an xml string with webmenu data
493
* @param: onLoadFunction - function that is called after loading is done
496
this.loadXMLString = function(xmlString, onLoadFunction) {
497
if (onLoadFunction) this._doOnLoad = function() { onLoadFunction(); };
498
this._xmlLoader.loadXMLString(xmlString);
500
this._buildMenu = function(t, parentId) {
501
// if (parentId==null) { parentId = this.topId;}
503
for (var q=0; q<t.childNodes.length; q++) {
504
if (t.childNodes[q].tagName == this.itemTagName) {
505
var r = t.childNodes[q];
508
item["id"] = this.idPrefix+(r.getAttribute("id")||this._genStr(24));
509
item["title"] = r.getAttribute("text")||"";
511
item["imgen"] = r.getAttribute("img")||"";
512
item["imgdis"] = r.getAttribute("imgdis")||"";
516
if (r.getAttribute("cssNormal") != null) { item["cssNormal"] = r.getAttribute("cssNormal"); }
518
item["type"] = r.getAttribute("type")||"item";
519
//#menu_checks:06062008{
520
if (item["type"] == "checkbox") {
521
item["checked"] = (r.getAttribute("checked")!=null);
522
item["imgen"] = "dhtmlxmenu_chbx_"+(item["checked"]?"1":"0")+".gif";
523
item["imgdis"] = "dhtmlxmenu_chbxdis_"+(item["checked"]?"1":"0")+".gif";
526
//#menu_radio:06062008{
527
if (item["type"] == "radio") {
528
item["checked"] = (r.getAttribute("checked")!=null);
529
item["imgen"] = "dhtmlxmenu_rdbt_"+(item["checked"]?"1":"0")+".gif";
530
item["imgdis"] = "dhtmlxmenu_rdbtdis_"+(item["checked"]?"1":"0")+".gif";
531
item["group"] = r.getAttribute("group")||this._genStr(24);
532
if (this.radio[item["group"]]==null) { this.radio[item["group"]] = new Array(); }
533
this.radio[item["group"]][this.radio[item["group"]].length] = item["id"];
537
item["state"] = (r.getAttribute("enabled")!=null?"disabled":"enabled");
538
item["parent"] = (parentId!=null?parentId:this.idPrefix+this.topId);
539
// item["complex"] = (((this.dLoad)&&(parentId!=null))?(r.getAttribute("complex")!=null?true:false):(this._buildMenu(r,item["id"])>0));
540
item["complex"] = (this.dLoad?(r.getAttribute("complex")!=null?true:false):(this._buildMenu(r,item["id"])>0));
541
if (this.dLoad && item["complex"]) { item["loaded"] = "no"; }
542
this.itemPull[item["id"]] = item;
543
// check for user data
544
for (var w=0; w<r.childNodes.length; w++) {
546
var tagNm = r.childNodes[w].tagName;
547
if (tagNm != null) { tagNm = tagNm.toLowerCase(); }
549
if (tagNm == this.userDataTagName) {
550
var d = r.childNodes[w];
551
if (d.getAttribute("name")!=null) { this.userData[item["id"]+"_"+d.getAttribute("name")] = (d.firstChild.nodeValue!=null?d.firstChild.nodeValue:""); }
553
// extended text, added in 0.4
554
if (tagNm == this.itemTextTagName) { item["title"] = r.childNodes[w].firstChild.nodeValue; }
555
// tooltips, added in 0.4
556
if (tagNm == this.itemTipTagName) { item["tip"] = r.childNodes[w].firstChild.nodeValue; }
557
// hotkeys, added in 0.4
558
if (tagNm == this.itemHotKeyTagName) { item["hotkey"] = r.childNodes[w].firstChild.nodeValue; }
565
/* parse incoming xml */
566
this._xmlParser = function() {
567
if (main_self.dLoad) {
568
var t = this.getXMLTopNode("menu");
569
parentId = (t.getAttribute("parentId")!=null?t.getAttribute("parentId"):null);
570
if (parentId == null) {
572
// main_self.idPrefix = main_self._genStr(12);
573
main_self._buildMenu(t, null);
574
main_self._initTopLevelMenu();
576
main_self._buildMenu(t, main_self.idPrefix+parentId);
577
main_self._addSubMenuPolygon(main_self.idPrefix+parentId, main_self.idPrefix+parentId);//, main_self.idPull[main_self.idPrefix+parentId]);
578
if (main_self.menuSelected == main_self.idPrefix+parentId) {
579
var pId = main_self.idPrefix+parentId;
580
var isTop = main_self.itemPull[main_self.idPrefix+parentId]["parent"]==main_self.idPrefix+main_self.topId;
581
var level = ((isTop&&(!main_self.context))?main_self.dirTopLevel:main_self.dirSubLevel);
583
if (isTop && main_self.menuModeTopLevelTimeout && main_self.menuMode == "web" && !main_self.context) {
584
var item = main_self.idPull[main_self.idPrefix+parentId];
585
if (item._mouseOver == true) {
586
var delay = main_self.menuModeTopLevelTimeoutTime - (new Date().getTime()-item._dynLoadTM);
588
item._menuOpenTM = window.setTimeout(function(){ main_self._showPolygon(pId, level); }, delay);
593
if (!isShow) { main_self._showPolygon(pId, level); }
595
main_self.itemPull[main_self.idPrefix+parentId]["loaded"] = "yes";
596
if (main_self.loaderIcon == true) { main_self._updateLoaderIcon(main_self.idPrefix+parentId, false); }
599
main_self.callEvent("onXLE",[]);
601
var t = this.getXMLTopNode("menu");
603
// main_self.idPrefix = main_self._genStr(12);
604
main_self._buildMenu(t, null);
606
main_self.callEvent("onXLE",[]);
607
main_self._doOnLoad();
610
this._xmlLoader = new dtmlXMLLoaderObject(this._xmlParser, window);
611
/* show sublevel item */
612
this._showSubLevelItem = function(id,back) {
613
if (document.getElementById("arrow_" + this.idPrefix + id) != null) { document.getElementById("arrow_" + this.idPrefix + id).style.display = (back?"none":""); }
614
if (document.getElementById("image_" + this.idPrefix + id) != null) { document.getElementById("image_" + this.idPrefix + id).style.display = (back?"none":""); }
615
if (document.getElementById(this.idPrefix + id) != null) { document.getElementById(this.idPrefix + id).style.display = (back?"":"none"); }
617
/* hide sublevel item */
618
this._hideSubLevelItem = function(id) {
619
this._showSubLevelItem(id,true)
621
// generating id prefix
622
this.idPrefix = this._genStr(12);
623
/* attach body events */
624
dhtmlxEvent(document.body, "click", main_self._clearAndHide);
625
dhtmlxEvent(document.body, "contextmenu", function(e){
626
if (main_self._skip_hide) { main_self._skip_hide=false; return; }
629
var testZone = e.target || e.srcElement;
630
if (testZone.id != null) { if (main_self.isContextZone(testZone.id)) { toHide = false; } }
631
if (toHide) { main_self.hideContextMenu(); }
638
dhtmlXMenuObject.prototype.init = function() {
639
if (this._isInited == true) { return; }
641
this.callEvent("onXLS", []);
642
// this._xmlLoader.loadXML(this.dLoadUrl+"?action=loadMenu&parentId="+this.topId+"&topId="+this.topId);
643
this._xmlLoader.loadXML(this.dLoadUrl+"?action=loadMenu&etc="+new Date().getTime()); // &&parentId=topId&"+this.topId+"&topId="+this.topId);
645
this._initTopLevelMenu();
646
this._isInited = true;
649
dhtmlXMenuObject.prototype._initTopLevelMenu = function() {
650
// console.log(this.idPull);
651
this.dirTopLevel = "bottom";
652
this.dirSubLevel = "right";
654
this.idPull[this.idPrefix+this.topId] = new Array(0,0);
656
// console.log(this.idPrefix+this.topId)
658
this._addSubMenuPolygon(this.idPrefix+this.topId, this.idPrefix+this.topId);//, null);
659
//console.log(this.idPull)
660
this._attachEvents();
662
var m = this._getMenuNodes(this.idPrefix + this.topId);
663
for (var q=0; q<m.length; q++) { this._renderToplevelItem(m[q], null); }
666
dhtmlXMenuObject.prototype._countVisiblePolygonItems = function(id) {
669
if ((this.idPull["polygon_"+id] != null) && (this.idPull[id] != null)) {
670
for (var q=0; q<this.idPull["polygon_"+id].childNodes.length; q++) {
671
var node = this.idPull["polygon_"+id].childNodes[q];
672
count += (((node.style.display=="none")||(node.className=="dhtmlxMenu_SubLevelArea_Separator"))?0:1);
678
// console.log(this.idPull)
679
for (var a in this.itemPull) {
681
var par = this.itemPull[a]["parent"];
682
var tp = this.itemPull[a]["type"];
683
if (this.idPull[a] != null) {
684
// console.log(this.idPull[a])
686
if (par == id && (tp == "item" || tp == "radio" || tp == "checkbox") && this.idPull[a].style.display != "none") {
693
dhtmlXMenuObject.prototype._redefineComplexState = function(id) {
695
if (this.idPrefix+this.topId == id) { return; }
696
if ((this.idPull["polygon_"+id] != null) && (this.idPull[id] != null)) {
697
var u = this._countVisiblePolygonItems(id);
698
if ((u > 0) && (!this.itemPull[id]["complex"])) { this._updateItemComplexState(id, true, false); }
699
if ((u == 0) && (this.itemPull[id]["complex"])) { this._updateItemComplexState(id, false, false); }
702
/* complex arrow manipulations, over added in 0.4 */
703
dhtmlXMenuObject.prototype._updateItemComplexState = function(id, state, over) {
704
// 0.2 FIX :: topLevel's items can have complex items with arrow
705
if ((!this.context) && (this._getItemLevelType(id.replace(this.idPrefix,"")) == "TopLevel")) {
706
// 30.06.2008 fix > complex state for top level item, state only, no arrow
707
this.itemPull[id]["complex"] = state;
710
if ((this.idPull[id] == null) || (this.itemPull[id] == null)) { return; }
712
this.itemPull[id]["complex"] = state;
713
// try to retrieve arrow img object
715
// fixed in 0.4 for context
716
if (id == this.idPrefix+this.topId) { return; }
718
for (var q=0; q<this.idPull[id].childNodes.length; q++) {
719
var node = this.idPull[id].childNodes[q];
720
if (node.id != null) { if (node.id == "arrow_"+id) { arrowObj = node; } }
722
if (this.itemPull[id]["complex"]) {
723
if (arrowObj == null) {
724
arrowObj = document.createElement("IMG");
725
arrowObj.className = "dhtmlxMenu_"+this.skin+"_SubLevelArea_Item_Arrow";
726
arrowObj.id = "arrow_"+id;
727
arrowObj.border = "0";
728
this.idPull[id].appendChild(arrowObj);
730
// over state added in 0.4
731
if (this.dLoad && (this.itemPull[id]["loaded"] == "get") && this.loaderIcon) {
732
var ldrImg = this.skinPath+"dhtmlxmenu_loader.gif";
733
if (arrowObj.src.search(ldrImg) == -1) { arrowObj.src = ldrImg; }
735
arrowObj.src = this.skinPath+"dhtmlxmenu_sub"+(this.itemPull[id]["state"]=="enabled"?(over?"over":"enable"):"disable")+".gif";
739
if ((!this.itemPull[id]["complex"]) && (arrowObj!=null)) {
740
this.idPull[id].removeChild(arrowObj);
741
if (this.itemPull[id]["hotkey_backup"] != null) { this.setHotKey(id.replace(this.idPrefix, ""), this.itemPull[id]["hotkey_backup"]); }
745
/* return css-part level type */
746
dhtmlXMenuObject.prototype._getItemLevelType = function(id) {
747
return (this.itemPull[this.idPrefix+id]["parent"]==this.idPrefix+this.topId?"TopLevel":"SubLevelArea");
750
/* enable/disable sublevel item */
751
dhtmlXMenuObject.prototype._changeItemState = function(id, newState, levelType) {
753
var j = this.idPrefix + id;
754
if ((this.itemPull[j] != null) && (this.idPull[j] != null)) {
755
if (this.itemPull[j]["state"] != newState) {
756
this.itemPull[j]["state"] = newState;
757
this.idPull[j].className = "dhtmlxMenu_"+this.skin+"_"+(!this.context?levelType:"SubLevelArea")+"_Item_"+(this.itemPull[j]["state"]=="enabled"?"Normal":"Disabled");
758
this._updateItemComplexState(this.idPrefix+id, this.itemPull[this.idPrefix+id]["complex"], false);
759
this._updateItemImage(id, levelType);
760
// if changeItemState attached to onClick event and changing applies to selected item all selection should be reparsed
761
if ((this.idPrefix + this.menuLastClicked == j) && (levelType != "TopLevel")) { this._redistribSubLevelSelection(j, this.itemPull[j]["parent"]); }
762
if (levelType == "TopLevel" && !this.context) { // rebuild style.left and show nested polygons
763
this._redistribTopLevelPositions();
764
this._redistribTopLevelSelection(id, "parent");
770
//#menu_overflow:06062008#{
771
/***************************************************************************************************************************************************************
775
***************************************************************************************************************************************************************/
776
/* clear all selected subitems in polygon, implemented in 0.4 */
777
dhtmlXMenuObject.prototype._clearAllSelectedSubItemsInPolygon = function(polygon) {
778
var subIds = this._getSubItemToDeselectByPolygon(polygon);
779
// hide opened polygons and selected items
780
for (var q=0; q<this._openedPolygons.length; q++) { if (this._openedPolygons[q] != polygon) { this._hidePolygon(this._openedPolygons[q]); } }
781
for (var q=0; q<subIds.length; q++) { if (this.idPull[subIds[q]] != null) { if (this.itemPull[subIds[q]]["state"] == "enabled") { this.idPull[subIds[q]].className = "dhtmlxMenu_"+this.skin+"_SubLevelArea_Item_Normal"; } } }
783
/* define normal/disabled arrows in polygon */
784
dhtmlXMenuObject.prototype._checkArrowsState = function(id) {
785
var polygon = this.idPull["polygon_"+id];
786
var arrowUp = this.idPull["arrowup_"+id];
787
var arrowDown = this.idPull["arrowdown_"+id];
788
if (polygon.scrollTop == 0) {
789
arrowUp.className = "dhtmlxMenu_"+this.skin+"_SubLevelArea_ArrowUp_Disabled";
791
arrowUp.className = "dhtmlxMenu_"+this.skin+"_SubLevelArea_ArrowUp" + (arrowUp.over ? "_Over" : "");
793
if (polygon.scrollTop + polygon.offsetHeight < polygon.scrollHeight) {
794
arrowDown.className = "dhtmlxMenu_"+this.skin+"_SubLevelArea_ArrowDown" + (arrowDown.over ? "_Over" : "");
796
arrowDown.className = "dhtmlxMenu_"+this.skin+"_SubLevelArea_ArrowDown_Disabled";
799
/* add up-limit-arrow */
800
dhtmlXMenuObject.prototype._addUpArrow = function(id) {
801
var main_self = this;
802
var arrow = document.createElement("DIV");
803
arrow.pId = this.idPrefix+id;
804
arrow.id = "arrowup_"+this.idPrefix+id;
805
arrow.className = "dhtmlxMenu_"+this.skin+"_SubLevelArea_ArrowUp";
806
arrow.innerHTML = "<div class='dhtmlxMenu_"+this.skin+"_SubLevelArea_Arrow'></div>";
807
arrow.style.display = "none";
810
arrow.onmouseover = function() {
811
if (main_self.menuMode == "web") { window.clearTimeout(main_self.menuTimeoutHandler); }
812
main_self._clearAllSelectedSubItemsInPolygon(this.pId);
813
if (this.className == "dhtmlxMenu_"+main_self.skin+"_SubLevelArea_ArrowUp_Disabled") { return; }
814
this.className = "dhtmlxMenu_"+main_self.skin+"_SubLevelArea_ArrowUp_Over";
816
main_self._canScrollUp = true;
817
main_self._doScrollUp(this.pId, true);
819
arrow.onmouseout = function() {
820
if (main_self.menuMode == "web") {
821
window.clearTimeout(main_self.menuTimeoutHandler);
822
main_self.menuTimeoutHandler = window.setTimeout(function(){main_self._clearAndHide();}, main_self.menuTimeoutMsec, "JavaScript");
825
main_self._canScrollUp = false;
826
if (this.className == "dhtmlxMenu_"+main_self.skin+"_SubLevelArea_ArrowUp_Disabled") { return; }
827
this.className = "dhtmlxMenu_"+main_self.skin+"_SubLevelArea_ArrowUp";
828
window.clearTimeout(main_self._scrollUpTM);
831
// var polygon = this.idPull["polygon_"+this.idPrefix+id];
832
// polygon.insertBefore(arrow, polygon.childNodes[0]);
833
document.body.appendChild(arrow);
834
this.idPull[arrow.id] = arrow;
836
dhtmlXMenuObject.prototype._addDownArrow = function(id) {
837
var main_self = this;
838
var arrow = document.createElement("DIV");
839
arrow.pId = this.idPrefix+id;
840
arrow.id = "arrowdown_"+this.idPrefix+id;
841
arrow.className = "dhtmlxMenu_"+this.skin+"_SubLevelArea_ArrowDown";
842
arrow.innerHTML = "<div class='dhtmlxMenu_"+this.skin+"_SubLevelArea_Arrow'></div>";
843
arrow.style.display = "none";
846
arrow.onmouseover = function() {
847
if (main_self.menuMode == "web") { window.clearTimeout(main_self.menuTimeoutHandler); }
848
main_self._clearAllSelectedSubItemsInPolygon(this.pId);
849
if (this.className == "dhtmlxMenu_"+main_self.skin+"_SubLevelArea_ArrowDown_Disabled") { return; }
850
this.className = "dhtmlxMenu_"+main_self.skin+"_SubLevelArea_ArrowDown_Over";
852
main_self._canScrollDown = true;
853
main_self._doScrollDown(this.pId, true);
855
arrow.onmouseout = function() {
856
if (main_self.menuMode == "web") {
857
window.clearTimeout(main_self.menuTimeoutHandler);
858
main_self.menuTimeoutHandler = window.setTimeout(function(){main_self._clearAndHide();}, main_self.menuTimeoutMsec, "JavaScript");
861
main_self._canScrollDown = false;
862
if (this.className == "dhtmlxMenu_"+main_self.skin+"_SubLevelArea_ArrowDown_Disabled") { return; }
863
this.className = "dhtmlxMenu_"+main_self.skin+"_SubLevelArea_ArrowDown";
864
window.clearTimeout(main_self._scrollDownTM);
867
// var polygon = this.idPull["polygon_"+this.idPrefix+id];
868
// polygon.insertBefore(arrow, polygon.childNodes[0]);
869
// polygon.appendChild(arrow);
870
document.body.appendChild(arrow);
871
this.idPull[arrow.id] = arrow;
873
dhtmlXMenuObject.prototype._removeUpArrow = function(id) {
876
dhtmlXMenuObject.prototype._removeDownArrow = function(id) {
879
dhtmlXMenuObject.prototype._isArrowExists = function(id) {
880
if (this.idPull["arrowup_"+id] != null && this.idPull["arrowdown_"+id] != null) { return true; }
884
dhtmlXMenuObject.prototype._doScrollUp = function(id, checkArrows) {
885
var polygon = this.idPull["polygon_"+id];
886
if (this._canScrollUp && polygon.scrollTop > 0) {
888
var nextScrollTop = polygon.scrollTop - this._scrollUpTMStep;
889
if (nextScrollTop < 0) {
893
polygon.scrollTop = nextScrollTop;
896
this._scrollUpTM = window.setTimeout(function() { that._doScrollUp(id, false); }, this._scrollUpTMTime);
899
this._canScrollUp = false;
900
this._checkArrowsState(id);
903
this._checkArrowsState(id);
906
dhtmlXMenuObject.prototype._doScrollDown = function(id, checkArrows) {
907
var polygon = this.idPull["polygon_"+id];
908
if (this._canScrollDown && polygon.scrollTop + polygon.offsetHeight <= polygon.scrollHeight) {
910
var nextScrollTop = polygon.scrollTop + this._scrollDownTMStep;
911
if (nextScrollTop + polygon.offsetHeight > polygon.scollHeight) {
913
nextScrollTop = polygon.scollHeight - polygon.offsetHeight;
915
polygon.scrollTop = nextScrollTop;
918
this._scrollDownTM = window.setTimeout(function() { that._doScrollDown(id, false); }, this._scrollDownTMTime);
922
this._checkArrowsState(id);
925
this._checkArrowsState(id);
929
dhtmlXMenuObject.prototype._countPolygonItems = function(id) {
931
for (var a in this.itemPull) {
932
var par = this.itemPull[a]["parent"];
933
var tp = this.itemPull[a]["type"];
934
if (par == this.idPrefix+id && (tp == "item" || tp == "radio" || tp == "checkbox")) { count++; }
938
/* limit maximum items on single polygon, default - 0 = no limit */
940
* @desc: limits the maximum number of visible items in polygons
941
* @param: itemsNum - count of the maximum number of visible items
944
dhtmlXMenuObject.prototype.setOverflowHeight = function(itemsNum) {
945
if (this.limit == 0 && itemsNum <= 0) { return; }
946
if (this.limit == 0 && itemsNum > 0) {
948
var needHeight = true;
950
for (var a in this.idPull) {
951
// collect polygons for adding arrows
952
if (a.match(/^polygon_/gi) != null) {
953
var id = a.replace("polygon_"+this.idPrefix, "");
954
// count items on polygon
955
var itemCount = this._countPolygonItems(id);
956
// var itemCount = this._countVisiblePolygonItems(this.idPrefix+id);
957
// add items where they are needed
958
if (itemCount > itemsNum) {
959
this._addDownArrow(id);
960
this._addUpArrow(id);
964
this.limit = itemsNum;
967
if (this.limit > 0 && itemsNum > 0) {
968
for (var a in this.idPull) {
969
// check arrows (del or add if needed)
970
if (a.match(/^polygon_/gi) != null) {
971
var id = a.replace("polygon_"+this.idPrefix, "");
972
var itemCount = this._countPolygonItems(id);
973
// var itemCount = this._countVisiblePolygonItems(this.idPrefix+id);
975
if (this._isArrowExists && itemCount <= itemsNum) {
976
this._removeDownArrow(id);
977
this._removeUpArrow(id);
979
if (!this._isArrowExists && itemCount > itemsNum) {
980
this._addDownArrow(id);
981
this._addUpArrow(id);
985
this.limit = itemsNum;
987
if (this.limit > 0 && itemsNum <= 0) {
993
/***************************************************************************************************************************************************************
997
***************************************************************************************************************************************************************/
998
dhtmlXMenuObject.prototype._redistribTopLevelPositions = function() {
1000
for (var q=0; q<this.base.childNodes.length; q++) {
1001
if (this.base.childNodes[q].tagName == "DIV") {
1002
this.base.childNodes[q].style.left = w + "px";
1003
w += this.base.childNodes[q].offsetWidth;
1008
/* redistrib selection in case of top node in real-time mode */
1009
dhtmlXMenuObject.prototype._redistribTopLevelSelection = function(id, parent) {
1010
// kick polygons and decelect before selected menues
1011
var i = this._getSubItemToDeselectByPolygon("parent");
1012
this._removeSubItemFromSelected(-1, -1);
1013
for (var q=0; q<i.length; q++) {
1014
if (i[q] != id) { this._hidePolygon(i[q]); }
1015
if ((this.idPull[i[q]] != null) && (i[q] != id)) { this.idPull[i[q]].className = this.idPull[i[q]].className.replace(/Selected/g, "Normal"); }
1018
if (this.itemPull[this.idPrefix+id]["state"] == "enabled") {
1019
this.idPull[this.idPrefix+id].className = "dhtmlxMenu_"+this.skin+"_TopLevel_Item_Selected";
1021
this._addSubItemToSelected(this.idPrefix+id, "parent");
1022
this.menuSelected = (this.menuMode=="win"?(this.menuSelected!=-1?id:this.menuSelected):id);
1023
if ((this.itemPull[this.idPrefix+id]["complex"]) && (this.menuSelected != -1)) { this._showPolygon(this.idPrefix+id, this.dirTopLevel); }
1028
* @desc: defines an url where necessary images are located
1029
* @param: path - url to images
1032
dhtmlXMenuObject.prototype.setImagePath = function(path) { this.skinPath = path+"dhxmenu_"+this.skin+"/"; }
1034
* @desc: defines an url where necessary user embedded icons are located
1035
* @param: path - url to images
1038
dhtmlXMenuObject.prototype.setIconsPath = function(path) { this.imagePath = path; }
1040
* @desc: alias for setIconsPath
1043
dhtmlXMenuObject.prototype.setIconPath = dhtmlXMenuObject.prototype.setIconsPath;
1045
* @desc: sets open mode for the menu
1046
* @param: mode - win|web, the default mode is web, in the win mode a user should click anywhere to hide the menu, in the web mode - just put the mouse pointer out of the menu area
1049
dhtmlXMenuObject.prototype.setOpenMode = function(mode) { if ((mode == "win") || (mode == "web")) { this.menuMode = mode; } else { this.menuMode == "web"; } }
1052
* @desc: enables an item
1053
* @param: id - item's id to enable
1054
* @param: state - true|false
1057
dhtmlXMenuObject.prototype.setItemEnabled = function(id) {
1059
this._changeItemState(id, "enabled", this._getItemLevelType(id));
1062
* @desc: disables an item
1063
* @param: id - item's id to disable
1066
dhtmlXMenuObject.prototype.setItemDisabled = function(id) {
1067
this._changeItemState(id, "disabled", this._getItemLevelType(id));
1070
* @desc: returns true if the item is enabled
1071
* @param: id - the item to check
1074
dhtmlXMenuObject.prototype.isItemEnabled = function(id) {
1075
return (this.itemPull[this.idPrefix+id]!=null?(this.itemPull[this.idPrefix+id]["state"]=="enabled"):false);
1079
* @desc: returns item's text
1080
* @param: id - the item
1083
dhtmlXMenuObject.prototype.getItemText = function(id) {
1084
return (this.itemPull[this.idPrefix+id]!=null?this.itemPull[this.idPrefix+id]["title"]:"");
1088
* @desc: sets text for the item
1089
* @param: id - the item
1090
* @param: text - a new text
1093
dhtmlXMenuObject.prototype.setItemText = function(id, text) {
1094
id = this.idPrefix + id;
1095
if ((this.itemPull[id] != null) && (this.idPull[id] != null)) {
1096
this.idPull[id].innerHTML = this.idPull[id].innerHTML.replace(this.itemPull[id]["title"], text);
1097
this.itemPull[id]["title"] = text;
1098
// if changeItemState attached to onClick event and changing applies to selected item all selection should be reparsed
1099
if (this.idPrefix + this.menuLastClicked == id) { this._redistribSubLevelSelection(id, this.itemPull[id]["parent"]); }
1100
// fix top level, added in 0.4
1101
if (this.itemPull[id]["parent"] == this.idPrefix+this.topId) {
1102
this._redistribTopLevelPositions();
1106
/* show/hide item in menu, optimized for version 0.3 */
1107
dhtmlXMenuObject.prototype._changeItemVisible = function(id, visible) {
1108
itemId = this.idPrefix+id;
1109
if (this.itemPull[itemId] == null) { return; }
1110
if (this.itemPull[itemId]["type"] == "separator") { itemId = "separator_"+itemId; }
1111
if (this.idPull[itemId] == null) { return; }
1112
this.idPull[itemId].style.display = (visible?"":"none");
1113
if (this._getItemLevelType(id) == "TopLevel") { this._redistribTopLevelPositions(); }
1114
this._redefineComplexState(this.itemPull[this.idPrefix+id]["parent"]);
1118
* @desc: hides an item
1119
* @param: id - the item to hide
1122
dhtmlXMenuObject.prototype.hideItem = function(id) {
1123
this._changeItemVisible(id, false);
1126
* @desc: shows an item
1127
* @param: id - the item to show
1130
dhtmlXMenuObject.prototype.showItem = function(id) {
1131
this._changeItemVisible(id, true);
1134
* @desc: returns true if the item is hidden
1135
* @param: id - the item to check
1138
dhtmlXMenuObject.prototype.isItemHidden = function(id) {
1139
var isHidden = null;
1140
if (this.idPull[this.idPrefix+id] != null) { isHidden = (this.idPull[this.idPrefix+id].style.display == "none"); }
1144
* @desc: loads menu data from an html and calls onLoadFunction when loading is done
1145
* @param: object - html data container
1146
* @param: clearAfterAdd - true|false, removes the container object after the data is loaded
1147
* @param: onLoadFunction - is called after the data is loaded (but before clearing html content if clear is set to true)
1150
dhtmlXMenuObject.prototype.loadFromHTML = function(objId, clearAfterAdd, onLoadFunction) {
1152
// this.idPrefix = this._genStr(12);
1153
this.itemTagName = "DIV";
1154
if (typeof(objId) == "string") { objId = document.getElementById(objId); }
1155
this._buildMenu(objId, null);
1157
if (clearAfterAdd) { objId.parentNode.removeChild(objId); }
1158
if (onLoadFunction != null) { onLoadFunction(); }
1160
//#menu_checks:06062008{
1161
/***************************************************************************************************************************************************************
1165
***************************************************************************************************************************************************************/
1166
dhtmlXMenuObject.prototype._getCheckboxState = function(id) {
1167
if (this.itemPull[this.idPrefix+id] == null) { return null; }
1168
return this.itemPull[this.idPrefix+id]["checked"];
1170
dhtmlXMenuObject.prototype._setCheckboxState = function(id, state) {
1171
if (this.itemPull[this.idPrefix+id] == null) { return; }
1172
this.itemPull[this.idPrefix+id]["checked"] = state;
1174
dhtmlXMenuObject.prototype._updateCheckboxImage = function(id) {
1175
if (this.idPull[this.idPrefix+id] == null) { return; }
1176
this.itemPull[this.idPrefix+id]["imgen"] = "dhtmlxmenu_chbx_" + (this._getCheckboxState(id)?"1":"0") + ".gif";
1177
this.itemPull[this.idPrefix+id]["imgdis"] = "dhtmlxmenu_chbxdis_" + (this._getCheckboxState(id)?"1":"0") + ".gif";
1178
// search image, not childNodes[0]
1179
this.idPull[this.idPrefix+id].childNodes[0].src = this.skinPath + (this.itemPull[this.idPrefix+id]["state"]=="enabled"?this.itemPull[this.idPrefix+id]["imgen"]:this.itemPull[this.idPrefix+id]["imgdis"]);
1181
dhtmlXMenuObject.prototype._checkboxOnClickHandler = function(id, type) {
1182
if (type.charAt(1)=="d") { return; }
1183
if (this.itemPull[this.idPrefix+id] == null) { return; }
1184
var state = this._getCheckboxState(id);
1185
if (this.checkEvent("onCheckboxClick")) {
1186
if (this.callEvent("onCheckboxClick", [id, state, this.contextMenuZoneId])) {
1187
this.setCheckboxState(id, !state);
1190
this.setCheckboxState(id, !state);
1194
* @desc: sets checkbox's state
1195
* @param: id - the item
1196
* @param: state - a new state
1199
dhtmlXMenuObject.prototype.setCheckboxState = function(id, state) {
1200
this._setCheckboxState(id, state);
1201
this._updateCheckboxImage(id);
1204
* @desc: returns current checkbox's state
1205
* @param: id - the item
1208
dhtmlXMenuObject.prototype.getCheckboxState = function(id) {
1209
return this._getCheckboxState(id);
1212
* @desc: adds a new checkbox, sibling|child mode
1213
* @param: mode - (string) sibling|child
1214
* @param: nextToId - the item after which the checkbox will be added in the "sibling" mode or parent item's id in the "child" mode
1215
* @param: pos - item's position in the child mode (null for sibling)
1216
* @param: itemId - id of a new checkbox
1217
* @param: itemText - text of a new checkbox
1218
* @param: state - checked|unchecked
1219
* @param: disabled - enabled|disabled
1222
dhtmlXMenuObject.prototype.addCheckbox = function(mode, nextToId, pos, itemId, itemText, state, disabled) {
1224
if (this.itemPull[this.idPrefix+nextToId] == null) { return; }
1225
if (this.itemPull[this.idPrefix+nextToId]["parent"] == this.idPrefix+this.topId) { return; }
1227
var img = "dhtmlxmenu_chbx_"+(state?"1":"0")+".gif";
1228
var imgDis = "dhtmlxmenu_chbxdis_"+(state?"1":"0")+".gif";
1230
if (mode == "sibling") {
1231
var id = this.idPrefix+(itemId!=null?itemId:this._genStr(24));
1232
var parentId = this.idPrefix+this.getParentId(nextToId);
1233
this._addItemIntoGlobalStrorage(id, parentId, itemText, "checkbox", disabled, img, imgDis);
1234
this._renderSublevelItem(id, this.getItemPosition(nextToId));
1236
var id = this.idPrefix+(itemId!=null?itemId:this._genStr(24));
1237
var parentId = this.idPrefix+nextToId;
1238
this._addItemIntoGlobalStrorage(id, parentId, itemText, "checkbox", disabled, img, imgDis);
1239
if (this.idPull["polygon_"+parentId] == null) { this._renderSublevelPolygon(parentId, parentId); }
1240
this._renderSublevelItem(id, pos-1);
1241
this._redefineComplexState(parentId);
1246
/***************************************************************************************************************************************************************
1250
***************************************************************************************************************************************************************/
1251
//#menu_userdata:06062008{
1253
* @desc: sets userdata for an item
1254
* @param: id - the item
1255
* @param: name - the name of userdata (string)
1256
* @param: value - the value of userdata (usually string)
1259
dhtmlXMenuObject.prototype.setUserData = function(id, name, value) {
1260
this.userData[this.idPrefix+id+"_"+name] = value;
1264
* @desc: returns item's userdata
1265
* @param: id - the item
1266
* @param: name - the name of userdata (string)
1269
dhtmlXMenuObject.prototype.getUserData = function(id, name) {
1270
return (this.userData[this.idPrefix+id+"_"+name]!=null?this.userData[this.idPrefix+id+"_"+name]:null);
1274
/* real-time update icon in menu */
1275
dhtmlXMenuObject.prototype._updateItemImage = function(id, levelType) {
1276
// search existsing image
1278
for (var q=0; q<this.idPull[this.idPrefix+id].childNodes.length; q++) {
1279
var node = this.idPull[this.idPrefix+id].childNodes[q];
1280
if (node.id != null) { if (node.id == "image_"+this.idPrefix+id) { imgObj = node; } }
1283
if (this.itemPull[this.idPrefix+id]["type"] == "radio") {
1284
var imgSrc = this.itemPull[this.idPrefix+id][(this.itemPull[this.idPrefix+id]["state"]=="enabled"?"imgen":"imgdis")];
1285
// console.log(this.itemPull[this.idPrefix+id])
1287
var imgSrc = this.itemPull[this.idPrefix+id][(this.itemPull[this.idPrefix+id]["state"]=="enabled"?"imgen":"imgdis")];
1289
if (imgSrc.length > 0) {
1290
if (imgObj != null) {
1291
imgObj.src = (this.itemPull[this.idPrefix+id]["type"]=="checkbox"||this.itemPull[this.idPrefix+id]["type"]=="radio"?this.skinPath:this.imagePath) + imgSrc;
1292
// imgObj.src = this.imagePath + imgSrc;
1294
var newImgObj = document.createElement("IMG");
1295
newImgObj.className = "dhtmlxMenu_"+this.skin+"_"+levelType+"_Item_Icon";
1296
newImgObj.src = this.imagePath + imgSrc;
1297
newImgObj.id = "image_"+this.idPrefix+id;
1298
newImgObj.border = 0;
1299
this.idPull[this.idPrefix+id].appendChild(newImgObj);
1300
if (levelType == "TopLevel") { this.idPull[this.idPrefix+id].style.paddingLeft = this.topLevelItemPaddingIconExists+"px"; }
1303
if (imgObj != null) {
1304
this.idPull[this.idPrefix+id].removeChild(imgObj);
1305
if (levelType == "TopLevel") { this.idPull[this.idPrefix+id].style.paddingLeft = this.topLevelItemPaddingIconNotExists+"px"; }
1311
* @desc: returns item's image - array(img, imgDis)
1312
* @param: id - the item
1315
dhtmlXMenuObject.prototype.getItemImage = function(id) {
1316
var imgs = new Array(null, null);
1317
id = this.idPrefix+id;
1318
if (this.itemPull[id]["type"] == "item") {
1319
imgs[0] = this.itemPull[id]["imgen"];
1320
imgs[1] = this.itemPull[id]["imgdis"];
1325
* @desc: sets an image for the item
1326
* @param: id - the item
1327
* @param: img - the image for the enabled item (empty string for none)
1328
* @param: imgDis - the image for the disabled item (empty string for none)
1331
dhtmlXMenuObject.prototype.setItemImage = function(id, img, imgDis) {
1332
if (this.itemPull[this.idPrefix+id]["type"] != "item") { return; }
1333
this.itemPull[this.idPrefix+id]["imgen"] = img;
1334
this.itemPull[this.idPrefix+id]["imgdis"] = imgDis;
1335
this._updateItemImage(id, this._getItemLevelType(id));
1336
this._redistribTopLevelPositions();
1340
* @desc: removes both enabled and disabled item images
1341
* @param: id - the item
1344
dhtmlXMenuObject.prototype.clearItemImage = function(id) {
1345
this.setItemImage(id, "", "");
1348
* @desc: sets hide menu timeout (web mode only)
1349
* @param: tm - timeout, ms, 400 default
1352
dhtmlXMenuObject.prototype.setWebModeTimeout = function(tm) {
1353
this.menuTimeoutMsec = (!isNaN(tm)?tm:400);
1355
//#menu_radio:06062008{
1356
/***************************************************************************************************************************************************************
1360
***************************************************************************************************************************************************************/
1361
dhtmlXMenuObject.prototype._getRadioImgObj = function(id) {
1363
for (var q=0; q<this.idPull[this.idPrefix+id].childNodes.length; q++) {
1364
var node = this.idPull[this.idPrefix+id].childNodes[q];
1365
if (node.id != null) { if (node.id == "image_"+this.idPrefix+id) { imgObj = node; } }
1369
dhtmlXMenuObject.prototype._setRadioState = function(id, state) {
1370
// if (this.itemPull[this.idPrefix+id]["state"] != "enabled") { return; }
1371
var imgObj = this._getRadioImgObj(id);
1372
if (imgObj != null) {
1373
// fix, added in 0.4
1374
var rObj = this.itemPull[this.idPrefix+id];
1375
rObj["checked"] = state;
1376
rObj["imgen"] = "dhtmlxmenu_rdbt_"+(rObj["checked"]?"1":"0")+".gif";
1377
rObj["imgdis"] = "dhtmlxmenu_rdbtdis_"+(rObj["checked"]?"1":"0")+".gif";
1378
imgObj.src = this.skinPath + (rObj["state"]=="disabled"?rObj["imgdis"]:rObj["imgen"]);
1381
dhtmlXMenuObject.prototype._radioOnClickHandler = function(id, type) {
1382
if ((type.charAt(1)=="d") || (this.itemPull[this.idPrefix+id]["group"]==null)) { return; }
1383
// deselect all from the same group
1384
var group = this.itemPull[this.idPrefix+id]["group"];
1385
if (this.checkEvent("onRadioClick")) {
1386
if (this.callEvent("onRadioClick", [group, this.getRadioChecked(group), id, this.contextMenuZoneId])) {
1387
this.setRadioChecked(group, id);
1390
this.setRadioChecked(group, id);
1394
* @desc: returns a checked radio button in the group
1395
* @param: group - radio button group
1398
dhtmlXMenuObject.prototype.getRadioChecked = function(group) {
1400
for (var q=0; q<this.radio[group].length; q++) {
1401
var itemId = this.radio[group][q].replace(this.idPrefix, "");
1402
var imgObj = this._getRadioImgObj(itemId);
1403
if (imgObj != null) {
1404
var checked = (imgObj.src).match(/dhtmlxmenu_rdbt_1\.gif$/gi);
1405
if (checked != null) { id = itemId; }
1411
* @desc: checks a radio button inside the group
1412
* @param: group - radio button group
1413
* @param: id - radio button's id
1416
dhtmlXMenuObject.prototype.setRadioChecked = function(group, id) {
1417
if (this.radio[group] == null) { return; }
1418
for (var q=0; q<this.radio[group].length; q++) {
1419
var itemId = this.radio[group][q].replace(this.idPrefix, "");
1420
this._setRadioState(itemId, (itemId==id));
1424
* @desc: adds a new radio button, sibling|child mode
1425
* @param: mode - (string) sibling|child
1426
* @param: nextToId - the item after which the radio button will be added in the "sibling" mode or parent item's id in the "child" mode
1427
* @param: pos - the item's position in the child mode (null for sibling)
1428
* @param: itemId - id of a new radio button
1429
* @param: itemText - text of a new radio button
1430
* @param: group - radiogroup's id
1431
* @param: state - checked|unchecked
1432
* @param: disabled - enabled|disabled
1435
dhtmlXMenuObject.prototype.addRadioButton = function(mode, nextToId, pos, itemId, itemText, group, state, disabled) {
1437
if (this.itemPull[this.idPrefix+nextToId] == null) { return; }
1438
if (this.itemPull[this.idPrefix+nextToId]["parent"] == this.idPrefix+this.topId) { return; }
1441
var img = "dhtmlxmenu_rdbt_"+(state?"1":"0")+".gif";
1442
var imgDis = "dhtmlxmenu_rdbtdis_"+(state?"1":"0")+".gif";
1444
if (mode == "sibling") {
1445
var id = this.idPrefix+(itemId!=null?itemId:this._genStr(24));
1446
var parentId = this.idPrefix+this.getParentId(nextToId);
1447
this._addItemIntoGlobalStrorage(id, parentId, itemText, "radio", disabled, img, imgDis);
1448
this._renderSublevelItem(id, this.getItemPosition(nextToId));
1450
var id = this.idPrefix+(itemId!=null?itemId:this._genStr(24));
1451
var parentId = this.idPrefix+nextToId;
1452
this._addItemIntoGlobalStrorage(id, parentId, itemText, "radio", disabled, img, imgDis);
1453
if (this.idPull["polygon_"+parentId] == null) { this._renderSublevelPolygon(parentId, parentId); }
1454
this._renderSublevelItem(id, pos-1);
1455
this._redefineComplexState(parentId);
1458
var gr = (group!=null?group:this._genStr(24));
1459
this.itemPull[id]["group"] = gr;
1461
if (this.radio[gr]==null) { this.radio[gr] = new Array(); }
1462
this.radio[gr][this.radio[gr].length] = id;
1472
/* export to function */
1474
dhtmlXMenuObject.prototype.generateSQL = function() {
1475
var sql = "INSERT INTO `dhtmlxmenu_demo` (`itemId`, `itemParentId`, `itemOrder`, `itemText`, `itemType`, `itemEnabled`, `itemChecked`, `itemGroup`, `itemImage`, `itemImageDis`) VALUES ";
1478
for (var a in this.itemPull) {
1479
values += (values.length>0?", ":"")+"('"+a.replace(this.idPrefix,"")+"',"+
1480
"'"+(this.itemPull[a]["parent"]!=null?this.itemPull[a]["parent"].replace(this.idPrefix,""):"")+"',"+
1482
"'"+this.itemPull[a]["title"]+"',"+
1483
"'"+(this.itemPull[a]["type"]!="item"?this.itemPull[a]["type"]:"")+"',"+
1484
"'"+(this.itemPull[a]["state"]=="enabled"?"1":"0")+"',"+
1485
"'"+(this.itemPull[a]["checked"]!=null?(this.itemPull[a]["checked"]?"1":"0"):"0")+"',"+
1486
"'"+(this.itemPull[a]["group"]!=null?this.itemPull[a]["group"]:"")+"',"+
1487
"'"+this.itemPull[a]["imgen"]+"',"+
1488
"'"+this.itemPull[a]["imgdis"]+"')";
1495
* @desc: enables dynamic loading of sublevels
1496
* @param: url - server-side script, transmitted params are action=loadMenu and parentId
1497
* @param: icon - true|false, replaces elemet's arrow with loading image while loading
1500
dhtmlXMenuObject.prototype.enableDynamicLoading = function(url, icon) {
1502
this.dLoadUrl = url;
1503
this.loaderIcon = icon;
1506
/* internal, show/hide loader icon */
1507
dhtmlXMenuObject.prototype._updateLoaderIcon = function(id, state) {
1508
if (this.idPull[id] == null) { return; }
1509
for (var q=0; q<this.idPull[id].childNodes.length; q++) {
1510
if (this.idPull[id].childNodes[q].tagName == "IMG") {
1511
if (this.idPull[id].childNodes[q].className == "dhtmlxMenu_"+this.skin+"_SubLevelArea_Item_Arrow" + (state?"":"_Loading")) {
1512
this.idPull[id].childNodes[q].className = "dhtmlxMenu_"+this.skin+"_SubLevelArea_Item_Arrow" + (state?"_Loading":"");
1513
this.idPull[id].childNodes[q].src = this.skinPath + "dhtmlxmenu_" + (state?"loader":"subenable") + ".gif";
1520
* @desc: removes an item from the menu with all nested sublevels
1521
* @param: id - id of the item for removing
1524
dhtmlXMenuObject.prototype.removeItem = function(id) {
1525
id = this.idPrefix + id;
1526
if (this.itemPull[id] == null) { return; }
1528
var parentId = this.itemPull[id]["parent"];
1530
if (this.itemPull[id]["type"] == "separator") {
1531
this.idPull["separator_"+id].parentNode.removeChild(this.idPull["separator_"+id]);
1532
delete this.idPull["separator_"+id];
1533
delete this.itemPull[id];
1536
// complex/single item
1537
if (this.itemPull[id]["complex"]) {
1538
var items = this._getAllParents(id);
1539
items[items.length] = id;
1540
var polygons = new Array();
1541
for (var q=0; q<items.length; q++) {
1542
if (this.itemPull[items[q]]["type"] == "separator") {
1543
this.removeItem(items[q].replace(this.idPrefix,""));
1545
if (this.itemPull[items[q]]["complex"]) { polygons[polygons.length] = items[q]; }
1546
this.idPull[items[q]].parentNode.removeChild(this.idPull[items[q]]);
1547
delete this.idPull[items[q]];
1548
delete this.itemPull[items[q]];
1551
for (var q=0; q<polygons.length; q++) {
1552
this.idPull["polygon_"+polygons[q]].parentNode.removeChild(this.idPull["polygon_"+polygons[q]]);
1554
var pId = "polygon_"+polygons[q]+"_ie6cover";
1555
if (this.idPull[pId] != null) { document.body.removeChild(this.idPull[pId]); delete this.idPull[pId]; }
1557
delete this.idPull["polygon_"+polygons[q]];
1558
delete this.itemPull[polygons[q]];
1560
if (!this.context) { this._redistribTopLevelPositions(); }
1562
this.idPull[id].parentNode.removeChild(this.idPull[id]);
1563
delete this.idPull[id];
1564
delete this.itemPull[id];
1567
// checking existing empty polygon
1568
if (this.idPull["polygon_"+parentId] != null) {
1569
if (this.idPull["polygon_"+parentId].childNodes.length == 0) {
1570
document.body.removeChild(this.idPull["polygon_"+parentId]);
1572
var pId = "polygon_"+parentId+"_ie6cover";
1573
if (this.idPull[pId] != null) { document.body.removeChild(this.idPull[pId]); delete this.idPull[pId]; }
1575
delete this.idPull["polygon_"+parentId];
1576
this._updateItemComplexState(parentId, false, false);
1580
/* collect parents for remove complex item */
1581
dhtmlXMenuObject.prototype._getAllParents = function(id) {
1582
var parents = new Array();
1583
for (var a in this.itemPull) {
1584
if (this.itemPull[a]["parent"] == id) {
1585
parents[parents.length] = this.itemPull[a]["id"];
1586
if (this.itemPull[a]["complex"]) {
1587
var t = this._getAllParents(this.itemPull[a]["id"]);
1588
for (var q=0; q<t.length; q++) { parents[parents.length] = t[q]; }
1594
//#menu_context:06062008{
1595
/* render dhtmlxMenu as context menu of base object */
1597
* @desc: renders menu as contextual
1600
dhtmlXMenuObject.prototype.renderAsContextMenu = function() {
1601
this.context = true;
1602
if (this.base._autoSkinUpdate == true) {
1603
this.base.className = this.base.className.replace("dhtmlxMenu_"+this.skin+"_Middle","");
1604
this.base._autoSkinUpdate = false;
1606
if (this.addBaseIdAsContextZone != null) { this.addContextZone(this.addBaseIdAsContextZone); }
1609
* @desc: adds a contextual zone to a contextual menu
1610
* @param: zoneId - id of the object on page to render as a contextual zone
1613
dhtmlXMenuObject.prototype.addContextZone = function(zoneId) {
1614
var zone = document.getElementById(zoneId);
1615
var zoneExists = false;
1616
for (var a in this.contextZones) { zoneExists = zoneExists || (a == zoneId) || (this.contextZones[a] == zone); }
1617
if (zoneExists == true) { return false; }
1618
this.contextZones[zoneId] = zone;
1619
var main_self = this;
1620
if (zone.oncontextmenu != null) { zone._oldContextMenuHandler = zone.oncontextmenu; }
1621
zone.oncontextmenu = function(e) {
1623
main_self.contextMenuZoneId = this.id;
1624
main_self._clearAndHide();
1625
main_self._hideContextMenu();
1626
if (main_self.checkEvent("onBeforeContextMenu")) {
1627
if (main_self.callEvent("onBeforeContextMenu", [this.id])) {
1628
if (main_self.contextAutoShow) {
1629
main_self._showContextMenu(e.clientX, e.clientY);
1630
main_self.callEvent("onAfterContextMenu", [this.id]);
1634
if (main_self.contextAutoShow) {
1635
main_self._showContextMenu(e.clientX, e.clientY);
1636
main_self.callEvent("onAfterContextMenu", [this.id]);
1644
* @desc: removes an object from contextual zones list
1645
* @param: zoneId - id of a contextual zone
1648
dhtmlXMenuObject.prototype.removeContextZone = function(zoneId) {
1649
if (!this.isContextZone(zoneId)) { return false; }
1650
var zone = this.contextZones[zoneId];
1651
if (zone._oldContextMenuHandler != null) {
1652
zone.oncontextmenu = zone._oldContextMenuHandler;
1654
zone.oncontextmenu = null; // function() { return true; }
1656
delete this.contextZones[zoneId];
1660
* @desc: returns true if an object is used as a contextual zone for the menu
1661
* @param: zoneId - id of the object to check
1664
dhtmlXMenuObject.prototype.isContextZone = function(zoneId) {
1666
if (this.contextZones[zoneId] != null) { if (this.contextZones[zoneId] == document.getElementById(zoneId)) { isZone = true; } }
1669
dhtmlXMenuObject.prototype._isContextMenuVisible = function() {
1670
if (this.idPull["polygon_"+this.idPrefix+this.topId] == null) { return false; }
1671
return (this.idPull["polygon_"+this.idPrefix+this.topId].style.display == "");
1673
dhtmlXMenuObject.prototype._showContextMenu = function(x, y, zoneId) {
1674
// hide any opened context menu/polygons
1676
this._clearAndHide();
1677
this._hideContextMenu();
1680
if (this.idPull["polygon_"+this.idPrefix+this.topId] == null) { return false; }
1681
this.idPull[this.idPrefix+this.topId] = new Array(x, y);
1682
this._showPolygon(this.idPrefix+this.topId, "bottom");
1683
this.callEvent("onContextMenu", [zoneId]);
1685
dhtmlXMenuObject.prototype._hideContextMenu = function() {
1686
if (this.idPull["polygon_"+this.idPrefix+this.topId] == null) { return false; }
1687
this._clearAndHide();
1688
this._hidePolygon(this.idPrefix+this.topId);
1689
this.zInd = this.zIndInit;
1691
dhtmlXMenuObject.prototype._attachEvents = function() {
1692
var main_self = this;
1693
dhtmlxEvent(document.body, "click", function(){
1694
if (main_self._isContextMenuVisible() && main_self.contextAutoHide) { main_self._hideContextMenu(); }
1697
/* public: user call for show/hide context menu */
1699
* @desc: usercall to show a contextual menu
1700
* @param: x - position of the menu on x axis
1701
* @param: y - position of the menu on y axis
1704
dhtmlXMenuObject.prototype.showContextMenu = function(x, y) {
1705
this._showContextMenu(x, y, false);
1708
* @desc: usercall to hide a contextual menu
1711
dhtmlXMenuObject.prototype.hideContextMenu = function() {
1712
this._hideContextMenu();
1714
/* public: context menu auto open/close enable/disable */
1716
* @desc: sets to false to prevent showing a contextual menu by a click
1717
* @param: mode - true/false
1720
dhtmlXMenuObject.prototype.setAutoShowMode = function(mode) {
1721
this.contextAutoShow = (mode==true?true:false);
1724
* @desc: sets to false to prevent hiding a contextual menu by a click
1725
* @param: mode - true/false
1728
dhtmlXMenuObject.prototype.setAutoHideMode = function(mode) {
1729
this.contextAutoHide = (mode==true?true:false);
1734
* @desc: sets the area in which the menu can appear, if the area is not set, the menu will occupy all available visible space
1735
* @param: x1, x2 - int, leftmost and rightmost coordinates by x axis
1736
* @param: y1, y2 - int, topmost and bottommost coordinates by y axis
1739
dhtmlXMenuObject.prototype.setVisibleArea = function(x1, x2, y1, y2) {
1745
/* inner - returns true if prognozided polygon layout off the visible area */
1746
/*dhtmlXMenuObject.prototype._isInVisibleArea = function(x, y, w, h) {
1747
return ((x >= this.menuX1) && (x+w<=this.menuX2) && (y >= this.menuY1) && (y+h <= this.menuY2));
1751
* @desc: returns item's position in the current polygon
1752
* @param: id - the item
1755
dhtmlXMenuObject.prototype.getItemPosition = function(id) {
1756
id = this.idPrefix+id;
1758
if (this.itemPull[id] == null) { return pos; }
1759
var parent = this.itemPull[id]["parent"];
1760
var obj = (this.idPull["polygon_"+parent]!=null?this.idPull["polygon_"+parent]:this.base);
1761
for (var q=0; q<obj.childNodes.length; q++) { if (obj.childNodes[q]==this.idPull["separator_"+id]||obj.childNodes[q]==this.idPull[id]) { pos = q; } }
1766
* @desc: sets new item's position in the current polygon (moves an item inside the single level)
1767
* @param: id - the item
1768
* @param: pos - the position (int)
1771
dhtmlXMenuObject.prototype.setItemPosition = function(id, pos) {
1772
id = this.idPrefix+id;
1773
if (this.idPull[id] == null) { return; }
1775
var isOnTopLevel = (this.itemPull[id]["parent"] == this.idPrefix+this.topId);
1777
var itemData = this.idPull[id];
1778
var itemPos = this.getItemPosition(id.replace(this.idPrefix,""));
1779
var parent = this.itemPull[id]["parent"];
1780
var obj = (this.idPull["polygon_"+parent]!=null?this.idPull["polygon_"+parent]:this.base);
1781
obj.removeChild(obj.childNodes[itemPos]);
1782
if (pos < 0) { pos = 0; }
1784
if (isOnTopLevel && pos < 1) { pos = 1; }
1786
if (pos < obj.childNodes.length) { obj.insertBefore(itemData, obj.childNodes[pos]); } else { obj.appendChild(itemData); }
1788
if (isOnTopLevel) { this._redistribTopLevelPositions(); }
1792
* @desc: returns parent's id
1793
* @param: id - the item
1796
dhtmlXMenuObject.prototype.getParentId = function(id) {
1797
id = this.idPrefix+id;
1798
if (this.itemPull[id] == null) { return null; }
1799
return ((this.itemPull[id]["parent"]!=null?this.itemPull[id]["parent"]:this.topId).replace(this.idPrefix,""));
1801
/* public: add item */
1804
* @desc: adds a new sibling item
1805
* @param: nextToId - id of the element after which a new one will be inserted
1806
* @param: itemId - id of a new item
1807
* @param: itemText - text of a new item
1808
* @param: disabled - true|false, whether the item is disabled or not
1809
* @param: img - image for the enabled item
1810
* @param: imgDis - image for the disabled item
1813
dhtmlXMenuObject.prototype.addNewSibling = function(nextToId, itemId, itemText, disabled, imgEnabled, imgDisabled) {
1814
var id = this.idPrefix+(itemId!=null?itemId:this._genStr(24));
1815
var parentId = this.idPrefix+(nextToId!=null?this.getParentId(nextToId):this.topId);
1816
// console.log(id, parentId)
1817
// console.log(id, ",", parentId)
1818
this._addItemIntoGlobalStrorage(id, parentId, itemText, "item", disabled, imgEnabled, imgDisabled);
1819
if ((parentId == this.idPrefix+this.topId) && (!this.context)) { this._renderToplevelItem(id, this.getItemPosition(nextToId)); } else { this._renderSublevelItem(id, this.getItemPosition(nextToId)); }
1820
// this._redistribTopLevelPositions();
1824
* @desc: adds a new child item
1825
* @param: parentId - the item which will contain a new item in the sublevel
1826
* @param: position - the position of a new item
1827
* @param: itemId - id of a new item
1828
* @param: itemText - text of a new item
1829
* @param: disabled - true|false, whether the item is disabled or not
1830
* @param: img - image for the enabled item
1831
* @param: imgDis - image for the disabled item
1834
dhtmlXMenuObject.prototype.addNewChild = function(parentId, pos, itemId, itemText, disabled, imgEnabled, imgDisabled) {
1835
itemId = this.idPrefix+(itemId!=null?itemId:this._genStr(24));
1836
if (parentId == null) { parentId = this.topId; }
1837
// remove hotkey, added in 0.4
1838
this.setHotKey(parentId, "");
1840
parentId = this.idPrefix+parentId;
1841
this._addItemIntoGlobalStrorage(itemId, parentId, itemText, "item", disabled, imgEnabled, imgDisabled);
1842
if (this.idPull["polygon_"+parentId] == null) { this._renderSublevelPolygon(parentId, parentId); }
1843
this._renderSublevelItem(itemId, pos-1);
1844
// console.log(parentId)
1845
this._redefineComplexState(parentId);
1849
* @desc: add a new separator
1850
* @param: nextToId - id of the element after which a new separator will be inserted
1851
* @param: itemId - id of a new separator
1852
* @param: disabled - true|false, whether the item is disabled or not
1855
dhtmlXMenuObject.prototype.addNewSeparator = function(nextToId, itemId) { //, disabled) {
1856
itemId = this.idPrefix+(itemId!=null?itemId:this._genStr(24));
1857
var parentId = this.idPrefix+this.getParentId(nextToId);
1858
if ((parentId == this.idPrefix+this.topId) && (!this.context)) { return; }
1859
// this._addItemIntoGlobalStrorage(itemId, parentId, "", "item", disabled, "", "");
1860
// this._addItemIntoGlobalStrorage(itemId, parentId, "", "item", false, "", "");
1861
this._addItemIntoGlobalStrorage(itemId, parentId, "", "separator", false, "", "");
1862
this._renderSeparator(itemId, this.getItemPosition(nextToId));
1864
/* add item to storage */
1865
dhtmlXMenuObject.prototype._addItemIntoGlobalStrorage = function(itemId, itemParentId, itemText, itemType, disabled, img, imgDis) {
1869
imgen:(img!=null?img:""),
1870
imgdis:(imgDis!=null?imgDis:""),
1872
state:(disabled==true?"disabled":"enabled"),
1873
parent:itemParentId,
1877
this.itemPull[item.id] = item;
1879
/* add top menu item, complex define that submenues are in presence */
1880
dhtmlXMenuObject.prototype._renderToplevelItem = function(id, pos) {
1881
var main_self = this;
1882
var m = document.createElement("DIV");
1885
if (this.itemPull[id]["state"] == "enabled" && this.itemPull[id]["cssNormal"] != null) {
1886
m.className = this.itemPull[id]["cssNormal"];
1888
m.className = "dhtmlxMenu_"+this.skin+"_TopLevel_Item_"+(this.itemPull[id]["state"]=="enabled"?"Normal":"Disabled");
1890
m.innerHTML = this.itemPull[id]["title"];
1891
// tooltip, added in 0.4
1892
if (this.itemPull[id]["tip"].length > 0) { m.title = this.itemPull[id]["tip"]; }
1894
// image in top level
1895
if ((this.itemPull[id]["imgen"]!="")||(this.itemPull[id]["imgdis"]!="")) {
1896
var imgTop=this.itemPull[id][(this.itemPull[id]["state"]=="enabled")?"imgen":"imgdis"];
1898
var imgTop = "<img id='image_"+id+"' src='"+this.imagePath+imgTop+"' class='dhtmlxMenu_"+this.skin+"_TopLevel_Item_Icon' border='0'>";
1899
m.innerHTML = imgTop+m.innerHTML;
1900
m.style.paddingLeft = this.topLevelItemPaddingIconExists+"px";
1903
m.onselectstart = function(e) { e = e || event; e.returnValue = false; }
1905
for (var q=0; q<this.base.childNodes.length; q++) { if (!isNaN(this.base.childNodes[q].offsetWidth)) { w = w + this.base.childNodes[q].offsetWidth; } }
1906
m.style.left = w + "px";
1907
// remove selectable
1908
if (pos != null) { pos++; if (pos < 0) { pos = 0; } if (pos > this.base.childNodes.length - 1) { pos = null; } }
1909
if (pos != null) { this.base.insertBefore(m, this.base.childNodes[pos]); this._redistribTopLevelPositions(); } else { this.base.appendChild(m); }
1911
// this.base.appendChild(m);
1912
this.idPull[m.id] = m;
1914
if (this.itemPull[id]["complex"] && (!this.dLoad)) { this._addSubMenuPolygon(this.itemPull[id]["id"], this.itemPull[id]["id"]); }//, m); }
1915
m.onmouseover = function() {
1916
if (main_self.menuMode == "web") { window.clearTimeout(main_self.menuTimeoutHandler); }
1917
// kick polygons and decelect before selected menues
1918
var i = main_self._getSubItemToDeselectByPolygon("parent");
1919
main_self._removeSubItemFromSelected(-1, -1);
1920
for (var q=0; q<i.length; q++) {
1921
if (i[q] != this.id) { main_self._hidePolygon(i[q]); }
1922
if ((main_self.idPull[i[q]] != null) && (i[q] != this.id)) {
1924
if (main_self.itemPull[i[q]]["cssNormal"] != null) {
1925
main_self.idPull[i[q]].className = main_self.itemPull[i[q]]["cssNormal"];
1927
main_self.idPull[i[q]].className = main_self.idPull[i[q]].className.replace(/Selected/g, "Normal");
1932
if (main_self.itemPull[this.id]["state"] == "enabled") {
1933
this.className = "dhtmlxMenu_"+main_self.skin+"_TopLevel_Item_Selected";
1935
main_self._addSubItemToSelected(this.id, "parent");
1936
main_self.menuSelected = (main_self.menuMode=="win"?(main_self.menuSelected!=-1?this.id:main_self.menuSelected):this.id);
1937
if (main_self.dLoad && (main_self.itemPull[this.id]["loaded"]=="no")) {
1938
if (main_self.menuModeTopLevelTimeout && main_self.menuMode == "web" && !main_self.context) {
1939
this._mouseOver = true;
1940
this._dynLoadTM = new Date().getTime();
1942
var xmlLoader = new dtmlXMLLoaderObject(main_self._xmlParser, window);
1943
main_self.itemPull[this.id]["loaded"] = "get";
1944
main_self.callEvent("onXLS", []);
1945
xmlLoader.loadXML(main_self.dLoadUrl+"?action=loadMenu&parentId="+this.id.replace(main_self.idPrefix,"")+"&etc="+new Date().getTime());
1947
if ((!main_self.dLoad) || (main_self.dLoad && (main_self.itemPull[this.id]["loaded"]=="yes"))) {
1948
if ((main_self.itemPull[this.id]["complex"]) && (main_self.menuSelected != -1)) {
1949
if (main_self.menuModeTopLevelTimeout && main_self.menuMode == "web" && !main_self.context) {
1950
this._mouseOver = true;
1951
var showItemId = this.id;
1952
this._menuOpenTM = window.setTimeout(function(){main_self._showPolygon(showItemId, main_self.dirTopLevel);}, main_self.menuModeTopLevelTimeoutTime);
1954
main_self._showPolygon(this.id, main_self.dirTopLevel);
1959
main_self._doOnTouchMenu(this.id.replace(main_self.idPrefix, ""));
1961
m.onmouseout = function() {
1962
if (!((main_self.itemPull[this.id]["complex"]) && (main_self.menuSelected != -1)) && (main_self.itemPull[this.id]["state"]=="enabled")) {
1964
// console.log(main_self.itemPull[this.id])
1965
if (main_self.itemPull[this.id]["cssNormal"] != null) {
1967
m.className = main_self.itemPull[this.id]["cssNormal"];
1970
m.className = "dhtmlxMenu_"+main_self.skin+"_TopLevel_Item_Normal";
1973
if (main_self.menuMode == "web") {
1974
window.clearTimeout(main_self.menuTimeoutHandler);
1975
main_self.menuTimeoutHandler = window.setTimeout(function(){main_self._clearAndHide();}, main_self.menuTimeoutMsec, "JavaScript");
1977
if (main_self.menuModeTopLevelTimeout && main_self.menuMode == "web" && !main_self.context) {
1978
this._mouseOver = false;
1979
window.clearTimeout(this._menuOpenTM);
1982
m.onclick = function(e) {
1983
if (main_self.menuMode == "web") { window.clearTimeout(main_self.menuTimeoutHandler); }
1984
// fix, added in 0.4
1985
if (main_self.menuMode != "web" && main_self.itemPull[this.id]["state"] == "disabled") { return; }
1988
e.cancelBubble = true;
1989
if (main_self.menuMode == "win") {
1990
if (main_self.itemPull[this.id]["complex"]) {
1991
if (main_self.menuSelected == this.id) { main_self.menuSelected = -1; var s = false; } else { main_self.menuSelected = this.id; var s = true; }
1992
if (s) { main_self._showPolygon(this.id, main_self.dirTopLevel); } else { main_self._hidePolygon(this.id); }
1995
var tc = (main_self.itemPull[this.id]["complex"]?"c":"-");
1996
var td = (main_self.itemPull[this.id]["state"]!="enabled"?"d":"-");
1997
main_self._doOnClick(this.id.replace(main_self.idPrefix, ""), tc+td+"t");
2000
/* recursively creates and adds submenu polygon */
2001
dhtmlXMenuObject.prototype._addSubMenuPolygon = function(id, parentId) {
2002
var s = this._renderSublevelPolygon(id, parentId);
2003
var j = this._getMenuNodes(parentId);
2004
for (q=0; q<j.length; q++) { if (this.itemPull[j[q]]["type"] == "separator") { this._renderSeparator(j[q], null); } else { this._renderSublevelItem(j[q], null); } }
2005
if (id == parentId) { var level = "topLevel"; } else { var level = "subLevel"; }
2006
this.subMenuData[this.subMenuData.length] = new Array(id, s, level);
2007
for (var q=0; q<j.length; q++) { if (this.itemPull[j[q]]["complex"]) { this._addSubMenuPolygon(id, this.itemPull[j[q]]["id"]); } }
2009
/* inner: add single subpolygon/item/separator */
2010
dhtmlXMenuObject.prototype._renderSublevelPolygon = function(id, parentId) {
2011
var s = document.createElement("DIV");
2012
s.className = "dhtmlxMenu_"+this.skin+"_SubLevelArea_Polygon";
2013
s.oncontextmenu = function() { return false; }
2014
s.id = "polygon_" + parentId;
2015
s.onclick = function(e) { e = e || event; e.cancelBubble = true; }
2016
s.style.display = "none";
2017
document.body.appendChild(s);
2019
this.idPull[s.id] = s;
2020
if (this.sxDacProc != null) {
2021
this.idPull["sxDac_" + parentId] = new this.sxDacProc(s, s.className);
2023
this.idPull["sxDac_" + parentId]._setSpeed(this.dacSpeedIE);
2024
this.idPull["sxDac_" + parentId]._setCustomCycle(this.dacCyclesIE);
2026
this.idPull["sxDac_" + parentId]._setSpeed(this.dacSpeed);
2027
this.idPull["sxDac_" + parentId]._setCustomCycle(this.dacCycles);
2032
dhtmlXMenuObject.prototype._renderSublevelItem = function(id, pos) {
2033
var main_self = this;
2034
var k = document.createElement("DIV");
2035
if (this.itemPull[id]["state"] == "enabled") {
2036
k.className = "dhtmlxMenu_"+this.skin+"_SubLevelArea_Item_Normal";
2037
var arw = "dhtmlxmenu_subenable.gif";
2038
j_icon = this.itemPull[id]["imgen"];
2040
k.className = "dhtmlxMenu_"+this.skin+"_SubLevelArea_Item_Disabled";
2041
var arw = "dhtmlxmenu_subdisable.gif";
2042
j_icon = this.itemPull[id]["imgdis"];
2044
var imgPath = (this.itemPull[id]["type"]=="checkbox"||this.itemPull[id]["type"]=="radio"?this.skinPath:this.imagePath);
2045
if (this.itemPull[id]["complex"]) { var j_nodes = "<img src='" + this.skinPath + arw + "' border='0' class='dhtmlxMenu_"+this.skin+"_SubLevelArea_Item_Arrow' id='arrow_" + this.itemPull[id]["id"] + "'>"; } else { var j_nodes = ""; }
2046
if (j_icon.length > 0) { j_icon = "<img id='image_" + this.itemPull[id]["id"] + "' src='" + imgPath + j_icon + "' border='0' class='dhtmlxMenu_"+this.skin+"_SubLevelArea_Item_Icon'>"; }
2047
k.innerHTML = j_icon + this.itemPull[id]["title"] + j_nodes;
2048
// hotkey, added in 0.4
2049
if (this.itemPull[id]["hotkey"].length > 0 && !this.itemPull[id]["complex"]) {
2051
for (var q=0; q<this.itemPull[id]["hotkey"].length; q++) { p += " "; }
2052
k.innerHTML += "<div class='dhtmlxMenu_"+this.skin+"_SubLevelArea_Item_HotKey'>"+this.itemPull[id]["hotkey"]+"</div><span>"+p+"</span>";
2055
k.id = this.itemPull[id]["id"];
2056
k.parent = this.itemPull[id]["parent"];
2057
// tooltip, added in 0.4
2058
if (this.itemPull[id]["tip"].length > 0) { k.title = this.itemPull[id]["tip"]; }
2060
k.onselectstart = function(e) { e = e || event; e.returnValue = false; }
2061
k.onmouseover = function() {
2062
if (main_self.menuMode == "web") { window.clearTimeout(main_self.menuTimeoutHandler); }
2063
main_self._redistribSubLevelSelection(this.id, this.parent);
2065
if (main_self.menuMode == "web") {
2066
k.onmouseout = function() {
2067
window.clearTimeout(main_self.menuTimeoutHandler);
2068
main_self.menuTimeoutHandler = window.setTimeout(function(){main_self._clearAndHide();}, main_self.menuTimeoutMsec, "JavaScript");
2071
k.onclick = function(e) {
2072
// added in 0.4, preven complex closing if user event not defined
2073
if (!main_self.checkEvent("onClick") && main_self.itemPull[this.id]["complex"]) { return; }
2075
e = e || event; e.cancelBubble = true;
2076
tc = (main_self.itemPull[this.id]["complex"]?"c":"-");
2077
td = (main_self.itemPull[this.id]["state"]=="enabled"?"-":"d");
2078
switch (main_self.itemPull[this.id]["type"]) {
2080
main_self._checkboxOnClickHandler(this.id.replace(main_self.idPrefix, ""), tc+td+"n");
2083
main_self._radioOnClickHandler(this.id.replace(main_self.idPrefix, ""), tc+td+"n");
2086
main_self._doOnClick(this.id.replace(main_self.idPrefix, ""), tc+td+"n");
2090
var polygon = this.idPull["polygon_"+this.itemPull[id]["parent"]];
2091
if (pos != null) { pos++; if (pos < 0) { pos = 0; } if (pos > polygon.childNodes.length - 1) { pos = null; } }
2092
if (pos != null) { polygon.insertBefore(k, polygon.childNodes[pos]); } else { polygon.appendChild(k); }
2093
this.idPull[k.id] = k;
2095
dhtmlXMenuObject.prototype._renderSeparator = function(id, pos) {
2096
var main_self = this;
2097
var k = document.createElement("DIV");
2098
k.id = "separator_"+id;
2099
k.className = "dhtmlxMenu_"+this.skin+"_SubLevelArea_Separator";
2100
k.onselectstart = function(e) { e = e || event; e.returnValue = false; }
2101
k.onclick = function(e) {
2102
e = e || event; e.cancelBubble = true;
2103
main_self._doOnClick(this.id.replace("separator_" + main_self.idPrefix, ""), "--s");
2105
var polygon = this.idPull["polygon_"+this.itemPull[id]["parent"]];
2106
if (pos != null) { pos++; if (pos < 0) { pos = 0; } if (pos > polygon.childNodes.length - 1) { pos = null; } }
2107
if (pos != null) { polygon.insertBefore(k, polygon.childNodes[pos]); } else { polygon.appendChild(k); }
2108
this.idPull[k.id] = k;
2110
// hide any opened polygons
2112
* @desc: hides any open menu polygons
2115
dhtmlXMenuObject.prototype.hide = function() {
2116
this._clearAndHide();
2118
// tooltips, added in 0.4
2120
* @desc: sets tooltip for a menu item
2121
* @param: id - menu item's id
2122
* @param: tip - tooltip
2125
dhtmlXMenuObject.prototype.setTooltip = function(id, tip) {
2126
id = this.idPrefix+id;
2127
if (!(this.itemPull[id] != null && this.idPull[id] != null)) { return; }
2128
this.idPull[id].title = (tip.length > 0 ? this.itemPull[id]["tip"] : null);
2129
this.itemPull[id]["tip"] = tip;
2132
* @desc: returns tooltip of a menu item
2133
* @param: id - menu item's id
2136
dhtmlXMenuObject.prototype.getTooltip = function(id) {
2137
if (this.itemPull[this.idPrefix+id] == null) { return null; }
2138
return this.itemPull[this.idPrefix+id]["tip"];
2140
//#menu_hotkey:06062008#{
2141
// hot-keys, added in 0.4
2143
* @desc: sets menu hot-key (just text)
2144
* @param: id - menu item's id
2145
* @param: hkey - hot-key text
2148
dhtmlXMenuObject.prototype.setHotKey = function(id, hkey) {
2149
id = this.idPrefix+id;
2150
if (!(this.itemPull[id] != null && this.idPull[id] != null)) { return; }
2151
if (this.itemPull[id]["parent"] == this.idPrefix+this.topId) { return; }
2152
if (this.itemPull[id]["complex"]) { return; }
2153
if (this.itemPull[id]["type"] != "item") { return; }
2157
for (var q=0; q<this.idPull[id].childNodes.length; q++) {
2158
if (this.idPull[id].childNodes[q].tagName == "DIV" && this.idPull[id].childNodes[q].className == "dhtmlxMenu_"+this.skin+"_SubLevelArea_Item_HotKey") { hkObj = this.idPull[id].childNodes[q]; }
2159
if (this.idPull[id].childNodes[q].tagName == "SPAN") { spnObj = this.idPull[id].childNodes[q]; }
2161
if (hkey.length == 0) {
2163
this.itemPull[id]["hotkey_backup"] = this.itemPull[id]["hotkey"];
2164
this.itemPull[id]["hotkey"] = "";
2165
if (hkObj != null) { this.idPull[id].removeChild(hkObj); }
2166
if (spnObj != null) { this.idPull[id].removeChild(spnObj); }
2168
// add if needed or change
2169
this.itemPull[id]["hotkey"] = hkey;
2170
this.itemPull[id]["hotkey_backup"] = null;
2172
if (hkObj == null) {
2173
hkObj = document.createElement("DIV");
2174
hkObj.className = "dhtmlxMenu_"+this.skin+"_SubLevelArea_Item_HotKey";
2175
this.idPull[id].appendChild(hkObj);
2177
hkObj.innerHTML = hkey;
2180
for (var q=0; q<hkey.length; q++) { p += " "; }
2181
if (spnObj == null) {
2182
spnObj = document.createElement("SPAN");
2183
this.idPull[id].appendChild(spnObj);
2185
spnObj.innerHTML = p;
2190
* @desc: returns item's hot-key (just text)
2191
* @param: id - menu item's id
2194
dhtmlXMenuObject.prototype.getHotKey = function(id) {
2195
if (this.itemPull[this.idPrefix+id] == null) { return null; }
2196
return this.itemPull[this.idPrefix+id]["hotkey"];
2199
/* set toplevel item selected */
2200
dhtmlXMenuObject.prototype.setItemSelected = function(id) {
2201
if (this.itemPull[this.idPrefix+id] == null) { return null; }
2202
// console.log(this.itemPull[this.idPrefix+id]);
2206
dhtmlXMenuObject.prototype.dhx_Event = function() {
2207
this.dhx_SeverCatcherPath="";
2209
* @desc: attaches an event handler
2210
* @param: original - event's original name
2211
* @param: catcher - event handler
2212
* @param: CallObj - object that will call the event
2215
this.attachEvent = function(original, catcher, CallObj) {
2216
original = original.toLowerCase();
2217
CallObj = CallObj||this;
2218
original = 'ev_'+original;
2219
if ((!this[original]) || (!this[original].addEvent)) {
2220
var z = new this.eventCatcher(CallObj);
2221
z.addEvent(this[original]);
2224
return (original + ':' + this[original].addEvent(catcher)); //return ID (event name & event ID)
2226
this.callEvent = function(name,arg0) {
2227
name = name.toLowerCase();
2228
if (this["ev_"+name]) { return this["ev_"+name].apply(this,arg0); }
2232
* @desc: returns true if the event exists
2233
* @param: name - event's name
2236
this.checkEvent = function(name) {
2237
name = name.toLowerCase();
2238
if (this["ev_"+name]) { return true; }
2241
this.eventCatcher = function(obj) {
2242
var dhx_catch = new Array();
2244
var z = function() {
2245
if (dhx_catch) var res = true;
2246
for (var i=0; i<dhx_catch.length; i++) { if (dhx_catch[i] != null) { var zr = dhx_catch[i].apply(m_obj, arguments); res = res && zr; } }
2249
z.addEvent = function(ev) {
2250
if (typeof(ev) != "function") ev = eval(ev);
2251
if (ev) return dhx_catch.push( ev ) - 1;
2254
z.removeEvent = function(id) { dhx_catch[id] = null; }
2258
* @desc: removes an event handler
2259
* @param: id - event's id
2262
this.detachEvent = function(id) {
2264
var list = id.split(':'); //get EventName and ID
2265
this[list[0]].removeEvent(list[1]); //remove event
b'\\ No newline at end of file'