egroupware_official/api/js/egw_action/egw_menu_dhtmlx.ts

195 lines
4.5 KiB
TypeScript
Raw Normal View History

/**
* eGroupWare egw_action framework - JS Menu abstraction
*
* @link http://www.egroupware.org
* @author Andreas Stöckel <as@stylite.de>
* @copyright 2011 by Andreas Stöckel
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package egw_action
* @version $Id$
*/
import {egwMenuItem} from "./egw_menu";
/**
*
* @param {type} _structure
*/
export class egwMenuImpl
{
readonly dhtmlxmenu:any;
constructor(_structure)
{
//Create a new dhtmlxmenu object
// @ts-ignore //origin not easily ts compatible --> soon to be replaced by shoelace anyway
this.dhtmlxmenu = new dhtmlXMenuObject();
this.dhtmlxmenu.setSkin("egw");
this.dhtmlxmenu.renderAsContextMenu();
// TODO: Keyboard navigation of the menu
//Attach the simple click handler
this.dhtmlxmenu.attachEvent("onClick", (id) => {
if (id)
{
const elem = this.dhtmlxmenu.getUserData(id, 'egw_menu');
if (elem && elem.onClick)
{
if (elem.checkbox)
{
this.dhtmlxmenu.setContextMenuHideAllMode(false);
}
const res = elem.onClick(elem);
if (elem.checkbox && (res === false || res === true))
{
const checked = res;
if (elem.groupIndex != 0)
{
this.dhtmlxmenu.setRadioChecked(id, checked);
} else
{
this.dhtmlxmenu.setCheckboxState(id, checked);
}
}
}
}
});
//Attach the radiobutton click handler
this.dhtmlxmenu.attachEvent("onRadioClick", (group, idChecked, idClicked) => {
if (idClicked)
{
const elem = this.dhtmlxmenu.getUserData(idClicked, 'egw_menu');
if (elem)
{
elem.set_checked(true);
}
}
return true;
});
//Attach the radiobutton click handler
this.dhtmlxmenu.attachEvent("onCheckboxClick", (id, state) => {
if (id)
{
const elem = this.dhtmlxmenu.getUserData(id, 'egw_menu');
if (elem)
{
elem.set_checked(!state);
}
}
return true;
});
//Translate the given structure to the dhtmlx object structure
this._translateStructure(_structure, this.dhtmlxmenu.topId, 0);
// Add disableIfNoEPL class to the relevant action's DOM
for (const i in this.dhtmlxmenu.idPull)
{
if (this.dhtmlxmenu.userData[i + '_egw_menu'] &&
this.dhtmlxmenu.userData[i + '_egw_menu']['data'] &&
this.dhtmlxmenu.userData[i + '_egw_menu']['data']['disableIfNoEPL'])
{
this.dhtmlxmenu.idPull[i].className += ' disableIfNoEPL';
}
}
}
private _translateStructure(_structure:egwMenuItem[], _parentId: string, _idCnt: number)
{
//Initialize the counter which we will use to generate unique id's for all
//dhtmlx menu objects
let counter: number = 0;
let last_id = null;
_structure.forEach((elem: egwMenuItem, i: number) =>
{
const id = elem.id || 'elem_' + (_idCnt + counter);
counter++;
//Check whether this element is a separator
if (elem.caption == '-' && last_id != null)
{
//Add the separator next to last_id with the id "id"
this.dhtmlxmenu.addNewSeparator(last_id, id);
} else
{
if (elem.checkbox && elem.groupIndex === 0)
{
//Add checkbox
this.dhtmlxmenu.addCheckbox("child", _parentId, i, id,
elem.caption, elem.checked, !elem.enabled);
} else if (elem.checkbox && elem.groupIndex > 0)
{
//Add radiobox
elem._dhtmlx_grpid = "grp_" + _idCnt + '_' + elem.groupIndex;
this.dhtmlxmenu.addRadioButton("child", _parentId, i, id,
elem.caption, elem._dhtmlx_grpid, elem.checked, !elem.enabled);
} else
{
let caption = elem.caption;
if (elem.default)
caption = "<b>" + caption + "</b>";
this.dhtmlxmenu.addNewChild(_parentId, i, id, caption, !elem.enabled,
elem.iconUrl, elem.iconUrl);
}
if (elem.shortcutCaption != null)
{
this.dhtmlxmenu.setHotKey(id, elem.shortcutCaption);
}
if (elem.children.length > 0)
{
counter += this._translateStructure(elem.children, id, (_idCnt + counter));
}
}
//Set the actual egw menu as user data element
this.dhtmlxmenu.setUserData(id, 'egw_menu', elem);
// Set the tooltip if one has been set
if (elem.hint)
{
this.dhtmlxmenu.setTooltip(id, elem.hint);
}
last_id = id;
})
return counter;
};
public showAt(_x, _y, _onHide)
{
if (_onHide)
{
this.dhtmlxmenu.attachEvent("onHide", (id) => {
if (id === null)
{
_onHide();
}
});
}
window.setTimeout(() => {
this.dhtmlxmenu.showContextMenu(_x, _y);
// TODO: Get keyboard focus
}, 0);
};
public hide()
{
this.dhtmlxmenu.hide();
};
}