mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-23 07:09:20 +01:00
Implemented egw_popup_action, tested, got it working with IE
This commit is contained in:
parent
ce20a2f3ff
commit
1f751b452a
@ -27,16 +27,15 @@ function egwActionHandler(_executeEvent)
|
||||
/**
|
||||
* Associative array where action classes may register themselves
|
||||
*/
|
||||
var _egwActionClasses =
|
||||
{
|
||||
"default":
|
||||
{
|
||||
"actionConstructor": egwAction,
|
||||
"implementationConstructor": null
|
||||
}
|
||||
}
|
||||
if (typeof window._egwActionClasses == "undefined")
|
||||
window._egwActionClasses = {}
|
||||
|
||||
function egwAction(_id, _handler, _caption, _icon, _onExecute, _allowOnMultiple)
|
||||
_egwActionClasses["default"] = {
|
||||
"actionConstructor": egwAction,
|
||||
"implementation": null
|
||||
};
|
||||
|
||||
function egwAction(_id, _handler, _caption, _iconUrl, _onExecute, _allowOnMultiple)
|
||||
{
|
||||
//Default and check the values
|
||||
if (typeof _id != "string" || !_id)
|
||||
@ -45,8 +44,8 @@ function egwAction(_id, _handler, _caption, _icon, _onExecute, _allowOnMultiple)
|
||||
this.handler = null;
|
||||
if (typeof _label == "undefined")
|
||||
_label = "";
|
||||
if (typeof _icon == "undefined")
|
||||
_icon = "";
|
||||
if (typeof _iconUrl == "undefined")
|
||||
_iconUrl = "";
|
||||
if (typeof _onExecute == "undefined")
|
||||
_onExecute = null;
|
||||
if (typeof _allowOnMultiple == "undefined")
|
||||
@ -54,7 +53,7 @@ function egwAction(_id, _handler, _caption, _icon, _onExecute, _allowOnMultiple)
|
||||
|
||||
this.id = _id;
|
||||
this.caption = _caption;
|
||||
this.icon = _icon;
|
||||
this.iconUrl = _iconUrl;
|
||||
this.allowOnMultiple = _allowOnMultiple;
|
||||
this.type = "default"; //All derived classes have to override this!
|
||||
|
||||
@ -133,9 +132,9 @@ egwAction.prototype.set_caption = function(_value)
|
||||
this.caption = _value;
|
||||
}
|
||||
|
||||
egwAction.prototype.set_icon = function(_value)
|
||||
egwAction.prototype.set_iconUrl = function(_value)
|
||||
{
|
||||
this.icon = _value;
|
||||
this.iconUrl = _value;
|
||||
}
|
||||
|
||||
egwAction.prototype.set_allowOnMultiple = function(_value)
|
||||
@ -143,6 +142,12 @@ egwAction.prototype.set_allowOnMultiple = function(_value)
|
||||
this.allowOnMultiple = _value;
|
||||
}
|
||||
|
||||
egwAction.prototype.updateAction = function(_data)
|
||||
{
|
||||
egwActionStoreJSON(_data, this, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** egwActionManager Object **/
|
||||
|
||||
@ -160,7 +165,7 @@ function egwActionManager(_handler)
|
||||
this.actions = [];
|
||||
}
|
||||
|
||||
egwActionManager.prototype.addAction = function(_type, _id, _caption, _icon,
|
||||
egwActionManager.prototype.addAction = function(_type, _id, _caption, _iconUrl,
|
||||
_onExecute, _allowOnMultiple)
|
||||
{
|
||||
//Get the constructor for the given action type
|
||||
@ -170,7 +175,7 @@ egwActionManager.prototype.addAction = function(_type, _id, _caption, _icon,
|
||||
|
||||
if (typeof constructor == "function")
|
||||
{
|
||||
var action = new constructor(_id, this.handler, _caption, _icon, _onExecute,
|
||||
var action = new constructor(_id, this.handler, _caption, _iconUrl, _onExecute,
|
||||
_allowOnMultiple);
|
||||
this.actions.push[action];
|
||||
|
||||
@ -196,22 +201,20 @@ egwActionManager.prototype.updateActions = function(_actions)
|
||||
if (typeof elem.type == "undefined")
|
||||
elem.type = "default";
|
||||
|
||||
var constructor = _egwActionClasses[elem.type].actionConstructor;
|
||||
var constructor = null;
|
||||
|
||||
if (typeof constructor == "function")
|
||||
if (typeof _egwActionClasses[elem.type] != "undefined")
|
||||
constructor = _egwActionClasses[elem.type].actionConstructor;
|
||||
|
||||
if (typeof constructor == "function" && constructor)
|
||||
action = new constructor(elem.id, this.handler);
|
||||
else
|
||||
throw "Given action type not registered.";
|
||||
throw "Given action type \"" + elem.type + "\" not registered.";
|
||||
|
||||
this.actions.push(action);
|
||||
}
|
||||
|
||||
//Update the actions by calling the corresponding setter functions
|
||||
//TODO: Hirachical actions will need a reference to their parent -
|
||||
// this parent is has to be translated to a js object
|
||||
//TODO: Maby the setter, JSON, update stuff should somehow be moved
|
||||
// to a own base class.
|
||||
egwActionStoreJSON(elem, action, true);
|
||||
action.updateAction(elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -239,34 +242,34 @@ egwActionManager.prototype.getAction = function(_id)
|
||||
* which replaces "this" with a "new egwActionImplementation" and implement your
|
||||
* code in "doRegisterAction" und "doUnregisterAction".
|
||||
* Register your own implementation within the _egwActionClasses object.
|
||||
*
|
||||
* @param object _action is the parent egwAction object for that instance.
|
||||
*/
|
||||
function egwActionImplementation(_action)
|
||||
function egwActionImplementation()
|
||||
{
|
||||
this.action = _action;
|
||||
|
||||
this.doRegisterAction = null;
|
||||
this.doUnregisterAction = null;
|
||||
this.doRegisterAction = function() {throw "Abstract function call: registerAction"};
|
||||
this.doUnregisterAction = function() {throw "Abstract function call: unregisterAction"};
|
||||
this.doExecuteImplementation = function() {throw "Abstract function call: executeImplementation"};
|
||||
this.type = "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Injects the implementation code into the DOM tree by using the supplied
|
||||
* actionObjectInterface.
|
||||
*
|
||||
* @param object _actionObjectInterface is the AOI in which the implementation
|
||||
* should be registered.
|
||||
* @param function _triggerCallback is the callback function which will be triggered
|
||||
* when the user triggeres this action implementatino (e.g. starts a drag-drop or
|
||||
* right-clicks on an object.)
|
||||
* @param object context in which the triggerCallback should get executed.
|
||||
* @returns true if the Action had been successfully registered, false if it
|
||||
* had not.
|
||||
*/
|
||||
egwActionImplementation.registerAction = function(_actionObjectInterface)
|
||||
egwActionImplementation.prototype.registerAction = function(_actionObjectInterface, _triggerCallback, _context)
|
||||
{
|
||||
if (this.doRegisterAction == null)
|
||||
{
|
||||
throw "Abstract function call: registerAction";
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.doRegisterAction(_action, _actionObjectInterface);
|
||||
}
|
||||
if (typeof _context == "undefined")
|
||||
_context = null;
|
||||
|
||||
return this.doRegisterAction(_actionObjectInterface, _triggerCallback, _context);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -277,16 +280,14 @@ egwActionImplementation.registerAction = function(_actionObjectInterface)
|
||||
* @returns true if the Action had been successfully unregistered, false if it
|
||||
* had not.
|
||||
*/
|
||||
egwActionImplementation.unregisterAction = function(_actionObjectInterface)
|
||||
egwActionImplementation.prototype.unregisterAction = function(_actionObjectInterface)
|
||||
{
|
||||
if (this.doUnregisterAction == null)
|
||||
{
|
||||
throw "Abstract function call: unregisterAction";
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.doUnregisterAction(_action, _actionObjectInterface);
|
||||
}
|
||||
return this.doUnregisterAction(_actionObjectInterface);
|
||||
}
|
||||
|
||||
egwActionImplementation.prototype.executeImplementation = function(_context, _selected, _links)
|
||||
{
|
||||
return this.doExecuteImplementation(_context, _selected, _links);
|
||||
}
|
||||
|
||||
|
||||
@ -303,6 +304,7 @@ egwActionImplementation.unregisterAction = function(_actionObjectInterface)
|
||||
function egwActionLink(_manager)
|
||||
{
|
||||
this.enabled = true;
|
||||
this.visible = true;
|
||||
this.actionId = "";
|
||||
this.actionObj = null;
|
||||
this.manager = _manager;
|
||||
@ -318,6 +320,11 @@ egwActionLink.prototype.set_enabled = function(_value)
|
||||
this.enabled = _value;
|
||||
}
|
||||
|
||||
egwActionLink.prototype.set_visible = function(_value)
|
||||
{
|
||||
this.visible = _value;
|
||||
}
|
||||
|
||||
egwActionLink.prototype.set_actionId = function(_value)
|
||||
{
|
||||
this.actionId = _value;
|
||||
@ -327,27 +334,26 @@ egwActionLink.prototype.set_actionId = function(_value)
|
||||
throw "Given action object does not exist!"
|
||||
}
|
||||
|
||||
|
||||
/** egwActionObject Object **/
|
||||
|
||||
//State bitmask (only use powers of two for new states!)
|
||||
const EGW_AO_STATE_NORMAL = 0x00;
|
||||
const EGW_AO_STATE_SELECTED = 0x01;
|
||||
const EGW_AO_STATE_FOCUSED = 0x02;
|
||||
var EGW_AO_STATE_NORMAL = 0x00;
|
||||
var EGW_AO_STATE_SELECTED = 0x01;
|
||||
var EGW_AO_STATE_FOCUSED = 0x02;
|
||||
|
||||
const EGW_AO_EVENT_DRAG_OVER_ENTER = 0x00;
|
||||
const EGW_AO_EVENT_DRAG_OVER_LEAVE = 0x01;
|
||||
var EGW_AO_EVENT_DRAG_OVER_ENTER = 0x00;
|
||||
var EGW_AO_EVENT_DRAG_OVER_LEAVE = 0x01;
|
||||
|
||||
// No shift key is pressed
|
||||
const EGW_AO_SHIFT_STATE_NONE = 0x00;
|
||||
var EGW_AO_SHIFT_STATE_NONE = 0x00;
|
||||
// A shift key, which allows multiselection is pressed (usually CTRL on a PC keyboard)
|
||||
const EGW_AO_SHIFT_STATE_MULTI = 0x01;
|
||||
var EGW_AO_SHIFT_STATE_MULTI = 0x01;
|
||||
// A shift key is pressed, which forces blockwise selection (SHIFT on a PC keyboard)
|
||||
const EGW_AO_SHIFT_STATE_BLOCK = 0x02;
|
||||
var EGW_AO_SHIFT_STATE_BLOCK = 0x02;
|
||||
|
||||
// If this flag is set, this object will not be returned as "focused". If this
|
||||
// flag is not applied to container objects, it may lead to some strange behaviour.
|
||||
const EGW_AO_FLAG_IS_CONTAINER = 0x01;
|
||||
var EGW_AO_FLAG_IS_CONTAINER = 0x01;
|
||||
|
||||
/**
|
||||
* The egwActionObject represents an abstract object to which actions may be
|
||||
@ -524,6 +530,26 @@ egwActionObject.prototype.getContainerRoot = function()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all selected objects which are in the current container.
|
||||
*/
|
||||
egwActionObject.prototype.getSelectedObjects = function(_test)
|
||||
{
|
||||
if (typeof _test == "undefined")
|
||||
_test = null;
|
||||
|
||||
var result = [];
|
||||
var list = this.getContainerRoot().flatList();
|
||||
for (var i = 0; i < list.length; i++)
|
||||
{
|
||||
if (list[i].getSelected() && (!_test || _test(list[i])))
|
||||
{
|
||||
result.push(list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a list which contains all items of the element tree.
|
||||
@ -564,8 +590,8 @@ egwActionObject.prototype.traversePath = function(_to)
|
||||
// Get a flat list of all the hncp elements and search for this object
|
||||
// and the object supplied in the _to parameter.
|
||||
var flatList = contRoot.flatList();
|
||||
var thisId = contRoot.indexOf(this);
|
||||
var toId = contRoot.indexOf(_to);
|
||||
var thisId = flatList.indexOf(this);
|
||||
var toId = flatList.indexOf(_to);
|
||||
|
||||
// Check whether both elements have been found in this part of the tree,
|
||||
// return the slice of that list.
|
||||
@ -574,7 +600,7 @@ egwActionObject.prototype.traversePath = function(_to)
|
||||
var from = Math.min(thisId, toId);
|
||||
var to = Math.max(thisId, toId);
|
||||
|
||||
return this.slice(from, to + 1);
|
||||
return flatList.slice(from, to + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -745,10 +771,10 @@ egwActionObject.prototype.setFocused = function(_focused, _recPrev)
|
||||
//If the object is not focused, reset the focus state of all children
|
||||
for (var i = 0; i < this.children.length; i++)
|
||||
{
|
||||
// if (this.children[i] != _recPrev)
|
||||
// {
|
||||
if (this.children[i] != _recPrev)
|
||||
{
|
||||
this.children[i].setFocused(false, _recPrev);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -805,11 +831,12 @@ egwActionObject.prototype.updateActionLinks = function(_actionLinks, _recursive,
|
||||
var elem = _actionLinks[i];
|
||||
if (typeof elem.actionId != "undefined" && elem.actionId)
|
||||
{
|
||||
//Get the action link object, if it doesn't exists yet, create it
|
||||
//Get the action link object, if it doesn't exist yet, create it
|
||||
var actionLink = this.getActionLink(elem.actionId);
|
||||
if (!actionLink && _doCreate)
|
||||
{
|
||||
actionLink = new egwActionLink(this.manager);
|
||||
this.actionLinks.push(actionLink);
|
||||
}
|
||||
|
||||
//Set the supplied data
|
||||
@ -829,6 +856,131 @@ egwActionObject.prototype.updateActionLinks = function(_actionLinks, _recursive,
|
||||
}
|
||||
}
|
||||
|
||||
egwActionObject.prototype.registerActions = function()
|
||||
{
|
||||
var groups = this.getActionImplementationGroups();
|
||||
|
||||
for (group in groups)
|
||||
{
|
||||
// Get the action implementation for each group
|
||||
if (typeof _egwActionClasses[group] != "undefined" &&
|
||||
_egwActionClasses[group].implementation &&
|
||||
this.iface)
|
||||
{
|
||||
var impl = _egwActionClasses[group].implementation();
|
||||
|
||||
// Register a handler for that action with the interface of that object,
|
||||
// the callback and this object as context for the callback
|
||||
impl.registerAction(this.iface, this.executeActionImplementation, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
egwActionObject.prototype.triggerCallback = function()
|
||||
{
|
||||
if (this.onBeforeTrigger)
|
||||
{
|
||||
return this.onBeforeTrigger();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
egwActionObject.prototype.executeActionImplementation = function(_implContext, _implType)
|
||||
{
|
||||
if (typeof _implType == "string")
|
||||
_implType = _egwActionClasses[_implType].implementation();
|
||||
|
||||
if (typeof _implType == "object" && _implType)
|
||||
{
|
||||
var selectedActions = this.getSelectedLinks(_implType.type, true);
|
||||
if (selectedActions.selected.length > 0 && egwObjectLength(selectedActions.links) > 0)
|
||||
{
|
||||
_implType.executeImplementation(_implContext,
|
||||
selectedActions.selected, selectedActions.links);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all selected objects, which returned true in their triggerCallback and
|
||||
* all action links of those objects, which are of the given implementation type,
|
||||
* wheras actionLink properties such as "enabled" and "visible" are accumuleted.
|
||||
*/
|
||||
egwActionObject.prototype.getSelectedLinks = function(_implType, _includeThis)
|
||||
{
|
||||
// Get all objects in this container which are currently selected
|
||||
var selected = this.getSelectedObjects();
|
||||
|
||||
if (_includeThis)
|
||||
{
|
||||
var thisInList = false;
|
||||
for (var i = 0; i < selected.length; i++)
|
||||
{
|
||||
if (selected[i] == this)
|
||||
{
|
||||
thisInList = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!thisInList)
|
||||
{
|
||||
this.setSelected(true);
|
||||
this._ifaceCallback(egwSetBit(this.getState(), EGW_AO_STATE_SELECTED, true),
|
||||
EGW_AO_SHIFT_STATE_NONE);
|
||||
selected = [this];
|
||||
}
|
||||
}
|
||||
|
||||
var actionLinks = {};
|
||||
var testedSelected = [];
|
||||
for (var i = 0; i < selected.length; i++)
|
||||
{
|
||||
var obj = selected[i];
|
||||
if (obj.triggerCallback())
|
||||
{
|
||||
testedSelected.push(obj);
|
||||
|
||||
for (var j = 0; j < obj.actionLinks.length; j++)
|
||||
{
|
||||
var olink = obj.actionLinks[j]; //object link
|
||||
|
||||
// Test whether the action type is of the given implementation type
|
||||
if (olink.actionObj.type == _implType)
|
||||
{
|
||||
if (typeof actionLinks[olink.actionId] == "undefined")
|
||||
{
|
||||
actionLinks[olink.actionId] = {
|
||||
"actionObj": olink.actionObj,
|
||||
"enabled": i == 0 && (olink.actionObj.allowOnMultiple || selected.length == 1),
|
||||
"visible": false,
|
||||
"cnt": 0
|
||||
}
|
||||
}
|
||||
|
||||
var llink = actionLinks[olink.actionId];
|
||||
llink.enabled = llink.enabled && olink.enabled && olink.visible;
|
||||
llink.visible = llink.visible || olink.visible;
|
||||
llink.cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (k in actionLinks)
|
||||
{
|
||||
actionLinks[k].enabled = actionLinks[k].enabled && (actionLinks[k].cnt >= selected.length);
|
||||
}
|
||||
|
||||
|
||||
// Return an object which contains the accumulated actionLinks and all selected
|
||||
// objects.
|
||||
return {
|
||||
"selected": testedSelected,
|
||||
"links": actionLinks
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the action link, which contains the association to the action with
|
||||
* the given actionId.
|
||||
@ -867,7 +1019,7 @@ egwActionObject.prototype.getActionImplementationGroups = function(_test, _group
|
||||
|
||||
for (var i = 0; i < this.actionLinks.length; i++)
|
||||
{
|
||||
var action = this.actionsLink[i].actionObj;
|
||||
var action = this.actionLinks[i].actionObj;
|
||||
if (typeof action != "undefined" && _test(this))
|
||||
{
|
||||
if (typeof _groups[action.type] == "undefined")
|
||||
|
@ -61,3 +61,25 @@ function egwBitIsSet(_set, _bit)
|
||||
return (_set & _bit) > 0;
|
||||
}
|
||||
|
||||
function egwObjectLength(_obj)
|
||||
{
|
||||
var len = 0;
|
||||
for (k in _obj) len++;
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* IE Fix for array.indexOf
|
||||
*/
|
||||
if (typeof Array.prototype.indexOf == "undefined")
|
||||
{
|
||||
Array.prototype.indexOf = function(_elem) {
|
||||
for (var i = 0; i < this.length; i++)
|
||||
{
|
||||
if (this[i] === _elem)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -18,15 +18,15 @@ var _egw_active_menu = null;
|
||||
* in e.g. the egwMenu.addItem function.
|
||||
*/
|
||||
//TODO Icons: write PHP GD script which is cabable of generating the menu icons in various states (disabled, highlighted)
|
||||
function _egwGenMenuItem(_parent, _id, _label, _iconUrl, _onClick)
|
||||
function _egwGenMenuItem(_parent, _id, _caption, _iconUrl, _onClick)
|
||||
{
|
||||
//Preset the parameters
|
||||
if (typeof _parent == "undefined")
|
||||
_parent = null;
|
||||
if (typeof _id == "undefined")
|
||||
_id = "";
|
||||
if (typeof _label == "undefined")
|
||||
_label = "";
|
||||
if (typeof _caption == "undefined")
|
||||
_caption = "";
|
||||
if (typeof _iconUrl == "undefined")
|
||||
_iconUrl = "";
|
||||
if (typeof _onClick == "undefined")
|
||||
@ -34,7 +34,7 @@ function _egwGenMenuItem(_parent, _id, _label, _iconUrl, _onClick)
|
||||
|
||||
//Create a menu item with no parent (null) and set the given parameters
|
||||
var item = new egwMenuItem(_parent, _id);
|
||||
item.set_caption(_label);
|
||||
item.set_caption(_caption);
|
||||
item.set_iconUrl(_iconUrl);
|
||||
item.set_onClick(_onClick);
|
||||
|
||||
@ -217,7 +217,7 @@ egwMenu.prototype.hide = function()
|
||||
* the getItem function to search a specific menu item inside the menu tree. The
|
||||
* id may also be false, null or "", which makes sense for items like seperators,
|
||||
* which you don't want to access anymore after adding them to the menu tree.
|
||||
* @param string _label is the label of the newly generated menu item. Set the label
|
||||
* @param string _caption is the caption of the newly generated menu item. Set the caption
|
||||
* to "-" in order to create a sperator.
|
||||
* @param string _iconUrl is the URL of the icon which should be prepended to the
|
||||
* menu item. It may be false, null or "" if you don't want a icon to be displayed.
|
||||
@ -226,10 +226,10 @@ egwMenu.prototype.hide = function()
|
||||
* @returns egwMenuItem the newly generated menu item, which had been appended to the
|
||||
* menu item list.
|
||||
*/
|
||||
egwMenu.prototype.addItem = function(_id, _label, _iconUrl, _onClick)
|
||||
egwMenu.prototype.addItem = function(_id, _caption, _iconUrl, _onClick)
|
||||
{
|
||||
//Append the item to the list
|
||||
var item = _egwGenMenuItem(this, _id, _label, _iconUrl, _onClick);
|
||||
var item = _egwGenMenuItem(this, _id, _caption, _iconUrl, _onClick);
|
||||
this.children.push(item);
|
||||
|
||||
return item;
|
||||
@ -287,7 +287,8 @@ function egwMenuItem(_parent, _id)
|
||||
this.enabled = true;
|
||||
this.iconUrl = "";
|
||||
this.onClick = null;
|
||||
this.default = false;
|
||||
this["default"] = false;
|
||||
this.data = null;
|
||||
|
||||
this.children = [];
|
||||
this.parent = _parent;
|
||||
@ -314,6 +315,32 @@ egwMenuItem.prototype.setGlobalOnClick = function(_onClick)
|
||||
_egwSetMenuOnClick(this.children, _onClick);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new menu item to the list and returns a reference to that object.
|
||||
*
|
||||
* @param string _id is a unique identifier of the menu item. You can use the
|
||||
* the getItem function to search a specific menu item inside the menu tree. The
|
||||
* id may also be false, null or "", which makes sense for items like seperators,
|
||||
* which you don't want to access anymore after adding them to the menu tree.
|
||||
* @param string _caption is the caption of the newly generated menu item. Set the caption
|
||||
* to "-" in order to create a sperator.
|
||||
* @param string _iconUrl is the URL of the icon which should be prepended to the
|
||||
* menu item. It may be false, null or "" if you don't want a icon to be displayed.
|
||||
* @param function _onClick is the JS function which is being executed when the
|
||||
* menu item is clicked.
|
||||
* @returns egwMenuItem the newly generated menu item, which had been appended to the
|
||||
* menu item list.
|
||||
*/
|
||||
egwMenuItem.prototype.addItem = function(_id, _caption, _iconUrl, _onClick)
|
||||
{
|
||||
//Append the item to the list
|
||||
var item = _egwGenMenuItem(this, _id, _caption, _iconUrl, _onClick);
|
||||
this.children.push(item);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
//Setter functions for the menuitem properties
|
||||
|
||||
egwMenuItem.prototype.set_id = function(_value)
|
||||
@ -371,7 +398,11 @@ egwMenuItem.prototype.set_iconUrl = function(_value)
|
||||
|
||||
egwMenuItem.prototype.set_default = function(_value)
|
||||
{
|
||||
this.default = _value;
|
||||
this["default"] = _value;
|
||||
}
|
||||
|
||||
egwMenuItem.prototype.set_data = function(_value)
|
||||
{
|
||||
this.data = _value;
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ egwMenuImpl.prototype._translateStructure = function(_structure, _parentId, _idC
|
||||
else
|
||||
{
|
||||
var caption = elem.caption;
|
||||
if (elem.default)
|
||||
if (elem["default"])
|
||||
caption = "<b>" + caption + "</b>"
|
||||
this.dhtmlxmenu.addNewChild(_parentId, i, id, caption, !elem.enabled,
|
||||
elem.iconUrl, elem.iconUrl);
|
||||
|
@ -1,9 +1,21 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Test page for the egw action stuff</title>
|
||||
|
||||
<!-- Basic action stuff -->
|
||||
<script src="../egw_action.js"></script>
|
||||
<script src="../egw_action_common.js"></script>
|
||||
<script src="js/jquery.js"></script>
|
||||
|
||||
<!-- Popup stuff -->
|
||||
<link rel="stylesheet" type="text/css" href="skins/dhtmlxmenu_egw.css">
|
||||
<script src="js/dhtmlxcommon.js"></script>
|
||||
<script src="js/dhtmlxmenu.js"></script>
|
||||
<script src="js/dhtmlxmenu_ext.js"></script>
|
||||
<script src="../egw_action_popup.js"></script>
|
||||
<script src="../egw_menu.js"></script>
|
||||
<script src="../egw_menu_dhtmlx.js"></script>
|
||||
|
||||
<style>
|
||||
body, table {
|
||||
font-family: Arial, sans-serif;
|
||||
@ -11,7 +23,7 @@
|
||||
}
|
||||
.listbox {
|
||||
width: 250px;
|
||||
border: 1px solid gray;
|
||||
border: 2px groove gray;
|
||||
margin: 5px;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
@ -24,35 +36,34 @@
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.listbox .selected {
|
||||
.listbox tr.odd {
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
|
||||
.listbox tr.selected {
|
||||
background-color: #2b5d9b;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.listbox tr.odd.selected {
|
||||
background-color: #234b7d !important;
|
||||
}
|
||||
|
||||
.listbox .focused {
|
||||
border: 1px dashed black;
|
||||
padding: 2px;
|
||||
border: 1px dotted black;
|
||||
padding: 1px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<table class="listbox" id="lb1">
|
||||
<tr id="le1">
|
||||
<td><img src="imgs/page.png"/></td>
|
||||
<td style="width: 200px">File 1</td>
|
||||
<td><input type="checkbox"></td>
|
||||
</tr>
|
||||
<tr id="le2">
|
||||
<td><img src="imgs/page.png"/></td>
|
||||
<td style="width: 200px">File 2</td>
|
||||
<td><input type="checkbox"></td>
|
||||
</tr>
|
||||
<tr id="le3">
|
||||
<td><img src="imgs/page.png"/></td>
|
||||
<td style="width: 200px">File 3</td>
|
||||
<td><input type="checkbox"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="listbox" id="lb1">
|
||||
<tr id="folder1"><td><img src="imgs/folder.png"/></td><td style="width: 200px">Folder 1</td><td><input type="checkbox"></td></tr>
|
||||
<tr id="file1"><td><img src="imgs/page.png"/></td><td style="width: 200px">File 1</td><td><input type="checkbox"></td></tr>
|
||||
<tr id="file2"><td><img src="imgs/page.png"/></td><td style="width: 200px">File 2</td><td><input type="checkbox"></td></tr>
|
||||
<tr id="file3"><td><img src="imgs/page.png"/></td><td style="width: 200px">File 3</td><td><input type="checkbox"></td></tr>
|
||||
<tr id="file4"><td><img src="imgs/page.png"/></td><td style="width: 200px">File 4</td><td><input type="checkbox"></td></tr>
|
||||
<tr id="file5"><td><img src="imgs/page.png"/></td><td style="width: 200px">File 5</td><td><input type="checkbox"></td></tr>
|
||||
</table>
|
||||
<script>
|
||||
var actionManager = null;
|
||||
var objectManager = null;
|
||||
@ -69,11 +80,43 @@
|
||||
|
||||
aoi.node = _node;
|
||||
aoi.checkBox = ($(":checkbox", aoi.node))[0];
|
||||
aoi.checkBox.checked = false;
|
||||
|
||||
aoi.doGetDOMNode = function() {
|
||||
return self.node;
|
||||
return aoi.node;
|
||||
}
|
||||
|
||||
function getShiftState(e)
|
||||
{
|
||||
var state = EGW_AO_SHIFT_STATE_NONE;
|
||||
state = egwSetBit(state, EGW_AO_SHIFT_STATE_MULTI, e.ctrkKey || e.metaKey);
|
||||
state = egwSetBit(state, EGW_AO_SHIFT_STATE_BLOCK, e.shiftKey);
|
||||
return state;
|
||||
}
|
||||
|
||||
// Now append some action code to the node
|
||||
$(_node).click(function(e) {
|
||||
if (e.target != aoi.checkBox)
|
||||
{
|
||||
var selected = egwBitIsSet(aoi.getState(), EGW_AO_STATE_SELECTED);
|
||||
var state = getShiftState(e);
|
||||
|
||||
// "Normal" Listbox behaviour
|
||||
aoi.doSetState(egwSetBit(aoi.getState(), EGW_AO_STATE_SELECTED,
|
||||
!egwBitIsSet(state, EGW_AO_SHIFT_STATE_MULTI) || !selected),
|
||||
false, state);
|
||||
|
||||
// "PHPMyAdmin" Listbox behaviour
|
||||
// aoi.doSetState(egwSetBit(aoi.getState(), EGW_AO_STATE_SELECTED,
|
||||
// !selected), false, EGW_AO_SHIFT_STATE_MULTI);
|
||||
}
|
||||
});
|
||||
|
||||
$(aoi.checkBox).change(function() {
|
||||
aoi.doSetState(egwSetBit(aoi.getState(), EGW_AO_STATE_SELECTED,
|
||||
this.checked), false, EGW_AO_SHIFT_STATE_MULTI);
|
||||
});
|
||||
|
||||
aoi.doSetState = function(_state, _outerCall, _shiftState) {
|
||||
var selected = egwBitIsSet(_state, EGW_AO_STATE_SELECTED);
|
||||
this.checkBox.checked = selected;
|
||||
@ -88,30 +131,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Now append some action code to the node
|
||||
$(_node).click(function(e) {
|
||||
if (e.target != aoi.checkBox)
|
||||
{
|
||||
// "Normal" Listbox behaviour
|
||||
// aoi.doSetState(egwSetBit(aoi.getState(), EGW_AO_STATE_SELECTED,
|
||||
// true), false, EGW_AO_SHIFT_STATE_NONE);
|
||||
|
||||
// "PHPMyAdmin" Listbox behaviour
|
||||
var selected = egwBitIsSet(aoi.getState(), EGW_AO_STATE_SELECTED);
|
||||
aoi.doSetState(egwSetBit(aoi.getState(), EGW_AO_STATE_SELECTED,
|
||||
!selected), false, EGW_AO_SHIFT_STATE_MULTI);
|
||||
}
|
||||
});
|
||||
|
||||
$(aoi.checkBox).change(function() {
|
||||
aoi.doSetState(egwSetBit(aoi.getState(), EGW_AO_STATE_SELECTED,
|
||||
this.checked), false, EGW_AO_SHIFT_STATE_MULTI);
|
||||
});
|
||||
|
||||
|
||||
return aoi;
|
||||
}
|
||||
|
||||
function alertClicked(_action, _senders)
|
||||
{
|
||||
var ids = "";
|
||||
for (var i = 0; i < _senders.length; i++)
|
||||
ids += _senders[i].id + ((i < _senders.length - 1) ? ", " : "");
|
||||
|
||||
alert("Action '" + _action.caption + "' executed on elements '"
|
||||
+ ids + "'");
|
||||
}
|
||||
|
||||
function init()
|
||||
{
|
||||
@ -121,22 +152,110 @@
|
||||
|
||||
actionManager.updateActions(
|
||||
[
|
||||
{
|
||||
"id": "folder_open",
|
||||
"iconUrl": "imgs/folder.png",
|
||||
"caption": "Open folder",
|
||||
"onExecute": alertClicked,
|
||||
// "allowOnMultiple": false,
|
||||
"type": "popup",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"id": "file_view",
|
||||
"icon": "imgs/view.png",
|
||||
"iconUrl": "imgs/view.png",
|
||||
"caption": "View",
|
||||
"onExecute": alertClicked,
|
||||
"allowOnMultiple": false,
|
||||
"caption": "Datei anzeigen"
|
||||
"type": "popup",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"id": "file_preview",
|
||||
"iconUrl": "imgs/preview.png",
|
||||
"caption": "Preview",
|
||||
"onExecute": alertClicked,
|
||||
"allowOnMultiple": false,
|
||||
"type": "popup",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"id": "file_delete",
|
||||
"icon": "imgs/delete.png",
|
||||
"caption": "Datei löschen"
|
||||
"iconUrl": "imgs/delete.png",
|
||||
"caption": "Delete",
|
||||
"onExecute": alertClicked,
|
||||
"type": "popup",
|
||||
"group": 2
|
||||
},
|
||||
{
|
||||
"id": "file_edit",
|
||||
"iconUrl": "imgs/edit.png",
|
||||
"caption": "Edit file",
|
||||
"onExecute": alertClicked,
|
||||
"allowOnMultiple": false,
|
||||
"type": "popup"
|
||||
},
|
||||
{
|
||||
"id": "file_compress",
|
||||
"iconUrl": "imgs/compress.png",
|
||||
"caption": "Create ZIP archive",
|
||||
"onExecute": alertClicked,
|
||||
"type": "popup",
|
||||
"group": 1,
|
||||
"order": 1
|
||||
},
|
||||
{
|
||||
"id": "file_email",
|
||||
"iconUrl": "imgs/email.png",
|
||||
"caption": "E-Mail",
|
||||
"onExecute": alertClicked,
|
||||
"allowOnMultiple": false,
|
||||
"type": "popup",
|
||||
"group": 1,
|
||||
"order": 0
|
||||
},
|
||||
{
|
||||
"id": "file_compress_email",
|
||||
"caption": "Create ZIP and E-Mail",
|
||||
"onExecute": alertClicked,
|
||||
"type": "popup",
|
||||
"group": 1,
|
||||
"order": 2
|
||||
}
|
||||
]
|
||||
);
|
||||
|
||||
//Links which will be assigned to each listbox item
|
||||
var listboxFileLinks = [
|
||||
{"actionId": "file_view", "enabled": true},
|
||||
{"actionId": "file_preview", "enabled": true},
|
||||
{"actionId": "file_edit", "enabled": true},
|
||||
{"actionId": "file_email", "enabled": true},
|
||||
{"actionId": "file_compress_email", "enabled": true},
|
||||
{"actionId": "file_compress", "enabled": true},
|
||||
{"actionId": "file_delete", "enabled": true}
|
||||
];
|
||||
|
||||
var listboxFolderLinks = [
|
||||
{"actionId": "folder_open", "enabled": true},
|
||||
{"actionId": "file_compress_email", "enabled": true},
|
||||
{"actionId": "file_compress", "enabled": true},
|
||||
{"actionId": "file_delete", "enabled": true}
|
||||
];
|
||||
|
||||
$('#lb1 tr:odd').addClass('odd');
|
||||
|
||||
//Create an object representation for each listbox-row and append
|
||||
//each to its own listboxItemAOI
|
||||
$('#lb1 tr').each(function(index, elem) {
|
||||
objectManager.addObject(elem.id, new listboxItemAOI(elem));
|
||||
var obj = objectManager.addObject(elem.id, new listboxItemAOI(elem));
|
||||
//Apply the links to the actions
|
||||
if (elem.id.substr(0,4) == "file")
|
||||
obj.updateActionLinks(listboxFileLinks);
|
||||
else
|
||||
obj.updateActionLinks(listboxFolderLinks);
|
||||
|
||||
obj.registerActions();
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
@ -163,7 +163,6 @@ function getPageXY(event)
|
||||
var scrollLeft = document.body.scrollLeft ? document.body.scrollLeft :
|
||||
document.documentElement.scrollLeft;
|
||||
|
||||
// hide the menu first to avoid an "up-then-over" visual effect
|
||||
return {'x': (event.clientX + scrollLeft), 'y': (event.clientY + scrollTop)};
|
||||
}
|
||||
|
||||
|
@ -91,8 +91,8 @@ function egw_json_encode(input)
|
||||
var buf = [];
|
||||
for (var k in input)
|
||||
{
|
||||
//Filter the remove function, which is added to arrays in egw_fw_classes
|
||||
if (k != 'remove')
|
||||
//Filter non numeric entries
|
||||
if (!isNaN(k))
|
||||
buf.push(egw_json_encode(input[k]));
|
||||
}
|
||||
return '[' + buf.join(',') + ']';
|
||||
|
Loading…
Reference in New Issue
Block a user