mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-01-09 15:38:27 +01:00
Added toggleSelectAll functions, improved egw_action_popup, tested, fixed some bugs
This commit is contained in:
parent
9e38d4e030
commit
419c2af704
@ -551,6 +551,45 @@ egwActionObject.prototype.getSelectedObjects = function(_test)
|
|||||||
return result;
|
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.
|
* 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()
|
egwActionObject.prototype.registerActions = function()
|
||||||
{
|
{
|
||||||
var groups = this.getActionImplementationGroups();
|
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()
|
egwActionObject.prototype.triggerCallback = function()
|
||||||
{
|
{
|
||||||
if (this.onBeforeTrigger)
|
if (this.onBeforeTrigger)
|
||||||
@ -885,6 +930,15 @@ egwActionObject.prototype.triggerCallback = function()
|
|||||||
return true;
|
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)
|
egwActionObject.prototype.executeActionImplementation = function(_implContext, _implType)
|
||||||
{
|
{
|
||||||
if (typeof _implType == "string")
|
if (typeof _implType == "string")
|
||||||
@ -892,46 +946,56 @@ egwActionObject.prototype.executeActionImplementation = function(_implContext, _
|
|||||||
|
|
||||||
if (typeof _implType == "object" && _implType)
|
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)
|
if (selectedActions.selected.length > 0 && egwObjectLength(selectedActions.links) > 0)
|
||||||
{
|
{
|
||||||
_implType.executeImplementation(_implContext,
|
return _implType.executeImplementation(_implContext,
|
||||||
selectedActions.selected, selectedActions.links);
|
selectedActions.selected, selectedActions.links);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.forceSelection = function()
|
||||||
|
{
|
||||||
|
var selected = this.getSelectedObjects();
|
||||||
|
|
||||||
|
// Check whether this object is in the list
|
||||||
|
var thisInList = selected.indexOf(this) != -1;
|
||||||
|
|
||||||
|
// If not, select it
|
||||||
|
if (!thisInList)
|
||||||
|
{
|
||||||
|
this.setSelected(true);
|
||||||
|
this._ifaceCallback(egwSetBit(this.getState(), EGW_AO_STATE_SELECTED, true),
|
||||||
|
EGW_AO_SHIFT_STATE_NONE);
|
||||||
|
selected = [this];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all selected objects, which returned true in their triggerCallback and
|
* Returns all selected objects, and all action links of those objects, which are
|
||||||
* all action links of those objects, which are of the given implementation type,
|
* of the given implementation type, wheras actionLink properties such as
|
||||||
* wheras actionLink properties such as "enabled" and "visible" are accumuleted.
|
* "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(_implType, _includeThis)
|
egwActionObject.prototype.getSelectedLinks = function(_actionType)
|
||||||
{
|
{
|
||||||
// Get all objects in this container which are currently selected
|
// Get all objects in this container which are currently selected
|
||||||
var selected = this.getSelectedObjects();
|
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 actionLinks = {};
|
||||||
var testedSelected = [];
|
var testedSelected = [];
|
||||||
for (var i = 0; i < selected.length; i++)
|
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
|
var olink = obj.actionLinks[j]; //object link
|
||||||
|
|
||||||
// Test whether the action type is of the given implementation type
|
// 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")
|
if (typeof actionLinks[olink.actionId] == "undefined")
|
||||||
{
|
{
|
||||||
actionLinks[olink.actionId] = {
|
actionLinks[olink.actionId] = {
|
||||||
"actionObj": olink.actionObj,
|
"actionObj": olink.actionObj,
|
||||||
"enabled": i == 0 && (olink.actionObj.allowOnMultiple || selected.length == 1),
|
"enabled": (testedSelected.length == 1),
|
||||||
"visible": false,
|
"visible": false,
|
||||||
"cnt": 0
|
"cnt": 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Accumulate the action link properties
|
||||||
var llink = actionLinks[olink.actionId];
|
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.visible = llink.visible || olink.visible;
|
||||||
llink.cnt++;
|
llink.cnt++;
|
||||||
}
|
}
|
||||||
@ -967,12 +1033,15 @@ egwActionObject.prototype.getSelectedLinks = function(_implType, _includeThis)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check whether all objects supported the action
|
||||||
for (k in actionLinks)
|
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
|
// Return an object which contains the accumulated actionLinks and all selected
|
||||||
// objects.
|
// objects.
|
||||||
return {
|
return {
|
||||||
@ -1150,7 +1219,12 @@ egwActionObjectInterface.prototype.getState = function()
|
|||||||
*/
|
*/
|
||||||
function egwActionObjectManager(_id, _manager)
|
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);
|
_manager, EGW_AO_FLAG_IS_CONTAINER);
|
||||||
|
|
||||||
|
// The object manager doesn't allow selections and cannot perform actions
|
||||||
|
ao.triggerCallback = function() {return false;};
|
||||||
|
|
||||||
|
return ao;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,17 +58,6 @@ function egwPopupActionImplementation()
|
|||||||
|
|
||||||
ai.type = "popup";
|
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)
|
ai.doRegisterAction = function(_aoi, _callback, _context)
|
||||||
{
|
{
|
||||||
var node = _aoi.getDOMNode();
|
var node = _aoi.getDOMNode();
|
||||||
@ -78,7 +67,9 @@ function egwPopupActionImplementation()
|
|||||||
node.oncontextmenu = function(e) {
|
node.oncontextmenu = function(e) {
|
||||||
//Obtain the event object
|
//Obtain the event object
|
||||||
if (!e)
|
if (!e)
|
||||||
|
{
|
||||||
e = window.event;
|
e = window.event;
|
||||||
|
}
|
||||||
|
|
||||||
if (_egw_active_menu)
|
if (_egw_active_menu)
|
||||||
{
|
{
|
||||||
@ -86,13 +77,15 @@ function egwPopupActionImplementation()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_xy = ai.getPageXY(e);
|
_xy = ai._getPageXY(e);
|
||||||
_callback.call(_context, _xy, ai);
|
_callback.call(_context, _xy, ai);
|
||||||
}
|
}
|
||||||
|
|
||||||
e.cancelBubble = true;
|
e.cancelBubble = true;
|
||||||
if (e.stopPropagation)
|
if (e.stopPropagation)
|
||||||
|
{
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
}
|
||||||
return false;
|
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)
|
ai.doExecuteImplementation = function(_context, _selected, _links)
|
||||||
{
|
{
|
||||||
|
//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);
|
var menu = ai._buildMenu(_links, _selected);
|
||||||
menu.showAt(_context.x, _context.y);
|
menu.showAt(_context.posx, _context.posy);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the context menu from the given action links
|
||||||
|
*/
|
||||||
ai._buildMenu = function(_links, _selected)
|
ai._buildMenu = function(_links, _selected)
|
||||||
{
|
{
|
||||||
var menu = new egwMenu();
|
var menu = new egwMenu();
|
||||||
@ -187,6 +202,17 @@ function egwPopupActionImplementation()
|
|||||||
return menu;
|
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;
|
return ai;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,9 @@
|
|||||||
<!-- Basic action stuff -->
|
<!-- Basic action stuff -->
|
||||||
<script src="../egw_action.js"></script>
|
<script src="../egw_action.js"></script>
|
||||||
<script src="../egw_action_common.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>
|
<script src="js/jquery.js"></script>
|
||||||
|
|
||||||
<!-- Popup stuff -->
|
<!-- 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="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>
|
<tr id="file5"><td><img src="imgs/page.png"/></td><td style="width: 200px">File 5</td><td><input type="checkbox"></td></tr>
|
||||||
</table>
|
</table>
|
||||||
|
<button id="performAction">Perform action...</button><button id="selectAll">Select All</button>
|
||||||
<script>
|
<script>
|
||||||
var actionManager = null;
|
var actionManager = null;
|
||||||
var objectManager = null;
|
var objectManager = null;
|
||||||
@ -256,7 +260,17 @@
|
|||||||
obj.updateActionLinks(listboxFolderLinks);
|
obj.updateActionLinks(listboxFolderLinks);
|
||||||
|
|
||||||
obj.registerActions();
|
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>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
Loading…
Reference in New Issue
Block a user