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:
Andreas Stöckel 2011-03-10 20:58:35 +00:00
parent d7356a350f
commit 57aaf6d756
9 changed files with 1028 additions and 383 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

View 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

View File

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