From e7bd5a48138f95a688c002521d5e1aab9ecf5b05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20St=C3=B6ckel?= Date: Mon, 14 Mar 2011 20:11:08 +0000 Subject: [PATCH] Modernized grid design a bit, added auto triggering of the default action to the popup action, added simple action-binding to the egwGrid --- phpgwapi/js/egw_action/egw_action.js | 5 +- phpgwapi/js/egw_action/egw_action_popup.js | 54 +++++++-- phpgwapi/js/egw_action/egw_grid.js | 20 ++++ phpgwapi/js/egw_action/egw_grid_data.js | 39 ++++++- phpgwapi/js/egw_action/egw_grid_view.js | 16 ++- phpgwapi/js/egw_action/egw_menu_dhtmlx.js | 2 +- phpgwapi/js/egw_action/test/grid.css | 21 +++- .../egw_action/test/skins/dhtmlxmenu_egw.css | 11 +- .../js/egw_action/test/test_grid_view.html | 106 +++++++++++++++++- 9 files changed, 244 insertions(+), 30 deletions(-) diff --git a/phpgwapi/js/egw_action/egw_action.js b/phpgwapi/js/egw_action/egw_action.js index c1e68ea622..a2b521cb8b 100644 --- a/phpgwapi/js/egw_action/egw_action.js +++ b/phpgwapi/js/egw_action/egw_action.js @@ -386,6 +386,7 @@ function egwActionObject(_id, _parent, _iface, _manager, _flags) this.actionLinks = []; this.manager = _manager; this.flags = _flags; + this.data = null; this.registeredImpls = []; @@ -1012,7 +1013,7 @@ egwActionObject.prototype.updateActionLinks = function(_actionLinks, _recursive, } } - if (this.getVisible()) + if (this.getVisible() && this.iface != null) { this.registerActions(); } @@ -1024,7 +1025,7 @@ egwActionObject.prototype.updateActionLinks = function(_actionLinks, _recursive, egwActionObject.prototype._reconnectCallback = function() { this.registeredImpls = []; - this.registerActions; + this.registerActions(); } /** diff --git a/phpgwapi/js/egw_action/egw_action_popup.js b/phpgwapi/js/egw_action/egw_action_popup.js index f02ce0f4ad..2905a391b7 100644 --- a/phpgwapi/js/egw_action/egw_action_popup.js +++ b/phpgwapi/js/egw_action/egw_action_popup.js @@ -64,6 +64,13 @@ function egwPopupActionImplementation() if (node) { + node.ondblclick = function(e) { + _callback.call(_context, "default", ai); + + e.preventDefault(); + return false; + } + node.oncontextmenu = function(e) { //Obtain the event object if (!e) @@ -105,23 +112,45 @@ function egwPopupActionImplementation() */ ai.doExecuteImplementation = function(_context, _selected, _links) { - //Check whether the - if ((typeof _context.posx != "number" || typeof _context.posy != "number") && - typeof _context.id != "undefined") + if (_context != "default") { - // Calculate context menu position from the given DOM-Node - var node = _context; + //Check whether the context has the posx and posy parameters + 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; + x = node.offsetLeft; + y = node.offsetTop; - _context = {"posx": x, "posy": y} + _context = {"posx": x, "posy": y} + } + + var menu = ai._buildMenu(_links, _selected); + menu.showAt(_context.posx, _context.posy); + + return true; + } + else + { + var defaultAction = null; + for (k in _links) + { + if (_links[k].actionObj["default"] && _links[k].enabled) + { + defaultAction = _links[k].actionObj; + break; + } + } + + if (defaultAction) + { + defaultAction.execute(_selected); + } } - var menu = ai._buildMenu(_links, _selected); - menu.showAt(_context.posx, _context.posy); - - return true; + return false; } /** @@ -187,6 +216,7 @@ function egwPopupActionImplementation() { var item = menu.addItem(link.actionObj.id, link.actionObj.caption, link.actionObj.iconUrl); + item["default"] = link.actionObj["default"]; item.data = link.actionObj; if (link.enabled) { diff --git a/phpgwapi/js/egw_action/egw_grid.js b/phpgwapi/js/egw_action/egw_grid.js index 2384139e01..1fe431b532 100644 --- a/phpgwapi/js/egw_action/egw_grid.js +++ b/phpgwapi/js/egw_action/egw_grid.js @@ -11,6 +11,7 @@ /* uses + egw_action, egw_action_common, egw_action_view, egw_action_data, @@ -42,6 +43,11 @@ function egwGrid(_parentNode, _columns, _objectManager, _fetchCallback, _context this.gridOuter.updateColumns(this.columns.getColumnData()); } +egwGrid.prototype.setActionLinkGroup = function(_group, _links) +{ + this.dataRoot.actionLinkGroups[_group] = _links; +} + egwGrid.prototype.resize = function(_w, _h) { if (_w != this.width) @@ -72,3 +78,17 @@ egwGrid.prototype.columnsUpdate = function(_column) } } +/** + * Emptys the grid + */ +egwGrid.prototype.empty = function() +{ + this.dataRoot.empty(); + this.gridOuter.grid.empty(); +} + +egwGrid.prototype.reload = function() +{ + this.gridOuter.empty(); +} + diff --git a/phpgwapi/js/egw_action/egw_grid_data.js b/phpgwapi/js/egw_action/egw_grid_data.js index eb0898d579..ee59c656e8 100644 --- a/phpgwapi/js/egw_action/egw_grid_data.js +++ b/phpgwapi/js/egw_action/egw_grid_data.js @@ -66,6 +66,8 @@ function egwGridDataElement(_id, _parent, _columns, _readQueue, _objectManager) this.type = egwGridViewRow; this.userData = null; this.updatedGrid = null; + this.actionLinkGroups = {}; + this.group = false; this.gridViewObj = null; } @@ -100,6 +102,17 @@ egwGridDataElement.prototype.set_canHaveChildren = function(_value) this.canHaveChildren = _value && (this.children.length == 0); } +egwGridDataElement.prototype.set_group = function(_value) +{ + this.group = _value; + + var root = this.getRootElement(); + if (typeof root.actionLinkGroups[_value] != "undefined") + { + this.actionObject.updateActionLinks(root.actionLinkGroups[_value]); + } +} + /** * Updates the column data. The column data is an object (used as associative array) * which may be of the following outline: @@ -290,6 +303,7 @@ egwGridDataElement.prototype.insertElement = function(_index, _id) // Create the action object var object = this.actionObject.insertObject(_index, _id, null, 0); + object.data = element; // Link the two together element.actionObject = object; @@ -535,7 +549,9 @@ egwGridDataElement.prototype.setGridViewObj = function(_obj) if (_obj && typeof _obj.getAOI == "function") { - this.actionObject.setAOI(_obj.getAOI()); + var aoi = _obj.getAOI(); + this.actionObject.setAOI(aoi); + aoi.reconnectActions(); } else { @@ -601,6 +617,14 @@ egwGridDataElement.prototype.callEndUpdate = function() } } +/** + * Deletes all child elements + */ +egwGridDataElement.prototype.empty = function() +{ + this.children = []; + this.readQueue.empty(); +} /** - egwGridDataReadQueue -- **/ @@ -815,7 +839,7 @@ egwGridDataQueue.prototype.prefetch = function(_cnt) { var idx = planes[plane].idx; - if (idx == planes[plane].parent.children.length) + if (!planes.parent || idx == planes[plane].parent.children.length) { planes[plane].done = true; done++; @@ -853,6 +877,11 @@ egwGridDataQueue.prototype.prefetch = function(_cnt) } } +egwGridDataQueue.prototype.empty = function() +{ + this.queue = []; +} + /** * Empties the queue and calls the fetch callback which cares about retrieving * the data from the server. @@ -896,6 +925,12 @@ egwGridDataQueue.prototype.flushQueue = function(_doPrefetch) this.timeoutId = 0; } +/** + * Internal function which is called when the data is received from the fetchCallback. + * + * @param _data contains the data which has been retrieved by the fetchCallback + * @param _queue is the list of elements which had been requested. + */ egwGridDataQueue.prototype.dataCallback = function(_data, _queue) { var rootData = []; diff --git a/phpgwapi/js/egw_action/egw_grid_view.js b/phpgwapi/js/egw_action/egw_grid_view.js index aef1fdee6c..fed9ad80bb 100644 --- a/phpgwapi/js/egw_action/egw_grid_view.js +++ b/phpgwapi/js/egw_action/egw_grid_view.js @@ -919,6 +919,7 @@ function egwGridViewGrid_empty(_newColumns) this.innerNode.empty(); this.children = []; + this.maxIconWidth = 16; } function egwGridViewGrid_addContainer(_class) @@ -1128,7 +1129,7 @@ function egwGridViewRow_aoiSetState(_state, _shiftState) function egwGridViewRow_aoiGetDOMNode() { - return this.row.parentNode ? this.row.parentNode : null; + return this.row.parentNode ? this.row.parentNode.context : null; } /** @@ -1155,6 +1156,7 @@ var function egwGridViewRow_doInsertIntoDOM() { this.parentNode.empty(); + this.parentNode.addClass("row"); // Setup the aoi and inform the item about it if (!this.aoi) @@ -1180,10 +1182,15 @@ function egwGridViewRow_doInsertIntoDOM() e.data.item._columnClick(egwGetShiftState(e), e.data.col); }); + // Mark the first and last column if (i == 0) { td.addClass("first"); } + if (i == this.columns.length - 1) + { + td.addClass("last"); + } // Set the column width if (EGW_GRID_VIEW_ROW_BORDER === false) @@ -1255,6 +1262,8 @@ function egwGridViewRow_doUpdateData(_immediate) } e.data.setOpen(!e.data.opened); + + return false; // Don't bubble this event }); } td.append(arrow); @@ -1294,6 +1303,7 @@ function egwGridViewRow_doUpdateData(_immediate) if (data[col.id].caption) { var caption = $(document.createElement("span")); + caption.addClass("caption"); caption.html(data[col.id].caption); td.append(caption); } @@ -1323,7 +1333,7 @@ function egwGridViewRow_doUpdateData(_immediate) function egwGridViewRow_checkOdd() { - if (this.item && this.parentNode) +/* if (this.item && this.parentNode) { // Update the "odd"-Class of the item var odd = this.item.isOdd(); @@ -1333,7 +1343,7 @@ function egwGridViewRow_checkOdd() $(this.parentNode).toggleClass("odd", odd); this.isOdd = odd; } - } + }*/ } function egwGridViewRow_doSetViewArea() diff --git a/phpgwapi/js/egw_action/egw_menu_dhtmlx.js b/phpgwapi/js/egw_action/egw_menu_dhtmlx.js index a0d3914e22..cda1a9771d 100644 --- a/phpgwapi/js/egw_action/egw_menu_dhtmlx.js +++ b/phpgwapi/js/egw_action/egw_menu_dhtmlx.js @@ -102,7 +102,7 @@ egwMenuImpl.prototype._translateStructure = function(_structure, _parentId, _idC { var caption = elem.caption; if (elem["default"]) - caption = "" + caption + "" + caption = "" + caption + ""; this.dhtmlxmenu.addNewChild(_parentId, i, id, caption, !elem.enabled, elem.iconUrl, elem.iconUrl); } diff --git a/phpgwapi/js/egw_action/test/grid.css b/phpgwapi/js/egw_action/test/grid.css index e68abf6ca1..f53922c902 100644 --- a/phpgwapi/js/egw_action/test/grid.css +++ b/phpgwapi/js/egw_action/test/grid.css @@ -30,9 +30,9 @@ body, td, th { background-color: #b7c3ff; } -.egwGridView_grid tr.selected.odd td { +/*.egwGridView_grid tr.selected.odd td { background-color: #9dadff; -} +}*/ .egwGridView_scrollarea { width: 100%; @@ -61,6 +61,15 @@ body, td, th { border-right: 1px solid silver; padding: 2px 3px 2px 4px; margin: 0; + border-bottom: 1px solid #e0e0e0; +} + +.egwGridView_grid td.last { + border-right-width: 0; +} + +.egwGridView_grid tr.row:hover { + background-color: #f0f0ff; } .egwGridView_grid tr { @@ -72,9 +81,9 @@ body, td, th { display: none; } -.egwGridView_grid tr.odd { +/*.egwGridView_grid tr.odd { background-color: #F1F1F1; -} +}*/ .egwGridView_grid span.indentation { display: inline-block; @@ -129,6 +138,10 @@ body, td, th { text-align: center; } +.egwGridView_grid span.caption { + cursor: default; +} + .egwGridView_outer thead th { background-color: #E0E0E0; font-weight: normal; diff --git a/phpgwapi/js/egw_action/test/skins/dhtmlxmenu_egw.css b/phpgwapi/js/egw_action/test/skins/dhtmlxmenu_egw.css index 26af8d7107..9612a47dae 100644 --- a/phpgwapi/js/egw_action/test/skins/dhtmlxmenu_egw.css +++ b/phpgwapi/js/egw_action/test/skins/dhtmlxmenu_egw.css @@ -13,6 +13,7 @@ -moz-user-select: none; padding: 0px 7px; } + .dhtmlx_winviewport.dhtmlx_skin_egw div.dhtmlxMenu_egw_Middle, .dhxlayout_fullscreened div.dhtmlxMenu_egw_Middle, .dhx_tabbar_zone.dhx_tabbar_zone_egw div.dhtmlxMenu_egw_Middle, @@ -61,7 +62,7 @@ div.dhtmlxMenu_egw_TopLevel_Item_Selected { position: relative; float: left; font-family: Arial, Helvetica, Sans-Serif; - font-size: 10pt; + font-size: 11px; font-weight: normal; cursor: default; white-space: nowrap; @@ -187,7 +188,7 @@ div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl td.sub } div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl div.sub_item_text { font-family: Arial, Helvetica, Sans-Serif; - font-size: 10pt; + font-size: 11px; font-weight: normal; color: #000000; white-space: nowrap; @@ -202,7 +203,7 @@ div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl td.sub } div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl td.sub_item_hk div.sub_item_hk { font-family: Arial, Helvetica, Sans-Serif; - font-size: 10px; + font-size: 11px; color: #a4bed4; text-align: right; } @@ -303,7 +304,7 @@ div.dhtmlxMenu_egw_SubLevelArea_ArrowDown_Disabled div.dhtmlxMenu_SubLevelArea_A left: none; right: 8px; font-family: Arial, Helvetica, Sans-Serif; - font-size: 10pt; + font-size: 11px; color: #000000; cursor: default; } @@ -316,7 +317,7 @@ div.dhtmlxMenu_egw_SubLevelArea_ArrowDown_Disabled div.dhtmlxMenu_SubLevelArea_A right: none; left: 8px; font-family: Arial, Helvetica, Sans-Serif; - font-size: 10pt; + font-size: 11px; color: #000000; cursor: default; } diff --git a/phpgwapi/js/egw_action/test/test_grid_view.html b/phpgwapi/js/egw_action/test/test_grid_view.html index d7dd422e58..09461a8ca5 100644 --- a/phpgwapi/js/egw_action/test/test_grid_view.html +++ b/phpgwapi/js/egw_action/test/test_grid_view.html @@ -7,14 +7,24 @@ + + + + + + + + + +

Test for dynamically displaying and loading grid lines

@@ -79,6 +89,86 @@ } ]; + var actions = + [ + { + "id": "folder_open", + "iconUrl": "imgs/folder.png", + "caption": "Open folder", + "onExecute": alertClicked, + "allowOnMultiple": false, + "type": "popup", + "default": true + }, + { + "id": "file_view", + "iconUrl": "imgs/view.png", + "caption": "View", + "onExecute": alertClicked, + "allowOnMultiple": false, + "type": "popup", + }, + { + "id": "file_preview", + "iconUrl": "imgs/preview.png", + "caption": "Preview", + "onExecute": alertClicked, + "allowOnMultiple": false, + "type": "popup", + "default": true + }, + { + "id": "file_delete", + "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 + } + ]; + + var listboxFolderLinks = [ + {"actionId": "folder_open", "enabled": true}, + {"actionId": "file_compress_email", "enabled": true}, + {"actionId": "file_compress", "enabled": true}, + {"actionId": "file_delete", "enabled": true} + ]; + function fetchDataProc(_elems, _columns, _callback, _context) { // Delay the result a bit to simulate real network traffic @@ -122,7 +212,8 @@ "id": _elems[i], "data": data, "caption": _elems[i], - "iconUrl": "imgs/folder.png" + "iconUrl": "imgs/folder.png", + "group": "folder" }); } } @@ -133,10 +224,13 @@ $(document).ready(function() { actionManager = new egwActionManager(); + actionManager.updateActions(actions); + objectManager = new egwActionObjectManager("", actionManager); grid = new egwGrid($("#container"), columns, objectManager, fetchDataProc, window); + grid.setActionLinkGroup("folder", listboxFolderLinks); grid.dataRoot.loadData( [ { @@ -185,6 +279,16 @@ } } } + + 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 + "'"); + }