forked from extern/egroupware
Fixed problems with executeActionImplementation when called from a container object, fixed problem with popup menu which did not open in some cases, added the ability to use the 'enabled' property of an action as an callback function (actionObject is passed as parameter), introduced egwFnct-class which consistently handles 'javaScript:fnct' strings, added 'allowOnMultiple':'only' setting, added 'hint', 'checkbox', 'checked', 'radioGroup' properties to popup actions, added 'setDefaultExecute' function to egwAction objects, which applies an handler to all objects which don't have a handler yet
This commit is contained in:
parent
fe5202c7a2
commit
cb9355ac00
@ -53,7 +53,7 @@ function egwAction(_parent, _id, _caption, _iconUrl, _onExecute, _allowOnMultipl
|
||||
this.caption = _caption;
|
||||
this.iconUrl = _iconUrl;
|
||||
this.allowOnMultiple = _allowOnMultiple;
|
||||
this.enabled = true;
|
||||
this.enabled = new egwFnct(this, true);
|
||||
this.hideOnDisabled = false;
|
||||
this.data = null; // Data which can be freely assigned to the action
|
||||
|
||||
@ -62,9 +62,7 @@ function egwAction(_parent, _id, _caption, _iconUrl, _onExecute, _allowOnMultipl
|
||||
this.parent = _parent;
|
||||
this.children = [];
|
||||
|
||||
this.execJSFnct = null;
|
||||
this.execHandler = false;
|
||||
this.set_onExecute(_onExecute);
|
||||
this.onExecute = new egwFnct(this, null, []);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -189,6 +187,28 @@ egwAction.prototype.updateActions = function(_actions)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applys the same onExecute handler to all actions which don't have an execute
|
||||
* handler set.
|
||||
*/
|
||||
egwAction.prototype.setDefaultExecute = function(_value)
|
||||
{
|
||||
// Check whether the onExecute handler of this action should be set
|
||||
if (this.type != "actionManager" && !this.onExecute.hasHandler())
|
||||
{
|
||||
this.onExecute.setValue(_value);
|
||||
}
|
||||
|
||||
// Apply the value to all children
|
||||
if (this.canHaveChildren)
|
||||
{
|
||||
for (var i = 0; i < this.children.length; i++)
|
||||
{
|
||||
this.children[i].setDefaultExecute(_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes this action by using the method specified in the onExecute setter.
|
||||
*
|
||||
@ -202,14 +222,7 @@ egwAction.prototype.execute = function(_senders, _target)
|
||||
_target == null;
|
||||
}
|
||||
|
||||
if (this.execJSFnct && typeof this.execJSFnct == "function")
|
||||
{
|
||||
return this.execJSFnct(this, _senders, _target);
|
||||
}
|
||||
else if (this.execHandler)
|
||||
{
|
||||
//this.handler.execute(this, _senders); TODO
|
||||
}
|
||||
this.onExecute.exec(this, _senders, _target);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -230,35 +243,7 @@ egwAction.prototype.execute = function(_senders, _target)
|
||||
*/
|
||||
egwAction.prototype.set_onExecute = function(_value)
|
||||
{
|
||||
//Reset the onExecute handlers
|
||||
this.execJSFnct = null;
|
||||
this.execHandler = false;
|
||||
|
||||
if (typeof _value == "string")
|
||||
{
|
||||
// Check whether the given string contains a javaScript function which
|
||||
// should be called upon executing the action
|
||||
if (_value.substr(0, 11) == "javaScript:")
|
||||
{
|
||||
//Check whether the given function exists
|
||||
var fnct = _value.substr(11);
|
||||
if (typeof window[fnct] == "function")
|
||||
{
|
||||
this.execJSFnct = window[fnct];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (typeof _value == "boolean")
|
||||
{
|
||||
// There is no direct reference to the PHP code which should be executed,
|
||||
// as the PHP code has knowledge about this.
|
||||
this.execHandler = _value;
|
||||
}
|
||||
else if (typeof _value == "function")
|
||||
{
|
||||
//The JS function has been passed directly
|
||||
this.execJSFnct = _value;
|
||||
}
|
||||
this.onExecute.setValue(_value);
|
||||
}
|
||||
|
||||
egwAction.prototype.set_caption = function(_value)
|
||||
@ -273,9 +258,12 @@ egwAction.prototype.set_iconUrl = function(_value)
|
||||
|
||||
egwAction.prototype.set_enabled = function(_value)
|
||||
{
|
||||
this.enabled = _value;
|
||||
this.enabled.setValue(_value);
|
||||
}
|
||||
|
||||
/**
|
||||
* The allowOnMultiple property may be true, false or "only"
|
||||
*/
|
||||
egwAction.prototype.set_allowOnMultiple = function(_value)
|
||||
{
|
||||
this.allowOnMultiple = _value;
|
||||
@ -1314,7 +1302,10 @@ egwActionObject.prototype.executeActionImplementation = function(_implContext, _
|
||||
{
|
||||
if (_execType == EGW_AO_EXEC_SELECTED)
|
||||
{
|
||||
this.forceSelection();
|
||||
if (!(egwBitIsSet(EGW_AO_FLAG_IS_CONTAINER, this.flags)))
|
||||
{
|
||||
this.forceSelection();
|
||||
}
|
||||
var selectedActions = this.getSelectedLinks(_implType.type);
|
||||
}
|
||||
else if (_execType = EGW_AO_EXEC_THIS)
|
||||
@ -1406,7 +1397,7 @@ egwActionObject.prototype._getLinks = function(_objs, _actionType)
|
||||
|
||||
// Accumulate the action link properties
|
||||
var llink = actionLinks[olink.actionId];
|
||||
llink.enabled = olink.actionObj.enabled && llink.enabled &&
|
||||
llink.enabled = llink.enabled && olink.actionObj.enabled.exec(this) &&
|
||||
olink.enabled && olink.visible;
|
||||
llink.visible = (llink.visible || olink.visible);
|
||||
llink.cnt++;
|
||||
@ -1420,8 +1411,11 @@ egwActionObject.prototype._getLinks = function(_objs, _actionType)
|
||||
{
|
||||
actionLinks[k].enabled = actionLinks[k].enabled &&
|
||||
(actionLinks[k].cnt >= testedSelected.length) &&
|
||||
(actionLinks[k].actionObj.allowOnMultiple ||
|
||||
actionLinks[k].cnt == 1);
|
||||
(
|
||||
(actionLinks[k].actionObj.allowOnMultiple === true) ||
|
||||
(actionLinks[k].actionObj.allowOnMultiple == "only" && actionLinks[k].cnt > 1) ||
|
||||
(actionLinks[k].actionObj.allowOnMultiple == false && actionLinks[k].cnt == 1)
|
||||
);
|
||||
actionLinks[k].visible = actionLinks[k].visible &&
|
||||
(actionLinks[k].enabled || !actionLinks[k].actionObj.hideOnDisabled);
|
||||
}
|
||||
|
@ -295,6 +295,87 @@ egwEventQueue.prototype.queueTimeout = function(_proc, _context, _args, _id, _ti
|
||||
}, _timeout)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class which is used to be able to handle references to JavaScript functions
|
||||
* from strings.
|
||||
*
|
||||
* @param object _context is the context in which the function will be executed.
|
||||
* @param mixed _default is the default value which should be returned when no
|
||||
* function (string) has been set. If it is a function this function will be
|
||||
* called.
|
||||
* @param array _acceptedTypes is an array of types which contains the "typeof"
|
||||
* strings of accepted non-functions in setValue
|
||||
*/
|
||||
function egwFnct(_context, _default, _acceptedTypes)
|
||||
{
|
||||
if (typeof _context == "undefined")
|
||||
{
|
||||
_context = null;
|
||||
}
|
||||
|
||||
if (typeof _default == "undefined")
|
||||
{
|
||||
_default = false;
|
||||
}
|
||||
|
||||
if (typeof _acceptedTypes == "undefined")
|
||||
{
|
||||
_acceptedTypes = ["boolean"];
|
||||
}
|
||||
|
||||
this.context = _context;
|
||||
this.acceptedTypes = _acceptedTypes;
|
||||
this.fnct = null;
|
||||
this.value = null;
|
||||
this.setValue(_default);
|
||||
}
|
||||
|
||||
egwFnct.prototype.hasHandler = function()
|
||||
{
|
||||
return this.fnct !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the function/return value for the exec function
|
||||
*/
|
||||
egwFnct.prototype.setValue = function(_value)
|
||||
{
|
||||
this.value = null;
|
||||
this.fnct = null;
|
||||
|
||||
if (typeof _value == "function")
|
||||
{
|
||||
this.fnct = _value;
|
||||
}
|
||||
else if (typeof _value == "string" &&
|
||||
_value.substr(0,11) == "javaScript:" &&
|
||||
typeof window[_value.substr(11)] == "function")
|
||||
{
|
||||
this.fnct = window[_value.substr(11)];
|
||||
}
|
||||
else if (this.acceptedTypes.indexOf(typeof _value) >= 0)
|
||||
{
|
||||
this.value = _value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the function
|
||||
*/
|
||||
egwFnct.prototype.exec = function()
|
||||
{
|
||||
if (this.fnct)
|
||||
{
|
||||
return this.fnct.apply(this.context, arguments);
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
sprintf() for JavaScript 0.6
|
||||
|
||||
|
@ -25,6 +25,10 @@ function egwPopupAction(_id, _handler, _caption, _icon, _onExecute, _allowOnMult
|
||||
action["default"] = false;
|
||||
action.order = 0;
|
||||
action.group = 0;
|
||||
action.hint = false;
|
||||
action.checkbox = false;
|
||||
action.radioGroup = 0;
|
||||
action.checked = false;
|
||||
|
||||
action.set_default = function(_value) {
|
||||
action["default"] = _value;
|
||||
@ -38,6 +42,25 @@ function egwPopupAction(_id, _handler, _caption, _icon, _onExecute, _allowOnMult
|
||||
action.group = _value;
|
||||
}
|
||||
|
||||
action.set_hint = function(_value) {
|
||||
action.hint = _value;
|
||||
}
|
||||
|
||||
// If true, the action will be rendered as checkbox
|
||||
action.set_checkbox = function(_value) {
|
||||
action.checkbox = _value;
|
||||
}
|
||||
|
||||
action.set_checked = function(_value) {
|
||||
action.checked = _value;
|
||||
}
|
||||
|
||||
// If radioGroup is >0 and the element is a checkbox, radioGroup specifies
|
||||
// the group of radio buttons this one belongs to
|
||||
action.set_radioGroup = function(_value) {
|
||||
action.radioGroup = _value;
|
||||
}
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
@ -136,8 +159,8 @@ function egwPopupActionImplementation()
|
||||
// Calculate context menu position from the given DOM-Node
|
||||
var node = _context;
|
||||
|
||||
x = node.offsetLeft;
|
||||
y = node.offsetTop;
|
||||
x = $(node).offset().left;
|
||||
y = $(node).offset().top;
|
||||
|
||||
_context = {"posx": x, "posy": y}
|
||||
}
|
||||
@ -284,10 +307,23 @@ function egwPopupActionImplementation()
|
||||
var item = _menu.addItem(link.actionObj.id, link.actionObj.caption,
|
||||
link.actionObj.iconUrl);
|
||||
item["default"] = link.actionObj["default"];
|
||||
item.data = link.actionObj;
|
||||
|
||||
// As this code is also used when a drag-drop popup menu is built,
|
||||
// we have to perform this check
|
||||
if (link.actionObj.type == "popup")
|
||||
{
|
||||
item.set_hint(link.actionObj.hint);
|
||||
item.set_checkbox(link.actionObj.checkbox);
|
||||
item.set_checked(link.actionObj.checked);
|
||||
item.set_groupIndex(link.actionObj.radioGroup);
|
||||
}
|
||||
|
||||
item.set_data(link.actionObj);
|
||||
if (link.enabled && _enabled)
|
||||
{
|
||||
item.set_onClick(function(elem) {
|
||||
// Copy the "checked" state
|
||||
elem.data.checked = elem.checked;
|
||||
elem.data.execute(_selected, _target);
|
||||
});
|
||||
}
|
||||
|
@ -406,3 +406,8 @@ egwMenuItem.prototype.set_data = function(_value)
|
||||
this.data = _value;
|
||||
}
|
||||
|
||||
egwMenuItem.prototype.set_hint = function(_value)
|
||||
{
|
||||
this.hint = _value;
|
||||
}
|
||||
|
||||
|
@ -116,6 +116,12 @@ egwMenuImpl.prototype._translateStructure = function(_structure, _parentId, _idC
|
||||
//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);
|
||||
}
|
||||
|
||||
var last_id = id;
|
||||
}
|
||||
|
||||
@ -136,7 +142,11 @@ egwMenuImpl.prototype.showAt = function(_x, _y, _onHide)
|
||||
}
|
||||
});
|
||||
}
|
||||
this.dhtmlxmenu.showContextMenu(_x, _y);
|
||||
|
||||
var self = this;
|
||||
window.setTimeout(function() {
|
||||
self.dhtmlxmenu.showContextMenu(_x, _y);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
egwMenuImpl.prototype.hide = function()
|
||||
|
@ -256,7 +256,9 @@
|
||||
"onExecute": alertClicked,
|
||||
"type": "popup",
|
||||
"group": 1,
|
||||
"order": 2
|
||||
"order": 2,
|
||||
"allowOnMultiple": "only",
|
||||
"hint": "Compresses multiple files and mails them"
|
||||
},
|
||||
{
|
||||
"id": "send_to",
|
||||
@ -333,6 +335,21 @@
|
||||
"iconUrl": "imgs/copy.png",
|
||||
"onExecute": alertClicked,
|
||||
"acceptedTypes": "file"
|
||||
},
|
||||
{
|
||||
"id": "chk1",
|
||||
"type": "popup",
|
||||
"checkbox": true,
|
||||
"checked": true,
|
||||
"caption": "Test1"
|
||||
},
|
||||
{
|
||||
"id": "chk2",
|
||||
"type": "popup",
|
||||
"checkbox": true,
|
||||
"checked": false,
|
||||
"caption": "Test2",
|
||||
"onExecute": alertClicked
|
||||
}
|
||||
]
|
||||
);
|
||||
@ -347,7 +364,9 @@
|
||||
{"actionId": "file_compress", "enabled": true},
|
||||
{"actionId": "file_delete", "enabled": true},
|
||||
{"actionId": "send_to", "enabled": true},
|
||||
"file_drag"
|
||||
"file_drag",
|
||||
"chk1",
|
||||
"chk2"
|
||||
];
|
||||
|
||||
var listboxFolderLinks = [
|
||||
|
Loading…
Reference in New Issue
Block a user