mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-08 17:14:44 +01:00
Implemented keyboard navigation and data retrival for uids
This commit is contained in:
parent
e20f2e9333
commit
cfa9c190bb
@ -80,7 +80,8 @@ var et2_dataview_controller = Class.extend({
|
||||
|
||||
// Create the selection manager
|
||||
this._selectionMgr = new et2_dataview_selectionManager(this._indexMap,
|
||||
_actionObjectManager, this._selectionFetchRange, this);
|
||||
_actionObjectManager, this._selectionFetchRange,
|
||||
this._makeIndexVisible, this);
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
@ -658,8 +659,13 @@ var et2_dataview_controller = Class.extend({
|
||||
|
||||
// Update the total element count in the grid
|
||||
this.self._grid.setTotalCount(_response.total);
|
||||
this.self._selectionMgr.setTotalCount(_response.total);
|
||||
},
|
||||
|
||||
/**
|
||||
* Callback function used by the selection manager to translate the selected
|
||||
* range to uids.
|
||||
*/
|
||||
_selectionFetchRange: function (_range, _callback, _context) {
|
||||
this._dataProvider.dataFetch(
|
||||
{ "start": _range.top, "num_rows": _range.bottom - _range.top + 1,
|
||||
@ -668,6 +674,13 @@ var et2_dataview_controller = Class.extend({
|
||||
_callback.call(_context, _response.order);
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Tells the grid to make the given index visible.
|
||||
*/
|
||||
_makeIndexVisible: function (_idx) {
|
||||
this._grid.makeIndexVisible(_idx);
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -12,20 +12,28 @@
|
||||
|
||||
/*egw:uses
|
||||
et2_dataview_view_aoi;
|
||||
|
||||
egw_action.egw_keymanager;
|
||||
*/
|
||||
|
||||
/**
|
||||
* The selectioManager is internally used by the et2_dataview_controller class
|
||||
* to manage the row selection.
|
||||
* As the action system does not allow selection of entries which are currently
|
||||
* not in the dom tree, we have to manage this in this class. The idea is to
|
||||
* manage an external action object interface for each visible row and proxy all
|
||||
* state changes between an dummy action object, that does no selection handling,
|
||||
* and the external action object interface.
|
||||
*/
|
||||
var et2_dataview_selectionManager = Class.extend({
|
||||
|
||||
init: function (_indexMap, _actionObjectManager, _queryRangeCallback,
|
||||
_context) {
|
||||
_makeVisibleCallback, _context) {
|
||||
// Copy the arguments
|
||||
this._indexMap = _indexMap;
|
||||
this._actionObjectManager = _actionObjectManager;
|
||||
this._queryRangeCallback = _queryRangeCallback;
|
||||
this._makeVisibleCallback = _makeVisibleCallback;
|
||||
this._context = _context;
|
||||
|
||||
// Internal map which contains all curently selected uids and their
|
||||
@ -34,79 +42,48 @@ var et2_dataview_selectionManager = Class.extend({
|
||||
this._focusedEntry = null;
|
||||
this._invertSelection = false;
|
||||
this._inUpdate = false;
|
||||
this._total = 0;
|
||||
},
|
||||
|
||||
setIndexMap: function (_indexMap) {
|
||||
this._indexMap = _indexMap;
|
||||
},
|
||||
|
||||
setTotalCount: function (_total) {
|
||||
this._total = _total;
|
||||
},
|
||||
|
||||
registerRow: function (_uid, _idx, _tr, _links) {
|
||||
|
||||
// Get the corresponding entry from the registered rows array
|
||||
var entry = this._getRegisteredRowsEntry(_uid);
|
||||
|
||||
// If the row has changed unregister the old one and do not delete
|
||||
// entry from the entry map
|
||||
if (entry.tr && entry.tr !== _tr) {
|
||||
this.unregisterRow(_uid, entry.tr, true);
|
||||
}
|
||||
|
||||
// Create the AOI for the tr
|
||||
if (!entry.tr)
|
||||
if (!entry.tr && _links)
|
||||
{
|
||||
// Create the AOI which is used internally in the selection manager
|
||||
// this AOI is not connected to the AO, as the selection manager
|
||||
// cares about selection etc.
|
||||
entry.aoi = new et2_dataview_rowAOI(_tr);
|
||||
entry.aoi.setStateChangeCallback(
|
||||
function (_newState, _changedBit, _shiftState) {
|
||||
if (_changedBit === EGW_AO_STATE_SELECTED)
|
||||
{
|
||||
// Call the select handler
|
||||
this._handleSelect(
|
||||
_uid,
|
||||
entry,
|
||||
egwBitIsSet(_shiftState, EGW_AO_SHIFT_STATE_BLOCK),
|
||||
egwBitIsSet(_shiftState, EGW_AO_SHIFT_STATE_MULTI)
|
||||
);
|
||||
}
|
||||
}, this);
|
||||
|
||||
// Create AOI
|
||||
if (_links)
|
||||
{
|
||||
var dummyAOI = new egwActionObjectInterface();
|
||||
var self = this;
|
||||
|
||||
// Handling for Action Implementations updating the state
|
||||
dummyAOI.doSetState = function (_state) {
|
||||
if (!self._inUpdate)
|
||||
{
|
||||
// Update the "focused" flag
|
||||
self.setFocused(_uid, egwBitIsSet(_state, EGW_AO_STATE_FOCUSED));
|
||||
|
||||
// Generally update the state
|
||||
self._updateState(_uid, _state);
|
||||
}
|
||||
};
|
||||
|
||||
// Connect the "doTriggerEvent" of the dummy AOI to our internal
|
||||
// aoi.
|
||||
dummyAOI.doTriggerEvent = entry.aoi.doTiggerEvent;
|
||||
|
||||
// Implementation of the getDOMNode function, so that the event
|
||||
// handlers can be properly bound
|
||||
dummyAOI.getDOMNode = function () { return _tr; };
|
||||
|
||||
// Create an action object for the tr and connect it to a dummy AOI
|
||||
entry.ao = this._actionObjectManager.addObject(_uid, dummyAOI);
|
||||
entry.ao.updateActionLinks(_links);
|
||||
}
|
||||
this._attachActionObjectInterface(entry, _tr, _uid);
|
||||
this._attachActionObject(entry, _tr, _uid, _links, _idx)
|
||||
}
|
||||
|
||||
// Update the entry
|
||||
entry.idx = _idx;
|
||||
entry.ao._index = entry.idx = _idx;
|
||||
entry.tr = _tr;
|
||||
|
||||
// Update the visible state of the _tr
|
||||
this._updateEntryState(entry, entry.state);
|
||||
},
|
||||
|
||||
unregisterRow: function (_uid, _tr) {
|
||||
unregisterRow: function (_uid, _tr, _noDelete) {
|
||||
|
||||
// _noDelete defaults to false
|
||||
_noDelete = _noDelete ? true : false;
|
||||
|
||||
if (typeof this._registeredRows[_uid] !== "undefined"
|
||||
&& this._registeredRows[_uid].tr === _tr)
|
||||
{
|
||||
@ -122,7 +99,8 @@ var et2_dataview_selectionManager = Class.extend({
|
||||
this._registeredRows[_uid].ao = null;
|
||||
}
|
||||
|
||||
if (this._registeredRows[_uid].state === EGW_AO_STATE_NORMAL)
|
||||
if (!_noDelete
|
||||
&& this._registeredRows[_uid].state === EGW_AO_STATE_NORMAL)
|
||||
{
|
||||
delete this._registeredRows[_uid];
|
||||
}
|
||||
@ -180,10 +158,140 @@ var et2_dataview_selectionManager = Class.extend({
|
||||
}
|
||||
},
|
||||
|
||||
getSelected: function () {
|
||||
// Collect all currently selected ids
|
||||
var ids = [];
|
||||
for (var key in this._registeredRows)
|
||||
{
|
||||
if (egwBitIsSet(this._registeredRows[key].state, EGW_AO_STATE_SELECTED))
|
||||
{
|
||||
ids.push(key);
|
||||
}
|
||||
}
|
||||
|
||||
// Return an array containing those ids
|
||||
return {
|
||||
"inverted": this._invertSelection,
|
||||
"ids": ids
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/** -- PRIVATE FUNCTIONS -- **/
|
||||
|
||||
|
||||
_attachActionObjectInterface: function (_entry, _tr, _uid) {
|
||||
// Create the AOI which is used internally in the selection manager
|
||||
// this AOI is not connected to the AO, as the selection manager
|
||||
// cares about selection etc.
|
||||
_entry.aoi = new et2_dataview_rowAOI(_tr);
|
||||
_entry.aoi.setStateChangeCallback(
|
||||
function (_newState, _changedBit, _shiftState) {
|
||||
if (_changedBit === EGW_AO_STATE_SELECTED)
|
||||
{
|
||||
// Call the select handler
|
||||
this._handleSelect(
|
||||
_uid,
|
||||
_entry,
|
||||
egwBitIsSet(_shiftState, EGW_AO_SHIFT_STATE_BLOCK),
|
||||
egwBitIsSet(_shiftState, EGW_AO_SHIFT_STATE_MULTI)
|
||||
);
|
||||
}
|
||||
}, this);
|
||||
},
|
||||
|
||||
_getDummyAOI: function (_entry, _tr, _uid, _idx) {
|
||||
// Create AOI
|
||||
var dummyAOI = new egwActionObjectInterface();
|
||||
var self = this;
|
||||
|
||||
// Handling for Action Implementations updating the state
|
||||
dummyAOI.doSetState = function (_state) {
|
||||
if (!self._inUpdate)
|
||||
{
|
||||
// Update the "focused" flag
|
||||
self.setFocused(_uid, egwBitIsSet(_state, EGW_AO_STATE_FOCUSED));
|
||||
|
||||
// Generally update the state
|
||||
self._updateState(_uid, _state);
|
||||
}
|
||||
};
|
||||
|
||||
// Handle the "make visible" event, pass the request to the parent
|
||||
// controller
|
||||
dummyAOI.doMakeVisible = function () {
|
||||
self._makeVisibleCallback.call(self._context, _idx);
|
||||
}
|
||||
|
||||
// Connect the the two AOIs
|
||||
dummyAOI.doTriggerEvent = _entry.aoi.doTiggerEvent;
|
||||
|
||||
// Implementation of the getDOMNode function, so that the event
|
||||
// handlers can be properly bound
|
||||
dummyAOI.getDOMNode = function () { return _tr; };
|
||||
|
||||
return dummyAOI;
|
||||
},
|
||||
|
||||
_attachActionObject: function (_entry, _tr, _uid, _links, _idx) {
|
||||
|
||||
// Get the dummyAOI which connects the action object to the tr but
|
||||
// does no selection handling
|
||||
var dummyAOI = this._getDummyAOI(_entry, _tr, _uid, _idx);
|
||||
|
||||
// Create an action object for the tr and connect it to a dummy AOI
|
||||
_entry.ao = this._actionObjectManager.addObject(_uid, dummyAOI);
|
||||
_entry.ao.updateActionLinks(_links);
|
||||
_entry.ao._index = _idx;
|
||||
|
||||
// Overwrite some functions like "traversePath", "getNext" and
|
||||
// "getPrevious"
|
||||
var self = this;
|
||||
|
||||
function getIndexAO (_idx) {
|
||||
// Check whether the index is in the index map
|
||||
if (typeof self._indexMap[_idx] !== "undefined"
|
||||
&& self._indexMap[_idx].uid)
|
||||
{
|
||||
return self._getRegisteredRowsEntry(self._indexMap[_idx].uid).ao;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function getElementRelatively (_step) {
|
||||
return getIndexAO(Math.max(0,
|
||||
Math.min(self._total - 1, _entry.idx + _step)));
|
||||
};
|
||||
|
||||
_entry.ao.getPrevious = function (_step) {
|
||||
return getElementRelatively(-_step);
|
||||
};
|
||||
|
||||
_entry.ao.getNext = function (_step) {
|
||||
return getElementRelatively(_step);
|
||||
};
|
||||
|
||||
_entry.ao.traversePath = function (_obj) {
|
||||
// Get the start and the stop index
|
||||
var s = Math.min(this._index, _obj._index);
|
||||
var e = Math.max(this._index, _obj._index);
|
||||
|
||||
var result = [];
|
||||
|
||||
for (var i = s; i < e; i++)
|
||||
{
|
||||
var ao = getIndexAO(i);
|
||||
if (ao)
|
||||
{
|
||||
result.push(ao);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
},
|
||||
|
||||
_updateState: function (_uid, _state) {
|
||||
var entry = this._getRegisteredRowsEntry(_uid);
|
||||
|
||||
|
@ -496,6 +496,46 @@ var et2_dataview_grid = et2_dataview_container.extend(et2_dataview_IViewRange, {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Makes the given index visible: TODO: Propagate this to the parent grid.
|
||||
*/
|
||||
makeIndexVisible: function (_idx)
|
||||
{
|
||||
// Get the element range
|
||||
var elemRange = this._getElementRange(_idx);
|
||||
|
||||
// Abort if the index was out of range
|
||||
if (!elemRange)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Calculate the current visible range
|
||||
var visibleRange = et2_bounds(
|
||||
this._viewRange.top + ET2_GRID_VIEW_EXT,
|
||||
this._viewRange.bottom - ET2_GRID_VIEW_EXT);
|
||||
|
||||
// Check whether the element is currently completely visible -- if yes,
|
||||
// do nothing
|
||||
if (visibleRange.top < elemRange.top
|
||||
&& visibleRange.bottom > elemRange.bottom)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (elemRange.top < visibleRange.top)
|
||||
{
|
||||
this.scrollarea.scrollTop(elemRange.top);
|
||||
}
|
||||
else
|
||||
{
|
||||
var h = elemRange.bottom - elemRange.top;
|
||||
this.scrollarea.scrollTop(elemRange.top - this._scrollHeight + h);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
|
||||
/* ---- PRIVATE FUNCTIONS ---- */
|
||||
|
||||
/* _inspectStructuralIntegrity: function() {
|
||||
@ -515,6 +555,38 @@ var et2_dataview_grid = et2_dataview_container.extend(et2_dataview_IViewRange, {
|
||||
}
|
||||
},*/
|
||||
|
||||
/**
|
||||
* Translates the given index to a range, returns false if the index is
|
||||
* out of range.
|
||||
*/
|
||||
_getElementRange: function (_idx)
|
||||
{
|
||||
// Recalculate the element positions
|
||||
this._recalculateElementPosition();
|
||||
|
||||
// Translate the given index to the map index
|
||||
var mapIdx = this._calculateMapIndex(_idx);
|
||||
|
||||
// Do nothing if the given index is out of range
|
||||
if (mapIdx === false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the map element
|
||||
var elem = this._map[mapIdx];
|
||||
|
||||
// Get the element range
|
||||
if (elem instanceof et2_dataview_spacer)
|
||||
{
|
||||
var avg = this.getAverageHeight();
|
||||
return et2_range(elem.getTop() + avg * (elem.getIndex() - _idx),
|
||||
avg);
|
||||
}
|
||||
|
||||
return elem.getRange();
|
||||
},
|
||||
|
||||
/**
|
||||
* Recalculates the position of the currently managed containers. This
|
||||
* routine only updates the pixel position of the elements -- the index of
|
||||
|
@ -550,8 +550,8 @@ var et2_nextmatch = et2_DOMWidget.extend(et2_IResizeable, {
|
||||
"nm",
|
||||
this.dataview.grid,
|
||||
this.rowProvider,
|
||||
null,
|
||||
this.options.settings.action_links,
|
||||
null,
|
||||
this.options.settings.actions
|
||||
);
|
||||
|
||||
|
@ -17,28 +17,33 @@
|
||||
* @param _action action object with attributes caption, id, nm_action, ...
|
||||
* @param _senders array of rows selected
|
||||
*/
|
||||
function nm_action(_action, _senders)
|
||||
function nm_action(_action, _senders, _target, _ids)
|
||||
{
|
||||
// ignore checkboxes, unless they have an explicit defined nm_action
|
||||
if (_action.checkbox && (!_action.data || typeof _action.data.nm_action == 'undefined')) return;
|
||||
|
||||
if (typeof _action.data == 'undefined' || !_action.data) _action.data = {};
|
||||
if (typeof _action.data.nm_action == 'undefined') _action.data.nm_action = 'submit';
|
||||
|
||||
|
||||
// ----------------------
|
||||
// TODO: Parse the _ids.inverted flag!
|
||||
// ----------------------
|
||||
var idsArr = _ids.ids;
|
||||
|
||||
var ids = "";
|
||||
for (var i = 0; i < _senders.length; i++)
|
||||
for (var i = 0; i < idsArr.length; i++)
|
||||
{
|
||||
var app_id = _senders[i].id.split('::', 2);
|
||||
var app_id = idsArr[i].split('::', 2);
|
||||
var id = app_id[1];
|
||||
ids += (id.indexOf(',') >= 0 ? '"'+id.replace(/"/g,'""')+'"' : id) +
|
||||
((i < _senders.length - 1) ? "," : "");
|
||||
((i < idsArr.length - 1) ? "," : "");
|
||||
}
|
||||
//console.log(_action); console.log(_senders);
|
||||
|
||||
var mgr = _action.getManager();
|
||||
|
||||
var select_all = mgr.getActionById("select_all");
|
||||
var confirm_msg = (_senders.length > 1 || select_all && select_all.checked) &&
|
||||
var confirm_msg = (idsArr.length > 1 || select_all && select_all.checked) &&
|
||||
typeof _action.data.confirm_multiple != 'undefined' ?
|
||||
_action.data.confirm_multiple : _action.data.confirm;
|
||||
|
||||
@ -49,7 +54,7 @@ function nm_action(_action, _senders)
|
||||
if (!confirm(confirm_msg)) return;
|
||||
}
|
||||
// in case we only need to confirm multiple selected (only _action.data.confirm_multiple)
|
||||
else if (typeof _action.data.confirm_multiple != 'undefined' && (_senders.length > 1 || select_all && select_all.checked))
|
||||
else if (typeof _action.data.confirm_multiple != 'undefined' && (idsArr.length > 1 || select_all && select_all.checked))
|
||||
{
|
||||
if (!confirm(_action.data.confirm_multiple)) return;
|
||||
}
|
||||
@ -94,7 +99,7 @@ function nm_action(_action, _senders)
|
||||
case 'egw_open':
|
||||
var params = _action.data.egw_open.split('-'); // type-appname-idNum (idNum is part of id split by :), eg. "edit-infolog"
|
||||
console.log(params);
|
||||
var egw_open_id = _senders[0].id;
|
||||
var egw_open_id = idsArr[0].id;
|
||||
if (typeof params[2] != 'undefined') egw_open_id = egw_open_id.split(':')[params[2]];
|
||||
egw_open(egw_open_id,params[1],params[0],params[3]);
|
||||
break;
|
||||
@ -103,7 +108,7 @@ function nm_action(_action, _senders)
|
||||
// open div styled as popup contained in current form and named action.id+'_popup'
|
||||
if (nm_popup_action == null)
|
||||
{
|
||||
nm_open_popup(_action, _senders);
|
||||
nm_open_popup(_action, _ids);
|
||||
break;
|
||||
}
|
||||
// fall through, if popup is open --> submit form
|
||||
@ -202,7 +207,9 @@ function nm_compare_field(_action, _senders, _target)
|
||||
return value == _action.data.fieldValue;
|
||||
}
|
||||
|
||||
var nm_popup_action, nm_popup_senders = null;
|
||||
// TODO: This code is rather suboptimal! No global variables as this code will
|
||||
// run in a global context
|
||||
var nm_popup_action, nm_popup_ids = null;
|
||||
|
||||
/**
|
||||
* Open popup for a certain action requiring further input
|
||||
@ -210,15 +217,15 @@ var nm_popup_action, nm_popup_senders = null;
|
||||
* Popup needs to have eTemplate name of action id plus "_popup"
|
||||
*
|
||||
* @param _action
|
||||
* @param _senders
|
||||
* @param _ids
|
||||
*/
|
||||
function nm_open_popup(_action, _senders)
|
||||
function nm_open_popup(_action, _ids)
|
||||
{
|
||||
var popup = document.getElementById(_action.getManager().etemplate_var_prefix + '[' + _action.id + '_popup]');
|
||||
|
||||
if (popup) {
|
||||
nm_popup_action = _action;
|
||||
nm_popup_senders = _senders;
|
||||
nm_popup_ids = _ids;
|
||||
popup.style.display = 'block';
|
||||
}
|
||||
}
|
||||
@ -231,7 +238,7 @@ function nm_submit_popup(button)
|
||||
button.form.submit_button.value = button.name; // set name of button (sub-action)
|
||||
|
||||
// call regular nm_action to transmit action and senders correct
|
||||
nm_action(nm_popup_action, nm_popup_senders);
|
||||
nm_action(nm_popup_action, null, null, nm_popup_ids);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -44,31 +44,28 @@ var et2_nextmatch_controller = et2_dataview_controller.extend(
|
||||
* is given.
|
||||
*/
|
||||
init: function (_egw, _execId, _widgetId, _grid, _rowProvider,
|
||||
_objectManager, _actionLinks, _actions) {
|
||||
_actionLinks, _objectManager, _actions) {
|
||||
|
||||
// Create the action/object managers
|
||||
if (_objectManager === null)
|
||||
// Copy the egw reference
|
||||
this.egw = _egw;
|
||||
|
||||
// Initialize the action and the object manager
|
||||
if (!_objectManager)
|
||||
{
|
||||
this._actionManager = new egwActionManager();
|
||||
this._actionManager.updateActions(_actions);
|
||||
this._actionManager.setDefaultExecute("javaScript:nm_action");
|
||||
|
||||
this._objectManager = new egwActionObjectManager("",
|
||||
this._actionManager, EGW_AO_FLAG_IS_CONTAINER);
|
||||
this._initActions(_actions)
|
||||
}
|
||||
else
|
||||
{
|
||||
this._actionManager = null;
|
||||
this._objectManager = _objectManager;
|
||||
}
|
||||
this._actionLinks = _actionLinks;
|
||||
|
||||
// Call the parent et2_dataview_controller constructor
|
||||
this._super(_grid, this, this._rowCallback, this._linkCallback, this,
|
||||
this._objectManager);
|
||||
|
||||
// Copy all parameters
|
||||
this.egw = _egw;
|
||||
// Copy the given parameters
|
||||
this._actionLinks = _actionLinks
|
||||
this._execId = _execId;
|
||||
this._widgetId = _widgetId;
|
||||
this._rowProvider = _rowProvider;
|
||||
@ -78,22 +75,19 @@ var et2_nextmatch_controller = et2_dataview_controller.extend(
|
||||
|
||||
// Directly use the API-Implementation of dataRegisterUID and
|
||||
// dataUnregisterUID
|
||||
this.dataRegisterUID = _egw.dataRegisterUID;
|
||||
this.dataUnregisterUID = _egw.dataUnregisterUID;
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
|
||||
// If the actionManager variable is set, the object- and actionManager
|
||||
// were created by this instance -- clear them
|
||||
if (this._actionManager)
|
||||
{
|
||||
this._objectManager.clear();
|
||||
// TODO: No such method. Maybe implement it?
|
||||
//this._actionManager.clear();
|
||||
this._objectManager.remove();
|
||||
this._actionManager.remove();
|
||||
}
|
||||
|
||||
//this._super();
|
||||
this._super();
|
||||
},
|
||||
|
||||
/**
|
||||
@ -108,6 +102,36 @@ var et2_nextmatch_controller = et2_dataview_controller.extend(
|
||||
|
||||
/** -- PRIVATE FUNCTIONS -- **/
|
||||
|
||||
/**
|
||||
* Initializes the action and the object manager.
|
||||
*/
|
||||
_initActions: function (_actions) {
|
||||
// Generate a uid for the action and object manager
|
||||
var uid = this.egw.uid();
|
||||
|
||||
// Initialize the action manager and add some actions to it
|
||||
var gam = egw_getActionManager(this.egw.appName);
|
||||
this._actionManager = gam.addAction("actionManager", uid);
|
||||
this._actionManager.updateActions(_actions);
|
||||
|
||||
// Set the default execute handler
|
||||
var self = this;
|
||||
this._actionManager.setDefaultExecute(function (_action, _senders, _target) {
|
||||
// Get the selected ids descriptor object
|
||||
var ids = self._selectionMgr.getSelected();
|
||||
|
||||
// Call the nm_action function with the ids
|
||||
nm_action(_action, _senders, _target, ids);
|
||||
});
|
||||
|
||||
// Initialize the object manager
|
||||
var gom = egw_getObjectManager(this.egw.appName);
|
||||
this._objectManager = gom.addObject(
|
||||
new egwActionObjectManager(uid, this._actionManager));
|
||||
this._objectManager.flags = this._objectManager.flags
|
||||
| EGW_AO_FLAG_DEFAULT_FOCUS | EGW_AO_FLAG_IS_CONTAINER;
|
||||
},
|
||||
|
||||
/**
|
||||
* Overwrites the inherited _destroyCallback function in order to be able
|
||||
* to free the "rowWidget".
|
||||
@ -166,8 +190,9 @@ var et2_nextmatch_controller = et2_dataview_controller.extend(
|
||||
_context);
|
||||
},
|
||||
|
||||
dataRegisterUID: function () {
|
||||
// Overwritten in the constructor
|
||||
dataRegisterUID: function (_uid, _callback, _context) {
|
||||
this.egw.dataRegisterUID(_uid, _callback, _context, this._execId,
|
||||
this._widgetId);
|
||||
},
|
||||
|
||||
dataUnregisterUID: function () {
|
||||
|
@ -161,6 +161,24 @@ function egwAction(_parent, _id, _caption, _iconUrl, _onExecute, _allowOnMultipl
|
||||
this.onExecute = new egwFnct(this, null, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the element and removes it from the parent container
|
||||
*/
|
||||
egwAction.prototype.remove = function () {
|
||||
// Remove all references to the child elements
|
||||
this.children = [];
|
||||
|
||||
// Remove this element from the parent list
|
||||
if (this.parent)
|
||||
{
|
||||
var idx = this.parent.children.indexOf(this);
|
||||
if (idx >= 0)
|
||||
{
|
||||
this.parent.children.splice(idx, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for a specific action with the given id
|
||||
*/
|
||||
|
@ -143,8 +143,18 @@ egw.extend("data", egw.MODULE_APP_LOCAL, function (_app, _wnd) {
|
||||
* called.
|
||||
*/
|
||||
dataFetch: function (_execId, _queriedRange, _filters, _widgetId,
|
||||
_callback, _context)
|
||||
_callback, _context, _knownUids)
|
||||
{
|
||||
var lm = lastModification;
|
||||
if (_queriedRange["no_data"])
|
||||
{
|
||||
lm = 0xFFFFFFFFFFFF;
|
||||
}
|
||||
else if (_queriedRange["only_data"])
|
||||
{
|
||||
lm = 0;
|
||||
}
|
||||
|
||||
var request = egw.json(
|
||||
"etemplate_widget_nextmatch::ajax_get_rows::etemplate",
|
||||
[
|
||||
@ -152,8 +162,8 @@ egw.extend("data", egw.MODULE_APP_LOCAL, function (_app, _wnd) {
|
||||
_queriedRange,
|
||||
_filters,
|
||||
_widgetId,
|
||||
egw.dataKnownUIDs(_app),
|
||||
_queriedRange["no_data"] ? 0xFFFFFFFFFFFF : lastModification
|
||||
_knownUids ? _knownUids : egw.dataKnownUIDs(_app),
|
||||
lm
|
||||
],
|
||||
function(result) {
|
||||
parseServerResponse(result, _callback, _context);
|
||||
@ -186,6 +196,21 @@ egw.extend("data_storage", egw.MODULE_GLOBAL, function (_app, _wnd) {
|
||||
*/
|
||||
var registeredCallbacks = {};
|
||||
|
||||
/**
|
||||
* Uids and timers used for querying data uids, hashed by the first few
|
||||
* bytes of the _execId, stored as an object of the form
|
||||
* {
|
||||
* "timer": <QUEUE TIMER>,
|
||||
* "uids": <ARRAY OF UIDS>
|
||||
* }
|
||||
*/
|
||||
var queue = {};
|
||||
|
||||
/**
|
||||
* Contains the queue timeout in milliseconds.
|
||||
*/
|
||||
var QUEUE_TIMEOUT = 10;
|
||||
|
||||
/**
|
||||
* This constant specifies the maximum age of entries in the local storrage
|
||||
* in milliseconds
|
||||
@ -230,9 +255,14 @@ egw.extend("data_storage", egw.MODULE_GLOBAL, function (_app, _wnd) {
|
||||
*
|
||||
* @param _uid is the uid for which the callback should be registered.
|
||||
* @param _callback is the callback which should get called.
|
||||
* @param _context is an optional parameter which can
|
||||
* @param _context is the optional context in which the callback will be
|
||||
* executed
|
||||
* @param _execId is the exec id which will be used in case the data is
|
||||
* not available
|
||||
* @param _widgetId is the widget id which will be used in case the uid
|
||||
* has to be fetched.
|
||||
*/
|
||||
dataRegisterUID: function (_uid, _callback, _context) {
|
||||
dataRegisterUID: function (_uid, _callback, _context, _execId, _widgetId) {
|
||||
// Create the slot for the uid if it does not exist now
|
||||
if (typeof registeredCallbacks[_uid] === "undefined")
|
||||
{
|
||||
@ -253,6 +283,33 @@ egw.extend("data_storage", egw.MODULE_GLOBAL, function (_app, _wnd) {
|
||||
localStorage[_uid].timestamp = (new Date).getTime();
|
||||
_callback.call(_context, localStorage[_uid].data);
|
||||
}
|
||||
else if (_execId && _widgetId)
|
||||
{
|
||||
// Get the first 50 bytes of the exex id
|
||||
var hash = _execId.substring(0, 50);
|
||||
|
||||
// Create a new queue if it does not exist yet
|
||||
if (typeof queue[hash] === "undefined")
|
||||
{
|
||||
var self = this;
|
||||
queue[hash] = { "uids": [], "timer": null };
|
||||
queue[hash].timer = window.setTimeout(function () {
|
||||
// Fetch the data
|
||||
self.dataFetch(_execId, {"start": 0, "num_rows": 0, "only_data": true},
|
||||
[], _widgetId, null, null, queue[hash].uids);
|
||||
|
||||
// Delete the queue entry
|
||||
delete queue[hash];
|
||||
}, 10);
|
||||
}
|
||||
|
||||
// Push the uid onto the queue
|
||||
queue[hash].uids.push(_uid.split("::").pop());
|
||||
}
|
||||
else
|
||||
{
|
||||
this.debug("log", "Data for uid " + _uid + " not available.");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user