mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-27 09:09:04 +01:00
Dynamic loading of content tested and optimized, resolved bugs, implemented support for data trees in the view classes. The whole progess can be seen in the test/test_grid_view.html file.
This commit is contained in:
parent
d7356a350f
commit
57aaf6d756
@ -395,8 +395,6 @@ function egwActionObject(_id, _parent, _iface, _manager, _flags)
|
|||||||
this.focusedChild = null;
|
this.focusedChild = null;
|
||||||
|
|
||||||
this.setAOI(_iface);
|
this.setAOI(_iface);
|
||||||
this.iface.setStateChangeCallback(this._ifaceCallback, this);
|
|
||||||
this.iface.setReconnectActionsCallback(this._reconnectCallback, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -418,6 +416,8 @@ egwActionObject.prototype.setAOI = function(_aoi)
|
|||||||
|
|
||||||
// Replace the interface object
|
// Replace the interface object
|
||||||
this.iface = _aoi;
|
this.iface = _aoi;
|
||||||
|
this.iface.setStateChangeCallback(this._ifaceCallback, this);
|
||||||
|
this.iface.setReconnectActionsCallback(this._reconnectCallback, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -764,7 +764,7 @@ egwActionObject.prototype._ifaceCallback = function(_newState, _changedBit, _shi
|
|||||||
// and set their select state.
|
// and set their select state.
|
||||||
if (egwBitIsSet(_shiftState, EGW_AO_SHIFT_STATE_BLOCK))
|
if (egwBitIsSet(_shiftState, EGW_AO_SHIFT_STATE_BLOCK))
|
||||||
{
|
{
|
||||||
var focused = this.getRootObject().getFocusedObject();
|
var focused = this.getFocusedObject();
|
||||||
if (focused)
|
if (focused)
|
||||||
{
|
{
|
||||||
objs = this.traversePath(focused);
|
objs = this.traversePath(focused);
|
||||||
@ -915,7 +915,7 @@ egwActionObject.prototype.setAllSelected = function(_selected, _informParent)
|
|||||||
*/
|
*/
|
||||||
egwActionObject.prototype.updateSelectedChildren = function(_child, _selected)
|
egwActionObject.prototype.updateSelectedChildren = function(_child, _selected)
|
||||||
{
|
{
|
||||||
var id = this.selectedChildren.indexOf(_child);
|
var id = this.selectedChildren.indexOf(_child); // TODO Replace by binary search, insert children sorted by index!
|
||||||
var wasEmpty = this.selectedChildren.length == 0;
|
var wasEmpty = this.selectedChildren.length == 0;
|
||||||
|
|
||||||
// Add or remove the given child from the selectedChildren list
|
// Add or remove the given child from the selectedChildren list
|
||||||
|
@ -91,6 +91,7 @@ function egwGetShiftState(e)
|
|||||||
var state = EGW_AO_SHIFT_STATE_NONE;
|
var state = EGW_AO_SHIFT_STATE_NONE;
|
||||||
state = egwSetBit(state, EGW_AO_SHIFT_STATE_MULTI, e.ctrkKey || e.metaKey);
|
state = egwSetBit(state, EGW_AO_SHIFT_STATE_MULTI, e.ctrkKey || e.metaKey);
|
||||||
state = egwSetBit(state, EGW_AO_SHIFT_STATE_BLOCK, e.shiftKey);
|
state = egwSetBit(state, EGW_AO_SHIFT_STATE_BLOCK, e.shiftKey);
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@ function egwGridDataElement(_id, _parent, _columns, _readQueue, _objectManager)
|
|||||||
this.canHaveChildren = false;
|
this.canHaveChildren = false;
|
||||||
this.type = egwGridViewRow;
|
this.type = egwGridViewRow;
|
||||||
this.userData = null;
|
this.userData = null;
|
||||||
|
this.updatedGrid = null;
|
||||||
|
|
||||||
this.gridViewObj = null;
|
this.gridViewObj = null;
|
||||||
}
|
}
|
||||||
@ -132,7 +133,8 @@ egwGridDataElement.prototype.set_data = function(_value)
|
|||||||
|
|
||||||
this.data[col_id] = {
|
this.data[col_id] = {
|
||||||
"data": data,
|
"data": data,
|
||||||
"sortData": sortData
|
"sortData": sortData,
|
||||||
|
"queued": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -168,8 +170,13 @@ egwGridDataElement.prototype.set_data = function(_value)
|
|||||||
* "canHaveChildren": [true|false] // Specifies whether the row "open/close" button is displayed
|
* "canHaveChildren": [true|false] // Specifies whether the row "open/close" button is displayed
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
egwGridDataElement.prototype.loadData = function(_data)
|
egwGridDataElement.prototype.loadData = function(_data, _doCallUpdate)
|
||||||
{
|
{
|
||||||
|
if (typeof _doCallUpdate == "undefined")
|
||||||
|
{
|
||||||
|
_doCallUpdate = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (_data.constructor == Array)
|
if (_data.constructor == Array)
|
||||||
{
|
{
|
||||||
var virgin = this.children.length == 0;
|
var virgin = this.children.length == 0;
|
||||||
@ -197,6 +204,7 @@ egwGridDataElement.prototype.loadData = function(_data)
|
|||||||
{
|
{
|
||||||
var count = typeof entry.count == "number" && entry.count >= 0 ? entry.count : 1;
|
var count = typeof entry.count == "number" && entry.count >= 0 ? entry.count : 1;
|
||||||
var prefix = typeof entry.prefix == "string" ? entry.prefix : "elem_";
|
var prefix = typeof entry.prefix == "string" ? entry.prefix : "elem_";
|
||||||
|
var canHaveChildren = typeof entry.canHaveChildren == "boolean" ? entry.canHaveChildren : false;
|
||||||
var index = last_element ? last_element.index + 1 : 0;
|
var index = last_element ? last_element.index + 1 : 0;
|
||||||
|
|
||||||
for (var j = 0; j < count; j++)
|
for (var j = 0; j < count; j++)
|
||||||
@ -204,6 +212,7 @@ egwGridDataElement.prototype.loadData = function(_data)
|
|||||||
var id = prefix + (index + j);
|
var id = prefix + (index + j);
|
||||||
element = this.insertElement(index + j, id);
|
element = this.insertElement(index + j, id);
|
||||||
element.type = type; // Type can only be set directly after creation
|
element.type = type; // Type can only be set directly after creation
|
||||||
|
element.canHaveChildren = canHaveChildren;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (entryType == EGW_DATA_TYPE_ELEMENT)
|
else if (entryType == EGW_DATA_TYPE_ELEMENT)
|
||||||
@ -240,7 +249,12 @@ egwGridDataElement.prototype.loadData = function(_data)
|
|||||||
this.loadData(_data.children);
|
this.loadData(_data.children);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.gridViewObj.callGridViewObjectUpdate();
|
if (_doCallUpdate)
|
||||||
|
{
|
||||||
|
this.callBeginUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.callGridViewObjectUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,7 +342,7 @@ egwGridDataElement.prototype.getElementById = function(_id, _depth)
|
|||||||
{
|
{
|
||||||
for (var i = 0; i < this.children.length; i++)
|
for (var i = 0; i < this.children.length; i++)
|
||||||
{
|
{
|
||||||
var elem = this.children.getElementById(_id, _depth - 1);
|
var elem = this.children[i].getElementById(_id, _depth - 1);
|
||||||
|
|
||||||
if (elem)
|
if (elem)
|
||||||
{
|
{
|
||||||
@ -348,13 +362,13 @@ egwGridDataElement.prototype.getChildren = function(_callback, _context)
|
|||||||
{
|
{
|
||||||
if (this.children.length > 0)
|
if (this.children.length > 0)
|
||||||
{
|
{
|
||||||
_callback.call(_context, this.children);
|
_callback.call(_context, this.children, true);
|
||||||
}
|
}
|
||||||
else if (this.canHaveChildren)
|
else if (this.canHaveChildren)
|
||||||
{
|
{
|
||||||
// If the children havn't been loaded yet, request them via queue call.
|
// If the children havn't been loaded yet, request them via queue call.
|
||||||
this.readQueue.queue(this, EGW_DATA_QUEUE_CHILDREN, function() {
|
this.readQueue.queueCall(this, EGW_DATA_QUEUE_CHILDREN, function() {
|
||||||
_callback.call(_context, this.children);
|
_callback.call(_context, this.children, false);
|
||||||
}, this);
|
}, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -386,16 +400,21 @@ egwGridDataElement.prototype.hasColumn = function(_columnId, _returnData)
|
|||||||
res = true;
|
res = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_returnData && typeof (this.data[_columnId]) != "undefined" && this.data[_columnId].queued)
|
||||||
|
{
|
||||||
|
res = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Check whether the column data of this column has been read,
|
// Check whether the column data of this column has been read,
|
||||||
// if yes, return it.
|
// if yes, return it.
|
||||||
if (typeof this.data[_columnIds] != "undefined")
|
if (typeof this.data[_columnId] != "undefined")
|
||||||
{
|
{
|
||||||
if (_returnData)
|
if (_returnData && typeof this.data[_columnId].data != "undefined")
|
||||||
{
|
{
|
||||||
res = this.data[_columnIds].data;
|
res = this.data[_columnId].data;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -456,7 +475,7 @@ egwGridDataElement.prototype.getData = function(_columnIds)
|
|||||||
// in the readQueue
|
// in the readQueue
|
||||||
if (queryList.length > 0)
|
if (queryList.length > 0)
|
||||||
{
|
{
|
||||||
this.readQueue.queue(this, queryList);
|
this.readQueue.queueCall(this, queryList);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -467,11 +486,16 @@ egwGridDataElement.prototype.getData = function(_columnIds)
|
|||||||
* Calls the row object update function - checks whether the row object implements
|
* Calls the row object update function - checks whether the row object implements
|
||||||
* this interface and whether it is set.
|
* this interface and whether it is set.
|
||||||
*/
|
*/
|
||||||
egwGridDataElement.prototype.callGridViewObjectUpdate = function()
|
egwGridDataElement.prototype.callGridViewObjectUpdate = function(_immediate)
|
||||||
{
|
{
|
||||||
|
if (typeof _immediate == "undefined")
|
||||||
|
{
|
||||||
|
_immediate = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.gridViewObj && typeof this.gridViewObj.doUpdateData == "function")
|
if (this.gridViewObj && typeof this.gridViewObj.doUpdateData == "function")
|
||||||
{
|
{
|
||||||
this.gridViewObj.doUpdateData();
|
this.gridViewObj.doUpdateData(_immediate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -516,7 +540,63 @@ egwGridDataElement.prototype.setGridViewObj = function(_obj)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the root element
|
||||||
|
*/
|
||||||
|
egwGridDataElement.prototype.getRootElement = function()
|
||||||
|
{
|
||||||
|
if (!this.parent)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return this.parent.getRootElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the depth of this element in the document tree
|
||||||
|
*/
|
||||||
|
egwGridDataElement.prototype.getDepth = function()
|
||||||
|
{
|
||||||
|
return (this.parent) ? (this.parent.getDepth() + 1) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls the beginUpdate function of the grid associated to the grid view object
|
||||||
|
*/
|
||||||
|
egwGridDataElement.prototype.callBeginUpdate = function()
|
||||||
|
{
|
||||||
|
if (this.gridViewObj)
|
||||||
|
{
|
||||||
|
var root = this.getRootElement();
|
||||||
|
|
||||||
|
if (root.updatedGrid != this.gridViewObj.grid)
|
||||||
|
{
|
||||||
|
if (root.updatedGrid)
|
||||||
|
{
|
||||||
|
root.updatedGrid.endUpdate();
|
||||||
|
}
|
||||||
|
root.updatedGrid = this.gridViewObj.grid;
|
||||||
|
root.updatedGrid.beginUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls the end update function of the currently active updated grid
|
||||||
|
*/
|
||||||
|
egwGridDataElement.prototype.callEndUpdate = function()
|
||||||
|
{
|
||||||
|
var root = this.getRootElement();
|
||||||
|
|
||||||
|
if (root.updatedGrid)
|
||||||
|
{
|
||||||
|
root.updatedGrid.endUpdate();
|
||||||
|
root.updatedGrid = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** - egwGridDataReadQueue -- **/
|
/** - egwGridDataReadQueue -- **/
|
||||||
@ -558,27 +638,56 @@ egwGridDataQueue.prototype.setDataRoot = function(_dataRoot)
|
|||||||
*/
|
*/
|
||||||
egwGridDataQueue.prototype._queue = function(_obj)
|
egwGridDataQueue.prototype._queue = function(_obj)
|
||||||
{
|
{
|
||||||
|
this.timeoutId++;
|
||||||
|
|
||||||
|
// Push the queue object onto the queue
|
||||||
this.queue.push(_obj);
|
this.queue.push(_obj);
|
||||||
|
|
||||||
if (this.queue.length > EGW_DATA_QUEUE_MAX_ELEM_COUNT)
|
if (this.queue.length > EGW_DATA_QUEUE_MAX_ELEM_COUNT)
|
||||||
{
|
{
|
||||||
this.flushQueue();
|
this.flushQueue(false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Specify that the element data is queued
|
||||||
|
for (var i = 0; i < this.queueColumns.length; i++)
|
||||||
|
{
|
||||||
|
if (typeof _obj.elem.data[this.queueColumns[i]] == "undefined")
|
||||||
|
{
|
||||||
|
_obj.elem.data[this.queueColumns[i]] = {
|
||||||
|
"queued": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the flush queue timeout
|
||||||
|
var tid = this.timeoutId;
|
||||||
|
var self = this;
|
||||||
|
window.setTimeout(function() {
|
||||||
|
if (self.timeoutId == tid)
|
||||||
|
{
|
||||||
|
self.flushQueue(true);
|
||||||
|
}
|
||||||
|
}, EGW_DATA_QUEUE_FLUSH_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
egwGridDataQueue.prototype.inQueue = function(_elem)
|
egwGridDataQueue.prototype._accumulateQueueColumns = function(_columns)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < this.queue.length; i++)
|
if (this.dataRoot.columns.columns.length > this.queueColumns.length)
|
||||||
{
|
{
|
||||||
if (this.queue[i].elem == _elem)
|
// Merge the specified columns into the queueColumns variable
|
||||||
|
for (var i = 0; i < _columns.length; i++)
|
||||||
{
|
{
|
||||||
return true;
|
if (this.queueColumns.indexOf(_columns[i]) == -1)
|
||||||
|
{
|
||||||
|
this.queueColumns.push(_columns[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -594,7 +703,7 @@ egwGridDataQueue.prototype.inQueue = function(_elem)
|
|||||||
* @param object _context is the context in which the callback function will
|
* @param object _context is the context in which the callback function will
|
||||||
* be executed.
|
* be executed.
|
||||||
*/
|
*/
|
||||||
egwGridDataQueue.prototype.queue = function(_elem, _columns, _callback, _context)
|
egwGridDataQueue.prototype.queueCall = function(_elem, _columns, _callback, _context)
|
||||||
{
|
{
|
||||||
if (typeof _callback == "undefined")
|
if (typeof _callback == "undefined")
|
||||||
{
|
{
|
||||||
@ -610,7 +719,7 @@ egwGridDataQueue.prototype.queue = function(_elem, _columns, _callback, _context
|
|||||||
if (!this._queue({
|
if (!this._queue({
|
||||||
"elem": _elem,
|
"elem": _elem,
|
||||||
"type": EGW_DATA_QUEUE_CHILDREN,
|
"type": EGW_DATA_QUEUE_CHILDREN,
|
||||||
"proc": _callback,
|
"callback": _callback,
|
||||||
"context": _context
|
"context": _context
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
@ -619,73 +728,125 @@ egwGridDataQueue.prototype.queue = function(_elem, _columns, _callback, _context
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Merge the specified columns into the queueColumns variable
|
// Accumulate the queue columns ids
|
||||||
for (var i = 0; i < _columns.length; i++)
|
this._accumulateQueueColumns(_columns);
|
||||||
{
|
|
||||||
if (this.queueColumns.indexOf(_columns[i]) == -1)
|
|
||||||
{
|
|
||||||
this.queueColumns.push(_columns[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Queue the element and search in the elements around the given one for
|
// Queue the element and search in the elements around the given one for
|
||||||
// elements whose data isn't loaded yet.
|
// elements whose data isn't loaded yet.
|
||||||
var done = !this._queue({
|
this._queue({
|
||||||
"elem": _elem,
|
"elem": _elem,
|
||||||
"type": EGW_DATA_QUEUE_ELEM,
|
"type": EGW_DATA_QUEUE_ELEM,
|
||||||
"proc": _callback,
|
"callback": _callback,
|
||||||
"context": _context
|
"context": _context
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Prefetch other elements around the given element
|
egwGridDataQueue.prototype._getQueuePlanes = function()
|
||||||
var parent = _elem.parent;
|
|
||||||
if (parent)
|
|
||||||
{
|
{
|
||||||
// Initialize the start prefetch index and the max prefetch count
|
var planes = [];
|
||||||
var prefetch = EGW_DATA_QUEUE_PREFETCH_COUNT;
|
var curPlane = null;
|
||||||
var idx = Math.floor(Math.max(0, _elem.index - prefetch / 2));
|
|
||||||
|
|
||||||
while (!done && prefetch > 0 && idx < parent.children.length)
|
for (var i = 0; i < this.queue.length; i++)
|
||||||
{
|
{
|
||||||
|
var elem = this.queue[i].elem;
|
||||||
|
|
||||||
// Don't prefetch the element itself
|
if (!curPlane || elem.parent != curPlane.parent)
|
||||||
if (idx != _elem.idx)
|
|
||||||
{
|
{
|
||||||
// Fetch the element with the current index from the children
|
curPlane = null;
|
||||||
// of the parent of the element.
|
for (var j = 0; j < planes.length; j++)
|
||||||
var elem = parent.children[idx];
|
|
||||||
|
|
||||||
// Check whether this element has all data columns loaded and is
|
|
||||||
// not already in the queue
|
|
||||||
if (!this.inQueue(elem))
|
|
||||||
{
|
{
|
||||||
var hasColumns = true;
|
if (planes[j].parent == elem.parent)
|
||||||
for (var j = 0; j < this.queueColumns.length; j++)
|
|
||||||
{
|
{
|
||||||
var res = elem.hasColumn(this.queueColumns[i], false);
|
curPlane = planes[j];
|
||||||
if (!res)
|
|
||||||
{
|
|
||||||
hasColumns = false;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasColumns)
|
if (!curPlane)
|
||||||
{
|
{
|
||||||
done = !this._queue({
|
curPlane = {
|
||||||
"elem": elem,
|
"parent": elem.parent,
|
||||||
"type": EGW_DATA_QUEUE_ELEM,
|
"cnt": 0,
|
||||||
"proc": null,
|
"min": 0,
|
||||||
"context": null
|
"max": 0,
|
||||||
});
|
"idx": 0,
|
||||||
prefetch--;
|
"done": false
|
||||||
}
|
};
|
||||||
|
planes.push(curPlane);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
idx++;
|
if (curPlane.cnt == 0 || elem.index < curPlane.min)
|
||||||
|
{
|
||||||
|
curPlane.min = elem.index;
|
||||||
|
}
|
||||||
|
if (curPlane.cnt == 0 || elem.index > curPlane.max)
|
||||||
|
{
|
||||||
|
curPlane.max = elem.index;
|
||||||
|
}
|
||||||
|
|
||||||
|
curPlane.cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return planes;
|
||||||
|
}
|
||||||
|
|
||||||
|
egwGridDataQueue.prototype.prefetch = function(_cnt)
|
||||||
|
{
|
||||||
|
var cnt = _cnt;
|
||||||
|
var planes = this._getQueuePlanes();
|
||||||
|
|
||||||
|
// Set the start indices
|
||||||
|
for (var i = 0; i < planes.length; i++)
|
||||||
|
{
|
||||||
|
planes[i].idx = Math.max(0, Math.ceil(planes[i].min - _cnt / (2 * planes.length)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add as many elements as specified to the prefetched elements
|
||||||
|
var done = 0;
|
||||||
|
var plane = 0;
|
||||||
|
while (cnt > 0 && done < planes.length)
|
||||||
|
{
|
||||||
|
if (!planes[plane].done)
|
||||||
|
{
|
||||||
|
var idx = planes[plane].idx;
|
||||||
|
|
||||||
|
if (idx == planes[plane].parent.children.length)
|
||||||
|
{
|
||||||
|
planes[plane].done = true;
|
||||||
|
done++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var hasData = true;
|
||||||
|
var elem = planes[plane].parent.children[idx];
|
||||||
|
for (var j = 0; j < this.queueColumns.length; j++)
|
||||||
|
{
|
||||||
|
if (!elem.hasColumn(this.queueColumns[i], false))
|
||||||
|
{
|
||||||
|
hasData = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!hasData)
|
||||||
|
{
|
||||||
|
this._queue({
|
||||||
|
"elem": elem,
|
||||||
|
"type": EGW_DATA_QUEUE_ELEM,
|
||||||
|
"callback": null,
|
||||||
|
"context": null
|
||||||
|
});
|
||||||
|
cnt--;
|
||||||
|
}
|
||||||
|
|
||||||
|
planes[plane].idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go to the next plane
|
||||||
|
plane = (plane + 1) % planes.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -693,14 +854,32 @@ egwGridDataQueue.prototype.queue = function(_elem, _columns, _callback, _context
|
|||||||
* Empties the queue and calls the fetch callback which cares about retrieving
|
* Empties the queue and calls the fetch callback which cares about retrieving
|
||||||
* the data from the server.
|
* the data from the server.
|
||||||
*/
|
*/
|
||||||
egwGridDataQueue.prototype.flushQueue = function()
|
egwGridDataQueue.prototype.flushQueue = function(_doPrefetch)
|
||||||
{
|
{
|
||||||
var ids = [];
|
var ids = [];
|
||||||
|
|
||||||
|
if (_doPrefetch)
|
||||||
|
{
|
||||||
|
// Get the count of elements which will be dynamically added to the list, "prefetched"
|
||||||
|
var prefetch_cnt = Math.min(EGW_DATA_QUEUE_PREFETCH_COUNT,
|
||||||
|
Math.max(0, EGW_DATA_QUEUE_MAX_ELEM_COUNT - this.queue.length));
|
||||||
|
|
||||||
|
this.prefetch(prefetch_cnt);
|
||||||
|
}
|
||||||
|
|
||||||
// Generate a list of element ids
|
// Generate a list of element ids
|
||||||
for (var i = 0; i < this.queue.length; i++)
|
for (var i = 0; i < this.queue.length; i++)
|
||||||
{
|
{
|
||||||
ids.push(this.queue[i].elem.id);
|
var id = this.queue[i].elem.id;
|
||||||
|
if (id == this.queue[i].elem.id)
|
||||||
|
{
|
||||||
|
if (this.queue[i].type == EGW_DATA_QUEUE_CHILDREN)
|
||||||
|
{
|
||||||
|
id = "[CHILDREN]" + id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ids.push(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call the fetch callback and save a snapshot of the current queue
|
// Call the fetch callback and save a snapshot of the current queue
|
||||||
@ -711,16 +890,19 @@ egwGridDataQueue.prototype.flushQueue = function()
|
|||||||
|
|
||||||
this.queue = [];
|
this.queue = [];
|
||||||
this.queueColumns = [];
|
this.queueColumns = [];
|
||||||
|
this.timeoutId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
egwGridDataQueue.prototype.dataCallback = function(_data, _queue)
|
egwGridDataQueue.prototype.dataCallback = function(_data, _queue)
|
||||||
{
|
{
|
||||||
var rootData = [];
|
var rootData = [];
|
||||||
|
try
|
||||||
|
{
|
||||||
// Iterate over the given data and check whether the data coresponds to one
|
// Iterate over the given data and check whether the data coresponds to one
|
||||||
// of the queue elements - if yes, call their (probably) specified callback.
|
// of the queue elements - if yes, call their (probably) specified callback.
|
||||||
// All elements for which no queue element can be found are added to the
|
// All elements for which no queue element can be found are added to the
|
||||||
// "rootData" list, which is then loaded by the "dataRoot" data object.
|
// "rootData" list, which is then loaded by the "dataRoot" data object.
|
||||||
|
var i = 0;
|
||||||
for (var i = 0; i < _data.length; i++)
|
for (var i = 0; i < _data.length; i++)
|
||||||
{
|
{
|
||||||
var hasTarget = false;
|
var hasTarget = false;
|
||||||
@ -734,8 +916,7 @@ egwGridDataQueue.prototype.dataCallback = function(_data, _queue)
|
|||||||
{
|
{
|
||||||
if (_queue[j].elem.id == id)
|
if (_queue[j].elem.id == id)
|
||||||
{
|
{
|
||||||
// The element has been found, update its data
|
_queue[j].elem.loadData(_data[i], true);
|
||||||
_queue[j].elem.loadData(_data[i]);
|
|
||||||
|
|
||||||
// Call the queue object callback (if specified)
|
// Call the queue object callback (if specified)
|
||||||
if (_queue[j].callback)
|
if (_queue[j].callback)
|
||||||
@ -744,7 +925,7 @@ egwGridDataQueue.prototype.dataCallback = function(_data, _queue)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Delete this queue element
|
// Delete this queue element
|
||||||
_queue.splice(i, 1);
|
_queue.splice(j, 1);
|
||||||
|
|
||||||
hasTarget = true;
|
hasTarget = true;
|
||||||
break;
|
break;
|
||||||
@ -754,10 +935,15 @@ egwGridDataQueue.prototype.dataCallback = function(_data, _queue)
|
|||||||
|
|
||||||
if (!hasTarget)
|
if (!hasTarget)
|
||||||
{
|
{
|
||||||
rootData.push(_queue[i]);
|
rootData.push(_data[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.dataRoot.loadData(rootData);
|
this.dataRoot.loadData(rootData, true);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
this.dataRoot.callEndUpdate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ function egwGridViewOuter(_parentNode, _dataRoot)
|
|||||||
this.scrollbarWidth = Math.max(10, this.getScrollbarWidth());
|
this.scrollbarWidth = Math.max(10, this.getScrollbarWidth());
|
||||||
|
|
||||||
// Start value for the average row height
|
// Start value for the average row height
|
||||||
this.avgRowHeight = 23.0;
|
this.avgRowHeight = 19.0;
|
||||||
this.avgRowCnt = 1;
|
this.avgRowCnt = 1;
|
||||||
|
|
||||||
// Insert the base grid container into the DOM-Tree
|
// Insert the base grid container into the DOM-Tree
|
||||||
@ -121,6 +121,19 @@ egwGridViewOuter.prototype.addHeightToAvg = function(_value)
|
|||||||
this.avgRowHeight = this.avgRowHeight * (1 - frac) + _value * frac;
|
this.avgRowHeight = this.avgRowHeight * (1 - frac) + _value * frac;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the height from the average container height
|
||||||
|
*/
|
||||||
|
egwGridViewOuter.prototype.remHeightFromAvg = function(_value)
|
||||||
|
{
|
||||||
|
if (this.avgRowCnt > 1)
|
||||||
|
{
|
||||||
|
var sum = this.avgRowHeight * this.avgRowCnt - _value;
|
||||||
|
this.avgRowCnt--;
|
||||||
|
this.avgRowCount = sum / this.avgRowCnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes all containers from the base grid and replaces it with spacers again.
|
* Removes all containers from the base grid and replaces it with spacers again.
|
||||||
* As only partial data is displayed, this method is faster than updating every
|
* As only partial data is displayed, this method is faster than updating every
|
||||||
@ -287,6 +300,8 @@ function egwGridViewContainer(_grid, _heightChangeProc)
|
|||||||
this.assumedHeight = false;
|
this.assumedHeight = false;
|
||||||
this.index = 0;
|
this.index = 0;
|
||||||
this.viewArea = false;
|
this.viewArea = false;
|
||||||
|
this.containerClass = "";
|
||||||
|
this.heightInAvg = false;
|
||||||
|
|
||||||
this.doInsertIntoDOM = null;
|
this.doInsertIntoDOM = null;
|
||||||
this.doSetViewArea = null;
|
this.doSetViewArea = null;
|
||||||
@ -323,7 +338,10 @@ egwGridViewContainer.prototype.setVisible = function(_visible, _force)
|
|||||||
|
|
||||||
// While the element has been invisible, the viewarea might have changed,
|
// While the element has been invisible, the viewarea might have changed,
|
||||||
// so check it now
|
// so check it now
|
||||||
|
if (this.visible)
|
||||||
|
{
|
||||||
this.checkViewArea();
|
this.checkViewArea();
|
||||||
|
}
|
||||||
|
|
||||||
// As the element is now (in)visible, its height has changed. Inform the
|
// As the element is now (in)visible, its height has changed. Inform the
|
||||||
// parent about it.
|
// parent about it.
|
||||||
@ -514,8 +532,10 @@ function egwGridViewGrid(_grid, _heightChangeProc, _scrollable, _outer)
|
|||||||
container.scrollable = _scrollable;
|
container.scrollable = _scrollable;
|
||||||
container.scrollHeight = 100;
|
container.scrollHeight = 100;
|
||||||
container.scrollEvents = 0;
|
container.scrollEvents = 0;
|
||||||
|
container.inUpdate = 0;
|
||||||
container.didUpdate = false;
|
container.didUpdate = false;
|
||||||
container.updateIndex = 0;
|
container.updateIndex = 0;
|
||||||
|
container.triggerID = 0;
|
||||||
container.setupContainer = egwGridViewGrid_setupContainer;
|
container.setupContainer = egwGridViewGrid_setupContainer;
|
||||||
container.insertContainer = egwGridViewGrid_insertContainer;
|
container.insertContainer = egwGridViewGrid_insertContainer;
|
||||||
container.removeContainer = egwGridViewGrid_removeContainer;
|
container.removeContainer = egwGridViewGrid_removeContainer;
|
||||||
@ -526,8 +546,12 @@ function egwGridViewGrid(_grid, _heightChangeProc, _scrollable, _outer)
|
|||||||
container.empty = egwGridViewGrid_empty;
|
container.empty = egwGridViewGrid_empty;
|
||||||
container.getOuter = egwGridViewGrid_getOuter;
|
container.getOuter = egwGridViewGrid_getOuter;
|
||||||
container.updateAssumedHeights = egwGridViewGrid_updateAssumedHeights;
|
container.updateAssumedHeights = egwGridViewGrid_updateAssumedHeights;
|
||||||
|
container.beginUpdate = egwGridViewGrid_beginUpdate;
|
||||||
|
container.endUpdate = egwGridViewGrid_endUpdate;
|
||||||
|
container.triggerUpdateAssumedHeights = egwGridViewGrid_triggerUpdateAssumedHeights;
|
||||||
container.children = [];
|
container.children = [];
|
||||||
container.outer = _outer;
|
container.outer = _outer;
|
||||||
|
container.containerClass = "grid";
|
||||||
|
|
||||||
// Overwrite the abstract container interface functions
|
// Overwrite the abstract container interface functions
|
||||||
container.invalidateHeightCache = egwGridViewGrid_invalidateHeightCache;
|
container.invalidateHeightCache = egwGridViewGrid_invalidateHeightCache;
|
||||||
@ -538,6 +562,67 @@ function egwGridViewGrid(_grid, _heightChangeProc, _scrollable, _outer)
|
|||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function egwGridViewGrid_beginUpdate()
|
||||||
|
{
|
||||||
|
if (this.inUpdate == 0)
|
||||||
|
{
|
||||||
|
this.didUpdate = false;
|
||||||
|
|
||||||
|
if (this.grid)
|
||||||
|
{
|
||||||
|
this.grid.beginUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.inUpdate++;
|
||||||
|
}
|
||||||
|
|
||||||
|
function egwGridViewGrid_triggerUpdateAssumedHeights()
|
||||||
|
{
|
||||||
|
this.triggerID++;
|
||||||
|
var self = this;
|
||||||
|
var id = this.triggerID;
|
||||||
|
window.setTimeout(function() {
|
||||||
|
if (id = self.triggerID)
|
||||||
|
{
|
||||||
|
self.triggerID = 0;
|
||||||
|
self.updateAssumedHeights(20);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
EGW_GRID_UPDATE_HEIGHTS_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
function egwGridViewGrid_endUpdate(_recPrev)
|
||||||
|
{
|
||||||
|
if (typeof _recPrev == "undefined")
|
||||||
|
{
|
||||||
|
_recPrev = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.inUpdate > 0)
|
||||||
|
{
|
||||||
|
this.inUpdate--;
|
||||||
|
|
||||||
|
if (this.inUpdate == 0 && this.grid)
|
||||||
|
{
|
||||||
|
this.grid.endUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.inUpdate == 0 && this.didUpdate)
|
||||||
|
{
|
||||||
|
// If an update has been done, check whether any height assumptions have been
|
||||||
|
// done. This procedure is executed with some delay, as this gives the browser
|
||||||
|
// the time to insert the newly generated objects into the DOM-Tree and allows
|
||||||
|
// us to read their height at a very fast rate.
|
||||||
|
if (this.didUpdate && !_recPrev)
|
||||||
|
{
|
||||||
|
this.triggerUpdateAssumedHeights();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.didUpdate = false;
|
||||||
|
}
|
||||||
|
|
||||||
function egwGridViewGrid_getOuter()
|
function egwGridViewGrid_getOuter()
|
||||||
{
|
{
|
||||||
if (this.outer)
|
if (this.outer)
|
||||||
@ -571,6 +656,7 @@ function egwGridViewGrid_setupContainer()
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
this.outerNode = $(document.createElement("td"));
|
this.outerNode = $(document.createElement("td"));
|
||||||
|
this.outerNode.addClass("frame");
|
||||||
|
|
||||||
if (this.scrollable)
|
if (this.scrollable)
|
||||||
{
|
{
|
||||||
@ -623,7 +709,6 @@ function egwGridViewGrid_scrollCallback(_event)
|
|||||||
var area = egwArea(this.scrollarea.scrollTop() - EGW_GRID_VIEW_EXT,
|
var area = egwArea(this.scrollarea.scrollTop() - EGW_GRID_VIEW_EXT,
|
||||||
this.scrollHeight + EGW_GRID_VIEW_EXT * 2);
|
this.scrollHeight + EGW_GRID_VIEW_EXT * 2);
|
||||||
|
|
||||||
// Set view area sets the "didUpdate" variable to false
|
|
||||||
this.setViewArea(area);
|
this.setViewArea(area);
|
||||||
|
|
||||||
this.scrollEvents = 0;
|
this.scrollEvents = 0;
|
||||||
@ -638,7 +723,7 @@ function egwGridViewGrid_updateAssumedHeights(_maxCount)
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
this.inUpdate = true;
|
this.beginUpdate();
|
||||||
|
|
||||||
while (traversed < this.children.length && cnt > 0)
|
while (traversed < this.children.length && cnt > 0)
|
||||||
{
|
{
|
||||||
@ -658,7 +743,16 @@ function egwGridViewGrid_updateAssumedHeights(_maxCount)
|
|||||||
var oldHeight = child.assumedHeight;
|
var oldHeight = child.assumedHeight;
|
||||||
child.invalidateHeightCache();
|
child.invalidateHeightCache();
|
||||||
var newHeight = child.getHeight();
|
var newHeight = child.getHeight();
|
||||||
|
|
||||||
|
if (child.containerClass == "row")
|
||||||
|
{
|
||||||
|
if (child.heightInAvg)
|
||||||
|
{
|
||||||
|
outer.remHeightFromAvg(oldHeight);
|
||||||
|
}
|
||||||
outer.addHeightToAvg(newHeight);
|
outer.addHeightToAvg(newHeight);
|
||||||
|
child.heightInAvg = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Offset the position of all following elements by the delta.
|
// Offset the position of all following elements by the delta.
|
||||||
var delta = newHeight - oldHeight;
|
var delta = newHeight - oldHeight;
|
||||||
@ -682,7 +776,7 @@ function egwGridViewGrid_updateAssumedHeights(_maxCount)
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
this.inUpdate = false;
|
this.endUpdate(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -690,9 +784,7 @@ function egwGridViewGrid_updateAssumedHeights(_maxCount)
|
|||||||
if (cnt == 0)
|
if (cnt == 0)
|
||||||
{
|
{
|
||||||
// If the maximum-update-count has been exhausted, retrigger this function
|
// If the maximum-update-count has been exhausted, retrigger this function
|
||||||
window.setTimeout(function() {
|
this.triggerUpdateAssumedHeights();
|
||||||
self.updateAssumedHeights(_maxCount);
|
|
||||||
}, EGW_GRID_UPDATE_HEIGHTS_TIMEOUT);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -705,6 +797,9 @@ function egwGridViewGrid_updateAssumedHeights(_maxCount)
|
|||||||
}
|
}
|
||||||
|
|
||||||
function egwGridViewGrid_insertContainer(_after, _class, _params)
|
function egwGridViewGrid_insertContainer(_after, _class, _params)
|
||||||
|
{
|
||||||
|
this.beginUpdate();
|
||||||
|
try
|
||||||
{
|
{
|
||||||
this.didUpdate = true;
|
this.didUpdate = true;
|
||||||
|
|
||||||
@ -713,7 +808,7 @@ function egwGridViewGrid_insertContainer(_after, _class, _params)
|
|||||||
var idx = this.children.length;
|
var idx = this.children.length;
|
||||||
if (typeof _after == "number")
|
if (typeof _after == "number")
|
||||||
{
|
{
|
||||||
idx = Math.max(-1, Math.min(this.children.length, _after)) + 1;
|
idx = Math.min(this.children.length, Math.max(-1, _after)) + 1;
|
||||||
}
|
}
|
||||||
else if (typeof _after == "object" && _after)
|
else if (typeof _after == "object" && _after)
|
||||||
{
|
{
|
||||||
@ -746,7 +841,7 @@ function egwGridViewGrid_insertContainer(_after, _class, _params)
|
|||||||
|
|
||||||
// Offset the position of all following elements by the height of the container
|
// Offset the position of all following elements by the height of the container
|
||||||
// and move the index of those elements
|
// and move the index of those elements
|
||||||
var height = this.getOuter().avgRowHeight; //container.getHeight(); // This took a lot of time.
|
var height = this.getOuter().avgRowHeight;
|
||||||
container.assumedHeight = height;
|
container.assumedHeight = height;
|
||||||
for (var i = idx + 1; i < this.children.length; i++)
|
for (var i = idx + 1; i < this.children.length; i++)
|
||||||
{
|
{
|
||||||
@ -756,11 +851,22 @@ function egwGridViewGrid_insertContainer(_after, _class, _params)
|
|||||||
|
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
this.endUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.callHeightChangeProc();
|
||||||
|
}
|
||||||
|
|
||||||
function egwGridViewGrid_removeContainer(_container)
|
function egwGridViewGrid_removeContainer(_container)
|
||||||
{
|
{
|
||||||
this.didUpdate = true;
|
this.didUpdate = true;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.beginUpdate();
|
||||||
|
|
||||||
var idx = _container.index;
|
var idx = _container.index;
|
||||||
|
|
||||||
// Offset the position of the folowing children back
|
// Offset the position of the folowing children back
|
||||||
@ -780,6 +886,13 @@ function egwGridViewGrid_removeContainer(_container)
|
|||||||
|
|
||||||
this.children.splice(idx, 1);
|
this.children.splice(idx, 1);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
this.endUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.callHeightChangeProc();
|
||||||
|
}
|
||||||
|
|
||||||
function egwGridViewGrid_empty(_newColumns)
|
function egwGridViewGrid_empty(_newColumns)
|
||||||
{
|
{
|
||||||
@ -807,6 +920,7 @@ function egwGridViewGrid_invalidateHeightCache(_children)
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.height = false;
|
this.height = false;
|
||||||
|
this.assumedHeight = false;
|
||||||
|
|
||||||
if (_children)
|
if (_children)
|
||||||
{
|
{
|
||||||
@ -837,17 +951,17 @@ function egwGridViewGrid_heightChangeHandler(_elem)
|
|||||||
{
|
{
|
||||||
this.didUpdate = true;
|
this.didUpdate = true;
|
||||||
|
|
||||||
// Get the height-change
|
// The old height of the element is now only an assumed height - the next
|
||||||
|
// time the "updateAssumedHeights" functions is triggered, this will be
|
||||||
|
// updated.
|
||||||
var oldHeight = _elem.assumedHeight !== false ? _elem.assumedHeight :
|
var oldHeight = _elem.assumedHeight !== false ? _elem.assumedHeight :
|
||||||
(_elem.height === false ? 0 : _elem.height);
|
(_elem.height === false ? this.getOuter().avgRowHeight : _elem.height);
|
||||||
_elem.invalidateHeightCache(false);
|
_elem.invalidateHeightCache(false);
|
||||||
var newHeight = _elem.getHeight();
|
_elem.assumedHeight = oldHeight;
|
||||||
var offs = newHeight - oldHeight;
|
|
||||||
|
|
||||||
// Set the offset of all elements succeding the given element correctly
|
if (_elem.containerClass == "grid" && !this.inUpdate)
|
||||||
for (var i = _elem.index + 1; i < this.children.length; i++)
|
|
||||||
{
|
{
|
||||||
this.children[i].offsetPosition(offs);
|
this.triggerUpdateAssumedHeights();
|
||||||
}
|
}
|
||||||
|
|
||||||
// As a result of the height of one of the children, the height of this element
|
// As a result of the height of one of the children, the height of this element
|
||||||
@ -864,8 +978,13 @@ function egwGridViewGrid_doInsertIntoDOM()
|
|||||||
this.outerNode.attr("colspan", this.columns.length + (this.scrollable ? 1 : 0));
|
this.outerNode.attr("colspan", this.columns.length + (this.scrollable ? 1 : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
function egwGridViewGrid_doSetviewArea(_area)
|
function egwGridViewGrid_doSetviewArea(_area, _recPrev)
|
||||||
{
|
{
|
||||||
|
if (typeof _recPrev == "undefined")
|
||||||
|
{
|
||||||
|
_recPrev == false;
|
||||||
|
}
|
||||||
|
|
||||||
// Do a binary search for elements which are inside the given area
|
// Do a binary search for elements which are inside the given area
|
||||||
this.didUpdate = false;
|
this.didUpdate = false;
|
||||||
var elem = null;
|
var elem = null;
|
||||||
@ -927,7 +1046,9 @@ function egwGridViewGrid_doSetviewArea(_area)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.inUpdate = true;
|
try
|
||||||
|
{
|
||||||
|
this.beginUpdate();
|
||||||
|
|
||||||
// Call the setViewArea function of visible child elements
|
// Call the setViewArea function of visible child elements
|
||||||
// Imporant: The setViewArea function has to work on a copy of children,
|
// Imporant: The setViewArea function has to work on a copy of children,
|
||||||
@ -937,19 +1058,10 @@ function egwGridViewGrid_doSetviewArea(_area)
|
|||||||
{
|
{
|
||||||
elems[i].setViewArea(_area, true);
|
elems[i].setViewArea(_area, true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
this.inUpdate = false;
|
finally
|
||||||
|
|
||||||
// If an update has been done, check whether any height assumptions have been
|
|
||||||
// done. This procedure is executed with some delay, as this gives the browser
|
|
||||||
// the time to insert the newly generated objects into the DOM-Tree and allows
|
|
||||||
// us to read their height at a very fast rate.
|
|
||||||
if (this.didUpdate)
|
|
||||||
{
|
{
|
||||||
var self = this;
|
this.endUpdate(_recPrev);
|
||||||
window.setTimeout(function() {
|
|
||||||
self.updateAssumedHeights(20);
|
|
||||||
}, EGW_GRID_UPDATE_HEIGHTS_TIMEOUT);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -968,10 +1080,17 @@ function egwGridViewRow(_grid, _heightChangeProc, _item)
|
|||||||
container.aoiSetup = egwGridViewRow_aoiSetup;
|
container.aoiSetup = egwGridViewRow_aoiSetup;
|
||||||
container.getAOI = egwGridViewRow_getAOI;
|
container.getAOI = egwGridViewRow_getAOI;
|
||||||
container.checkOdd = egwGridViewRow_checkOdd;
|
container.checkOdd = egwGridViewRow_checkOdd;
|
||||||
|
container._columnClick = egwGridViewRow__columnClick;
|
||||||
|
container.setOpen = egwGridViewRow_setOpen;
|
||||||
|
container.tdObjects = [];
|
||||||
|
container.containerClass = "row";
|
||||||
|
container.childGrid = null;
|
||||||
|
container.opened = false;
|
||||||
|
|
||||||
// Overwrite the inherited abstract functions
|
// Overwrite the inherited abstract functions
|
||||||
container.doInsertIntoDOM = egwGridViewRow_doInsertIntoDOM;
|
container.doInsertIntoDOM = egwGridViewRow_doInsertIntoDOM;
|
||||||
container.doSetViewArea = egwGridViewRow_doSetViewArea;
|
container.doSetViewArea = egwGridViewRow_doSetViewArea;
|
||||||
|
container.doUpdateData = egwGridViewRow_doUpdateData;
|
||||||
|
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
@ -1015,6 +1134,16 @@ function egwGridViewRow_getAOI()
|
|||||||
return this.aoi;
|
return this.aoi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function egwGridViewRow__columnClick(_shiftState, _column)
|
||||||
|
{
|
||||||
|
var state = this.aoi.getState();
|
||||||
|
var isSelected = egwBitIsSet(state, EGW_AO_STATE_SELECTED);
|
||||||
|
|
||||||
|
this.aoi.updateState(EGW_AO_STATE_SELECTED,
|
||||||
|
!egwBitIsSet(_shiftState, EGW_AO_SHIFT_STATE_MULTI) || !isSelected,
|
||||||
|
_shiftState);
|
||||||
|
}
|
||||||
|
|
||||||
var
|
var
|
||||||
EGW_GRID_VIEW_ROW_BORDER = false;
|
EGW_GRID_VIEW_ROW_BORDER = false;
|
||||||
|
|
||||||
@ -1032,26 +1161,25 @@ function egwGridViewRow_doInsertIntoDOM()
|
|||||||
// Check whether this element is odd
|
// Check whether this element is odd
|
||||||
this.checkOdd();
|
this.checkOdd();
|
||||||
|
|
||||||
// Read the column data
|
|
||||||
/*var ids = [];
|
|
||||||
for (var i = 0; i < this.columns.length; i++)
|
|
||||||
{
|
|
||||||
ids.push(this.columns[i].id);
|
|
||||||
}
|
|
||||||
|
|
||||||
data = this.item.getData(ids);*/
|
|
||||||
|
|
||||||
for (var i = 0; i < this.columns.length; i++)
|
for (var i = 0; i < this.columns.length; i++)
|
||||||
{
|
{
|
||||||
var col = this.columns[i];
|
var col = this.columns[i];
|
||||||
var td = $(document.createElement("td"));
|
var td = $(document.createElement("td"));
|
||||||
|
|
||||||
//if (typeof data[this.columns[i].id] != "undefined")
|
|
||||||
{
|
|
||||||
td.html("col" + i);
|
|
||||||
}
|
|
||||||
this.parentNode.append(td);
|
this.parentNode.append(td);
|
||||||
|
|
||||||
|
// Assign the click event to the column
|
||||||
|
td.mousedown(egwPreventSelect);
|
||||||
|
td.click({"item": this, "col": col.id}, function(e) {
|
||||||
|
this.onselectstart = null;
|
||||||
|
e.data.item._columnClick(egwGetShiftState(e), e.data.col);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
td.addClass("first");
|
||||||
|
}
|
||||||
|
|
||||||
// Set the column width
|
// Set the column width
|
||||||
if (EGW_GRID_VIEW_ROW_BORDER === false)
|
if (EGW_GRID_VIEW_ROW_BORDER === false)
|
||||||
{
|
{
|
||||||
@ -1059,11 +1187,117 @@ function egwGridViewRow_doInsertIntoDOM()
|
|||||||
}
|
}
|
||||||
td.css("width", col.drawnWidth - EGW_GRID_VIEW_ROW_BORDER);
|
td.css("width", col.drawnWidth - EGW_GRID_VIEW_ROW_BORDER);
|
||||||
|
|
||||||
|
// Store the column in the td object array
|
||||||
|
this.tdObjects.push({
|
||||||
|
"col": col,
|
||||||
|
"td": td
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.doUpdateData(true);
|
||||||
|
|
||||||
this.checkViewArea();
|
this.checkViewArea();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function egwGridViewRow_doUpdateData(_immediate)
|
||||||
|
{
|
||||||
|
var ids = [];
|
||||||
|
for (var i = 0; i < this.columns.length; i++)
|
||||||
|
{
|
||||||
|
ids.push(this.columns[i].id);
|
||||||
|
}
|
||||||
|
|
||||||
|
data = this.item.getData(ids);
|
||||||
|
|
||||||
|
for (var i = 0; i < this.tdObjects.length; i++)
|
||||||
|
{
|
||||||
|
var td = this.tdObjects[i].td;
|
||||||
|
var col = this.tdObjects[i].col;
|
||||||
|
if (typeof data[col.id] != "undefined")
|
||||||
|
{
|
||||||
|
td.empty();
|
||||||
|
if (col.type == EGW_COL_TYPE_NAME_ICON_FIXED)
|
||||||
|
{
|
||||||
|
// Insert the indentation spacer
|
||||||
|
var depth = this.item.getDepth() - 1;
|
||||||
|
if (depth > 0)
|
||||||
|
{
|
||||||
|
// Build the indentation object
|
||||||
|
var indentation = $(document.createElement("span"));
|
||||||
|
indentation.addClass("indentation");
|
||||||
|
indentation.css("width", (depth * 12) + "px");
|
||||||
|
td.append(indentation);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert the open/close arrow
|
||||||
|
if (this.item.canHaveChildren)
|
||||||
|
{
|
||||||
|
var arrow = $(document.createElement("span"));
|
||||||
|
arrow.addClass("arrow");
|
||||||
|
arrow.addClass(this.item.opened ? "opened" : "closed");
|
||||||
|
arrow.click(this, function(e) {
|
||||||
|
$this = $(this);
|
||||||
|
|
||||||
|
if (!e.data.opened)
|
||||||
|
{
|
||||||
|
$this.addClass("opened");
|
||||||
|
$this.removeClass("closed");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this.addClass("closed");
|
||||||
|
$this.removeClass("opened");
|
||||||
|
}
|
||||||
|
|
||||||
|
e.data.setOpen(!e.data.opened);
|
||||||
|
});
|
||||||
|
td.append(arrow);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert the icon
|
||||||
|
if (data[col.id].iconUrl)
|
||||||
|
{
|
||||||
|
// Build the icon element
|
||||||
|
var icon = $(document.createElement("img"));
|
||||||
|
icon.attr("src", data[col.id].iconUrl);
|
||||||
|
icon.load(this, function(e) {
|
||||||
|
e.data.callHeightChangeProc();
|
||||||
|
});
|
||||||
|
icon.addClass("icon");
|
||||||
|
td.append(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the caption
|
||||||
|
if (data[col.id].caption)
|
||||||
|
{
|
||||||
|
var caption = $(document.createElement("span"));
|
||||||
|
caption.html(data[col.id].caption);
|
||||||
|
td.append(caption);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
td.html(data[col.id]);
|
||||||
|
}
|
||||||
|
td.toggleClass("queued", false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
td.toggleClass("queued", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the open state
|
||||||
|
this.setOpen(this.item.opened);
|
||||||
|
|
||||||
|
// If the call is not from inside the doInsertIntoDOM function, we have to
|
||||||
|
// inform the parent about a possible height change
|
||||||
|
if (!_immediate)
|
||||||
|
{
|
||||||
|
this.callHeightChangeProc();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function egwGridViewRow_checkOdd()
|
function egwGridViewRow_checkOdd()
|
||||||
{
|
{
|
||||||
if (this.item && this.parentNode)
|
if (this.item && this.parentNode)
|
||||||
@ -1084,6 +1318,44 @@ function egwGridViewRow_doSetViewArea()
|
|||||||
this.checkOdd();
|
this.checkOdd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function egwGridViewRow_setOpen(_open)
|
||||||
|
{
|
||||||
|
if (_open != this.opened)
|
||||||
|
{
|
||||||
|
if (_open)
|
||||||
|
{
|
||||||
|
if (!this.childGrid)
|
||||||
|
{
|
||||||
|
// Get the arrow and put it to "loading" state
|
||||||
|
var arrow = $(".arrow", this.parentNode);
|
||||||
|
arrow.removeClass("closed");
|
||||||
|
arrow.addClass("loading");
|
||||||
|
|
||||||
|
// Create the "child grid"
|
||||||
|
this.childGrid = this.grid.insertContainer(this.index, egwGridViewGrid,
|
||||||
|
false);
|
||||||
|
this.childGrid.setVisible(false);
|
||||||
|
var spacer = this.childGrid.insertContainer(-1, egwGridViewSpacer,
|
||||||
|
this.grid.getOuter().avgRowHeight);
|
||||||
|
this.item.getChildren(function(_children) {
|
||||||
|
arrow.removeClass("loading");
|
||||||
|
arrow.removeClass("closed");
|
||||||
|
arrow.addClass("opened");
|
||||||
|
spacer.setItemList(_children);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.childGrid)
|
||||||
|
{
|
||||||
|
this.childGrid.setVisible(_open);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.opened = _open;
|
||||||
|
this.item.opend = _open;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** -- egwGridViewSpacer Class -- **/
|
/** -- egwGridViewSpacer Class -- **/
|
||||||
|
|
||||||
@ -1138,6 +1410,8 @@ function egwGridViewSpacer_doInsertIntoDOM()
|
|||||||
* creates those.
|
* creates those.
|
||||||
*/
|
*/
|
||||||
function egwGridViewSpacer_doSetViewArea()
|
function egwGridViewSpacer_doSetViewArea()
|
||||||
|
{
|
||||||
|
if (this.items.length > 0)
|
||||||
{
|
{
|
||||||
var avgHeight = this.grid.getOuter().avgRowHeight;
|
var avgHeight = this.grid.getOuter().avgRowHeight;
|
||||||
|
|
||||||
@ -1159,7 +1433,8 @@ function egwGridViewSpacer_doSetViewArea()
|
|||||||
this.grid.insertContainer(idx - 1, it_mid[i].type, it_mid[i]);
|
this.grid.insertContainer(idx - 1, it_mid[i].type, it_mid[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If top was greater than 0, insert a new spacer in front of the
|
// If top was greater than 0, insert a new spacer in front of the newly
|
||||||
|
// created elements.
|
||||||
if (it_top.length > 0)
|
if (it_top.length > 0)
|
||||||
{
|
{
|
||||||
var spacer = this.grid.insertContainer(idx - 1, egwGridViewSpacer, avgHeight);
|
var spacer = this.grid.insertContainer(idx - 1, egwGridViewSpacer, avgHeight);
|
||||||
@ -1177,5 +1452,6 @@ function egwGridViewSpacer_doSetViewArea()
|
|||||||
this.grid.removeContainer(this);
|
this.grid.removeContainer(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,6 +14,26 @@ body, td, th {
|
|||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.egwGridView_outer td.queued {
|
||||||
|
background-image: url(imgs/ajax-loader.gif);
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
height: 19px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.egwGridView_grid tr.focused td {
|
||||||
|
background-image: url(imgs/focused_hatching.png);
|
||||||
|
background-repeat: repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.egwGridView_grid tr.selected td {
|
||||||
|
background-color: #b7c3ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.egwGridView_grid tr.selected.odd td {
|
||||||
|
background-color: #9dadff;
|
||||||
|
}
|
||||||
|
|
||||||
.egwGridView_scrollarea {
|
.egwGridView_scrollarea {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
@ -37,16 +57,71 @@ body, td, th {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.egwGridView_grid td, .egwGridView_grid tr {
|
.egwGridView_grid td {
|
||||||
border-right: 1px solid silver;
|
border-right: 1px solid silver;
|
||||||
padding: 4px 3px 4px 4px;
|
padding: 2px 3px 2px 4px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.egwGridView_grid tr {
|
||||||
|
padding: 2px 3px 2px 4px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.egwGridView_grid tr.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.egwGridView_grid tr.odd {
|
.egwGridView_grid tr.odd {
|
||||||
background-color: #F1F1F1;
|
background-color: #F1F1F1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.egwGridView_grid span.indentation {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.egwGridView_grid span {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.egwGridView_grid img.icon {
|
||||||
|
vertical-align: middle;
|
||||||
|
margin: 2px 5px 2px 2px;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-khtml-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.egwGridView_grid span.arrow {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
margin-right: 2px;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-khtml-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.egwGridView_grid span.arrow.opened {
|
||||||
|
cursor: pointer;
|
||||||
|
background-image: url(imgs/arrows.png);
|
||||||
|
background-position: -8px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.egwGridView_grid span.arrow.closed {
|
||||||
|
cursor: pointer;
|
||||||
|
background-image: url(imgs/arrows.png);
|
||||||
|
background-position: 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.egwGridView_grid span.arrow.loading {
|
||||||
|
cursor: pointer;
|
||||||
|
background-image: url(imgs/ajax-loader.gif);
|
||||||
|
background-position: 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
.egwGridView_outer thead th {
|
.egwGridView_outer thead th {
|
||||||
background-color: #E0E0E0;
|
background-color: #E0E0E0;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
@ -66,32 +141,6 @@ body, td, th {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
.grid_outer {
|
|
||||||
border-spacing: 0;
|
|
||||||
border-collapse: collapse;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid_outer div.scrollarea {
|
|
||||||
overflow: auto;
|
|
||||||
width:100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid_outer td, .grid_outer tr {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.horizontal_spacer {
|
|
||||||
display: block;
|
|
||||||
background-image: url(imgs/non_loaded_bg.png);
|
|
||||||
background-position: top left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selectcols {
|
.selectcols {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 10px;
|
width: 10px;
|
||||||
@ -104,99 +153,9 @@ body, td, th {
|
|||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid {
|
.frame {
|
||||||
border-spacing: 0;
|
padding: 0 !important;
|
||||||
border-collapse: collapse;
|
border-right: 0 none silver !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.grid th.optcol {
|
|
||||||
width: 6px;
|
|
||||||
padding: 0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid tr.hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid td, .grid th {
|
|
||||||
border: 1px solid white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid tr.focused td {
|
|
||||||
border: 1px dotted black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid tr.selected td {
|
|
||||||
background-image: url(imgs/select_overlay.png);
|
|
||||||
background-position: center;
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid span.arrow {
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: middle;
|
|
||||||
width: 8px;
|
|
||||||
height: 8px;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
margin-right: 2px;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-khtml-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid span.arrow.opened {
|
|
||||||
cursor: pointer;
|
|
||||||
background-image: url(imgs/arrows.png);
|
|
||||||
background-position: -8px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid span.arrow.closed {
|
|
||||||
cursor: pointer;
|
|
||||||
background-image: url(imgs/arrows.png);
|
|
||||||
background-position: 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid tr.odd {
|
|
||||||
background-color: #F1F1F1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid th {
|
|
||||||
background-color: #E0E0E0;
|
|
||||||
font-weight: normal;
|
|
||||||
padding: 5px;
|
|
||||||
text-align: left;
|
|
||||||
border-left: 1px solid silver;
|
|
||||||
border-top: 1px solid silver;
|
|
||||||
border-right: 1px solid gray;
|
|
||||||
border-bottom: 1px solid gray;
|
|
||||||
background-image: url(imgs/header_overlay.png);
|
|
||||||
background-position: center;
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid td {
|
|
||||||
padding: 0;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid th.front {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid span.caption {
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid span.indentation {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid img.icon {
|
|
||||||
vertical-align: middle;
|
|
||||||
margin: 2px 5px 2px 2px;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-khtml-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
BIN
phpgwapi/js/egw_action/test/imgs/ajax-loader.gif
Normal file
BIN
phpgwapi/js/egw_action/test/imgs/ajax-loader.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
BIN
phpgwapi/js/egw_action/test/imgs/focused_hatching.png
Normal file
BIN
phpgwapi/js/egw_action/test/imgs/focused_hatching.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 202 B |
169
phpgwapi/js/egw_action/test/imgs/focused_hatching.svg
Normal file
169
phpgwapi/js/egw_action/test/imgs/focused_hatching.svg
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="32"
|
||||||
|
height="32"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.0 r9654"
|
||||||
|
sodipodi:docname="focused_hatching.svg"
|
||||||
|
inkscape:export-filename="/home/andreas/source/egroupware/trunk/egroupware/phpgwapi/js/egw_action/test/imgs/focused_hatching.png"
|
||||||
|
inkscape:export-xdpi="90"
|
||||||
|
inkscape:export-ydpi="90">
|
||||||
|
<defs
|
||||||
|
id="defs4" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="7.9195959"
|
||||||
|
inkscape:cx="8.8135677"
|
||||||
|
inkscape:cy="16.76308"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:window-width="1600"
|
||||||
|
inkscape:window-height="823"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="24"
|
||||||
|
inkscape:window-maximized="1">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid2985"
|
||||||
|
empspacing="2"
|
||||||
|
visible="true"
|
||||||
|
enabled="true"
|
||||||
|
snapvisiblegridlinesonly="true" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Ebene 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(0,-1020.3622)">
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.18232045"
|
||||||
|
d="M -2,34 34,-2"
|
||||||
|
id="path2987"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
transform="translate(0,1020.3622)" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.05801105"
|
||||||
|
d="M -2,30 30,-2"
|
||||||
|
id="path2989"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
transform="translate(0,1020.3622)" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.18232045"
|
||||||
|
d="M 26,-2 -2,26"
|
||||||
|
id="path2991"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
transform="translate(0,1020.3622)" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.05801105"
|
||||||
|
d="M 22,-2 -2,22"
|
||||||
|
id="path2993"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
transform="translate(0,1020.3622)" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.18232045"
|
||||||
|
d="M 18,-2 -2,18"
|
||||||
|
id="path2995"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
transform="translate(0,1020.3622)" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.05801105"
|
||||||
|
d="M -2,14 14,-2"
|
||||||
|
id="path2997"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
transform="translate(0,1020.3622)" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.05801105"
|
||||||
|
d="M 10,-2 -2,10"
|
||||||
|
id="path2999"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
transform="translate(0,1020.3622)" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.18232045"
|
||||||
|
d="M -2,6 6,-2"
|
||||||
|
id="path3001"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
transform="translate(0,1020.3622)" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.05801105"
|
||||||
|
d="M 2,-2 -2,2"
|
||||||
|
id="path3003"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
transform="translate(0,1020.3622)" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.05801105"
|
||||||
|
d="M 34,2 2,34"
|
||||||
|
id="path3005"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
transform="translate(0,1020.3622)" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.18232045"
|
||||||
|
d="M 6,34 34,6"
|
||||||
|
id="path3007"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
transform="translate(0,1020.3622)" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.05801105"
|
||||||
|
d="M 34,10 10,34"
|
||||||
|
id="path3009"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
transform="translate(0,1020.3622)" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.18232045"
|
||||||
|
d="M 14,34 34,14"
|
||||||
|
id="path3011"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
transform="translate(0,1020.3622)" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.05801105"
|
||||||
|
d="M 34,18 18,34"
|
||||||
|
id="path3013"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
transform="translate(0,1020.3622)" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.18232045"
|
||||||
|
d="M 22,34 34,22"
|
||||||
|
id="path3015"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
transform="translate(0,1020.3622)" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.05801105"
|
||||||
|
d="m 34,26 -8,8"
|
||||||
|
id="path3017"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
transform="translate(0,1020.3622)" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.18232045"
|
||||||
|
d="m 30,34 4,-4"
|
||||||
|
id="path3019"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
transform="translate(0,1020.3622)" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 6.3 KiB |
@ -17,7 +17,8 @@
|
|||||||
<link rel="stylesheet" href="grid.css"/>
|
<link rel="stylesheet" href="grid.css"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Test for dynamically displaying and loading grid lines (0,1 Mio Entries)</h1>
|
<h1>Test for dynamically displaying and loading grid lines</h1>
|
||||||
|
<b>Simulates network trafic by using window.setTimeout(), 100ms network latency</b>
|
||||||
<div id="container"></div>
|
<div id="container"></div>
|
||||||
<script>
|
<script>
|
||||||
var grid = null;
|
var grid = null;
|
||||||
@ -27,8 +28,9 @@
|
|||||||
var columns =
|
var columns =
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
|
"id": "name",
|
||||||
"caption": "Name",
|
"caption": "Name",
|
||||||
"width": "33%",
|
"width": "20%",
|
||||||
"type": EGW_COL_TYPE_NAME_ICON_FIXED
|
"type": EGW_COL_TYPE_NAME_ICON_FIXED
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -37,8 +39,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "rights",
|
"id": "rights",
|
||||||
"caption": "UNIX Filerights",
|
"caption": "UNIX Filerights"
|
||||||
"default": "---------"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "mime",
|
"id": "mime",
|
||||||
@ -46,29 +47,81 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "atime",
|
"id": "atime",
|
||||||
"caption": "atime"
|
"caption": "atime",
|
||||||
|
"width": "15%"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "ctime",
|
"id": "ctime",
|
||||||
"caption": "ctime"
|
"caption": "ctime",
|
||||||
|
"width": "15%"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "mtime",
|
"id": "mtime",
|
||||||
"caption": "mtime"
|
"caption": "mtime",
|
||||||
|
"width": "15%"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "owner",
|
"id": "owner",
|
||||||
"caption": "owner"
|
"caption": "owner",
|
||||||
|
"width": "10%"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "group",
|
"id": "group",
|
||||||
"caption": "group"
|
"caption": "group",
|
||||||
|
"width": "10%"
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
function fetchDataProc(_elems, _columns)
|
function fetchDataProc(_elems, _columns, _callback, _context)
|
||||||
{
|
{
|
||||||
console.log("Fetch Data Proc: ", _elems, _columns);
|
// Delay the result a bit to simulate real network traffic
|
||||||
|
window.setTimeout(function() {
|
||||||
|
var result = [];
|
||||||
|
for (var i = 0; i < _elems.length; i++)
|
||||||
|
{
|
||||||
|
// console.log(_elems[i]);
|
||||||
|
if (_elems[i].substr(0, "[CHILDREN]".length) == "[CHILDREN]")
|
||||||
|
{
|
||||||
|
var id = _elems[i].substr("[CHILDREN]".length);
|
||||||
|
var children = [
|
||||||
|
{
|
||||||
|
"entryType": EGW_DATA_TYPE_RANGE,
|
||||||
|
"prefix": id + "_child_",
|
||||||
|
"canHaveChildren": true,
|
||||||
|
"count": 20
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
result.push({
|
||||||
|
"id": id,
|
||||||
|
"children": children,
|
||||||
|
"opened": true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var data = {};
|
||||||
|
|
||||||
|
data["size"] = Math.floor(Math.random() * 1024) + "KiB";
|
||||||
|
data["rights"] = "rwxr-xr--";
|
||||||
|
data["mime"] = "image/png";
|
||||||
|
data["atime"] = (new Date).toUTCString();
|
||||||
|
data["mtime"] = (new Date).toUTCString();
|
||||||
|
data["ctime"] = (new Date).toUTCString();
|
||||||
|
data["owner"] = "as";
|
||||||
|
data["group"] = "stylitedevs";
|
||||||
|
|
||||||
|
result.push({
|
||||||
|
"id": _elems[i],
|
||||||
|
"data": data,
|
||||||
|
"caption": _elems[i],
|
||||||
|
"iconUrl": "imgs/folder.png"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_callback.call(_context, result);
|
||||||
|
}, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
@ -82,11 +135,12 @@
|
|||||||
{
|
{
|
||||||
"entryType": EGW_DATA_TYPE_RANGE,
|
"entryType": EGW_DATA_TYPE_RANGE,
|
||||||
"prefix": "root_elem_",
|
"prefix": "root_elem_",
|
||||||
"count": 100000
|
"canHaveChildren": true,
|
||||||
|
"count": 10000
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
grid.resize(1500, 650);
|
grid.resize(1500, 500);
|
||||||
});
|
});
|
||||||
|
|
||||||
function check_positions()
|
function check_positions()
|
||||||
|
Loading…
Reference in New Issue
Block a user