Implemented keyboard navigation and data retrival for uids

This commit is contained in:
Andreas Stöckel
2012-03-29 14:11:22 +00:00
parent e20f2e9333
commit cfa9c190bb
8 changed files with 394 additions and 94 deletions

View File

@ -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);