Added toggleSelectAll functions, improved egw_action_popup, tested, fixed some bugs

This commit is contained in:
Andreas Stöckel 2011-02-26 20:40:27 +00:00
parent 9e38d4e030
commit 419c2af704
3 changed files with 161 additions and 47 deletions

View File

@ -551,6 +551,45 @@ egwActionObject.prototype.getSelectedObjects = function(_test)
return result;
}
/**
* Returns whether all objects in this tree are selected
*/
egwActionObject.prototype.getAllSelected = function()
{
if (this.getSelected())
{
for (var i = 0; i < this.children.length; i++)
{
if (!this.children[i].getAllSelected())
return false;
}
return true;
}
return false;
}
/**
* Toggles the selection of all objects.
*
* @param _select boolean specifies whether the objects should get selected or not.
* If this parameter is not supplied, the selection will be toggled.
*/
egwActionObject.prototype.toggleAllSelected = function(_select)
{
if (typeof _select == "undefined")
{
_select = !this.getAllSelected();
}
this.setSelected(_select);
for (var i = 0; i < this.children.length; i++)
{
this.children[i].toggleAllSelected(_select);
}
}
/**
* Creates a list which contains all items of the element tree.
*
@ -856,6 +895,9 @@ egwActionObject.prototype.updateActionLinks = function(_actionLinks, _recursive,
}
}
/**
* Registers the action implementations inside the DOM-Tree.
*/
egwActionObject.prototype.registerActions = function()
{
var groups = this.getActionImplementationGroups();
@ -876,6 +918,9 @@ egwActionObject.prototype.registerActions = function()
}
}
/**
* Calls the onBeforeTrigger function - if it is set - or returns false.
*/
egwActionObject.prototype.triggerCallback = function()
{
if (this.onBeforeTrigger)
@ -885,6 +930,15 @@ egwActionObject.prototype.triggerCallback = function()
return true;
}
/**
* Executes the action implementation which is associated to the given action type.
*
* @param object _implContext is data which should be delivered to the action implementation.
* E.g. in case of the popup action implementation, the x and y coordinates where the
* menu should open are transmitted.
* @param string _implType is the action type for which the implementation should be
* executed.
*/
egwActionObject.prototype.executeActionImplementation = function(_implContext, _implType)
{
if (typeof _implType == "string")
@ -892,37 +946,30 @@ egwActionObject.prototype.executeActionImplementation = function(_implContext, _
if (typeof _implType == "object" && _implType)
{
var selectedActions = this.getSelectedLinks(_implType.type, true);
this.forceSelection();
var selectedActions = this.getSelectedLinks(_implType.type);
if (selectedActions.selected.length > 0 && egwObjectLength(selectedActions.links) > 0)
{
_implType.executeImplementation(_implContext,
return _implType.executeImplementation(_implContext,
selectedActions.selected, selectedActions.links);
}
}
return false;
}
/**
* 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.
* Forces the object to be inside the currently selected objects. If this is
* not the case, the object will select itself and deselect all other objects.
*/
egwActionObject.prototype.getSelectedLinks = function(_implType, _includeThis)
egwActionObject.prototype.forceSelection = function()
{
// 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;
}
}
// Check whether this object is in the list
var thisInList = selected.indexOf(this) != -1;
// If not, select it
if (!thisInList)
{
this.setSelected(true);
@ -932,6 +979,23 @@ egwActionObject.prototype.getSelectedLinks = function(_implType, _includeThis)
}
}
/**
* Returns all selected objects, and all action links of those objects, which are
* of the given implementation type, wheras actionLink properties such as
* "enabled" and "visible" are accumulated.
*
* Objects have the chance to change their action links or to deselect themselves
* in the onBeforeTrigger event, which is evaluated by the triggerCallback function.
*
* @param _actionType is the action type for which the actionLinks should be collected.
* @returns object An object which contains a "links" and a "selected" section with
* an array of links/selected objects-
*/
egwActionObject.prototype.getSelectedLinks = function(_actionType)
{
// Get all objects in this container which are currently selected
var selected = this.getSelectedObjects();
var actionLinks = {};
var testedSelected = [];
for (var i = 0; i < selected.length; i++)
@ -946,20 +1010,22 @@ egwActionObject.prototype.getSelectedLinks = function(_implType, _includeThis)
var olink = obj.actionLinks[j]; //object link
// Test whether the action type is of the given implementation type
if (olink.actionObj.type == _implType)
if (olink.actionObj.type == _actionType)
{
if (typeof actionLinks[olink.actionId] == "undefined")
{
actionLinks[olink.actionId] = {
"actionObj": olink.actionObj,
"enabled": i == 0 && (olink.actionObj.allowOnMultiple || selected.length == 1),
"enabled": (testedSelected.length == 1),
"visible": false,
"cnt": 0
}
}
// Accumulate the action link properties
var llink = actionLinks[olink.actionId];
llink.enabled = llink.enabled && olink.enabled && olink.visible;
llink.enabled = llink.enabled && olink.enabled &&
olink.visible;
llink.visible = llink.visible || olink.visible;
llink.cnt++;
}
@ -967,12 +1033,15 @@ egwActionObject.prototype.getSelectedLinks = function(_implType, _includeThis)
}
}
// Check whether all objects supported the action
for (k in actionLinks)
{
actionLinks[k].enabled = actionLinks[k].enabled && (actionLinks[k].cnt >= selected.length);
actionLinks[k].enabled = actionLinks[k].enabled &&
(actionLinks[k].cnt >= testedSelected.length) &&
(actionLinks[k].actionObj.allowOnMultiple ||
actionLinks[k].cnt == 1);
}
// Return an object which contains the accumulated actionLinks and all selected
// objects.
return {
@ -1150,7 +1219,12 @@ egwActionObjectInterface.prototype.getState = function()
*/
function egwActionObjectManager(_id, _manager)
{
return new egwActionObject(_id, null, new egwActionObjectInterface(),
var ao = new egwActionObject(_id, null, new egwActionObjectInterface(),
_manager, EGW_AO_FLAG_IS_CONTAINER);
// The object manager doesn't allow selections and cannot perform actions
ao.triggerCallback = function() {return false;};
return ao;
}

View File

@ -58,17 +58,6 @@ function egwPopupActionImplementation()
ai.type = "popup";
ai.getPageXY = function getPageXY(event)
{
// document.body.scrollTop does not work in IE
var scrollTop = document.body.scrollTop ? document.body.scrollTop :
document.documentElement.scrollTop;
var scrollLeft = document.body.scrollLeft ? document.body.scrollLeft :
document.documentElement.scrollLeft;
return {'x': (event.clientX + scrollLeft), 'y': (event.clientY + scrollTop)};
}
ai.doRegisterAction = function(_aoi, _callback, _context)
{
var node = _aoi.getDOMNode();
@ -78,7 +67,9 @@ function egwPopupActionImplementation()
node.oncontextmenu = function(e) {
//Obtain the event object
if (!e)
{
e = window.event;
}
if (_egw_active_menu)
{
@ -86,13 +77,15 @@ function egwPopupActionImplementation()
}
else
{
_xy = ai.getPageXY(e);
_xy = ai._getPageXY(e);
_callback.call(_context, _xy, ai);
}
e.cancelBubble = true;
if (e.stopPropagation)
{
e.stopPropagation();
}
return false;
}
}
@ -103,12 +96,34 @@ function egwPopupActionImplementation()
//
}
/**
* Builds the context menu and shows it at the given position/DOM-Node.
*/
ai.doExecuteImplementation = function(_context, _selected, _links)
{
var menu = ai._buildMenu(_links, _selected);
menu.showAt(_context.x, _context.y);
//Check whether the
if ((typeof _context.posx != "number" || typeof _context.posy != "number") &&
typeof _context.id != "undefined")
{
// Calculate context menu position from the given DOM-Node
var node = _context;
x = node.offsetLeft;
y = node.offsetTop;
_context = {"posx": x, "posy": y}
}
var menu = ai._buildMenu(_links, _selected);
menu.showAt(_context.posx, _context.posy);
return true;
}
/**
* Builds the context menu from the given action links
*/
ai._buildMenu = function(_links, _selected)
{
var menu = new egwMenu();
@ -187,6 +202,17 @@ function egwPopupActionImplementation()
return menu;
}
ai._getPageXY = function getPageXY(event)
{
// document.body.scrollTop does not work in IE
var scrollTop = document.body.scrollTop ? document.body.scrollTop :
document.documentElement.scrollTop;
var scrollLeft = document.body.scrollLeft ? document.body.scrollLeft :
document.documentElement.scrollLeft;
return {'posx': (event.clientX + scrollLeft), 'posy': (event.clientY + scrollTop)};
}
return ai;
}

View File

@ -5,6 +5,9 @@
<!-- Basic action stuff -->
<script src="../egw_action.js"></script>
<script src="../egw_action_common.js"></script>
<!-- JQuery is just used in this example. The egw_action scripts do not
need JQuery! -->
<script src="js/jquery.js"></script>
<!-- Popup stuff -->
@ -64,6 +67,7 @@
<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>
<button id="performAction">Perform action...</button><button id="selectAll">Select All</button>
<script>
var actionManager = null;
var objectManager = null;
@ -256,7 +260,17 @@
obj.updateActionLinks(listboxFolderLinks);
obj.registerActions();
})
});
$("#selectAll").click(function() {
objectManager.toggleAllSelected();
});
$("#performAction").click(function(e) {
if (!objectManager.executeActionImplementation(this, "popup"))
alert("Please select one or more objects.");
return false;
});
}
</script>
</body>