diff --git a/etemplate/js/et2_core_DOMWidget.js b/etemplate/js/et2_core_DOMWidget.js
index f9b6a997ac..9befec8301 100644
--- a/etemplate/js/et2_core_DOMWidget.js
+++ b/etemplate/js/et2_core_DOMWidget.js
@@ -151,7 +151,7 @@ var et2_DOMWidget = et2_widget.extend(et2_IDOMNode, {
}
// Append this node at its index
- var idx = this._parent ? this._parent.getChildren().indexOf(this) : -1;
+ var idx = this.getDOMIndex();
if (idx < 0 || idx >= this.parentNode.childNodes.length - 1)
{
this.parentNode.appendChild(node);
@@ -210,6 +210,31 @@ var et2_DOMWidget = et2_widget.extend(et2_IDOMNode, {
return this.parentNode;
},
+ /**
+ * Returns the index of this element in the DOM tree
+ */
+ getDOMIndex: function() {
+ if (this._parent)
+ {
+ var idx = 0;
+ var children = this._parent.getChildren();
+
+ for (var i = 0; i < children.length; i++)
+ {
+ if (children[i] == this)
+ {
+ return idx;
+ }
+ else if (children[i].isInTree())
+ {
+ idx++;
+ }
+ }
+ }
+
+ return -1;
+ },
+
/**
* Sets the id of the DOM-Node.
*/
diff --git a/etemplate/js/et2_core_arrayMgr.js b/etemplate/js/et2_core_arrayMgr.js
index a2397c9d74..bded44d73b 100644
--- a/etemplate/js/et2_core_arrayMgr.js
+++ b/etemplate/js/et2_core_arrayMgr.js
@@ -43,7 +43,6 @@ var et2_arrayMgr = Class.extend({
this.perspectiveData = {
"owner": null,
"key": null,
- "col": 0,
"row": 0
}
},
@@ -217,7 +216,7 @@ var et2_arrayMgr = Class.extend({
return et2_evalBool(val);
},
- openPerspective: function(_owner, _root, _col, _row)
+ openPerspective: function(_owner, _root, _row)
{
// Get the root node
var root = typeof _root == "string" ? this.data[_root] :
@@ -235,10 +234,9 @@ var et2_arrayMgr = Class.extend({
mgr.perspectiveData.key = _root;
}
- // Set the _col and _row parameter
- if (typeof _col != "undefined" && typeof _row != "undefined")
+ // Set _row parameter
+ if (typeof _row != "undefined")
{
- mgr.perspectiveData.col = _col;
mgr.perspectiveData.row = _row;
}
@@ -283,4 +281,26 @@ var et2_readonlysArrayMgr = et2_arrayMgr.extend({
});
+/**
+ * Creates a new set of array managers
+ */
+function et2_arrayMgrs_expand(_owner, _mgrs, _data, _row)
+{
+ // Create a copy of the given _mgrs associative array
+ var result = {};
+
+ // Merge the given data associative array into the existing array managers
+ for (var key in _data)
+ {
+ if (typeof _mgrs[key] != "undefined")
+ {
+ // Open a perspective for the given data row
+ result[key] = _mgrs[key].openPerspective(_owner,
+ _data[key], _row);
+ }
+ }
+
+ // Return the resulting managers object
+ return result;
+}
diff --git a/etemplate/js/et2_core_widget.js b/etemplate/js/et2_core_widget.js
index 8738ca446b..27f36f3613 100644
--- a/etemplate/js/et2_core_widget.js
+++ b/etemplate/js/et2_core_widget.js
@@ -229,10 +229,14 @@ var et2_widget = Class.extend({
this._parent.removeChild(this);
}
- // Delete all references to other objects
- this._children = [];
- this._parent = null;
- this._mgrs = {};
+ // Free the array managers if they belong to this widget
+ for (var key in this._mgrs)
+ {
+ if (this._mgrs[key] && this._mgrs[key].owner == this)
+ {
+ this._mgrs[key].free();
+ }
+ }
},
/**
diff --git a/etemplate/js/et2_dataview_model_dataProvider.js b/etemplate/js/et2_dataview_model_dataProvider.js
index 5567e4daca..eb58451188 100644
--- a/etemplate/js/et2_dataview_model_dataProvider.js
+++ b/etemplate/js/et2_dataview_model_dataProvider.js
@@ -19,12 +19,16 @@
var et2_dataview_dataProvider = Class.extend({
+ init: function() {
+ this.updateQueue = 0;
+ },
+
getCount: function() {
return 10000;
},
- registerDataRow: function(_idx, _dataRow) {
- var row = {
+ registerDataRow: function(_dataRow, _idx) {
+/* var row = {
"type": "dataRow",
"data": {
"ts_title": "Row " + _idx
@@ -41,7 +45,12 @@ var et2_dataview_dataProvider = Class.extend({
}
window.setTimeout(function() {_dataRow.updateData(row); },
- Math.round(rnd / 2));
+ Math.round(rnd / 2));*/
+
+
+ // All data rows are updated independently of all others - this allows
+ // user input between generation of the widgets.
+ window.setTimeout(function() {_dataRow.updateData({"readonlys": {"__ALL__": true}});}, 0);
},
unregisterDataRow: function(_dataRow) {
diff --git a/etemplate/js/et2_dataview_view_grid.js b/etemplate/js/et2_dataview_view_grid.js
index e7a0ba3721..c4b76c3f28 100644
--- a/etemplate/js/et2_dataview_view_grid.js
+++ b/etemplate/js/et2_dataview_view_grid.js
@@ -28,7 +28,7 @@ var ET2_GRID_VIEW_EXT = 25;
/**
* Determines the timeout after which the scroll-event is processed.
*/
-var ET2_GRID_SCROLL_TIMEOUT = 25;
+var ET2_GRID_SCROLL_TIMEOUT = 100;
var partitionTree = null;
@@ -46,7 +46,8 @@ var et2_dataview_grid = Class.extend(et2_dataview_IViewRange, {
* classes.
* @param _avgHeight is the starting average height of the column rows.
*/
- init: function(_parent, _outerId, _columnIds, _dataProvider, _avgHeight) {
+ init: function(_parent, _outerId, _columnIds, _dataProvider, _rowProvider,
+ _avgHeight) {
// If the parent is given, copy all other parameters from it
if (_parent != null)
@@ -63,12 +64,9 @@ var et2_dataview_grid = Class.extend(et2_dataview_IViewRange, {
this._outerId = _outerId;
this._columnIds = _columnIds;
this._dataProvider = _dataProvider;
+ this._rowProvider = _rowProvider;
this._avgHeight = _avgHeight;
- // Create the row provider
- this._rowProvider = new et2_dataview_rowProvider(_outerId,
- _columnIds);
-
this._scrollHeight = 0;
this._scrollTimeout = null;
}
@@ -112,9 +110,8 @@ var et2_dataview_grid = Class.extend(et2_dataview_IViewRange, {
// Stop the rebuild timer
window.clearInterval(this._rebuildTimer);
- // Free the partition tree and the row provider
+ // Free the partition tree
this._partitionTree.free();
- this._rowProvider.free();
},
/**
diff --git a/etemplate/js/et2_dataview_view_gridContainer.js b/etemplate/js/et2_dataview_view_gridContainer.js
index 342e14b369..77ce7b6163 100644
--- a/etemplate/js/et2_dataview_view_gridContainer.js
+++ b/etemplate/js/et2_dataview_view_gridContainer.js
@@ -52,6 +52,7 @@ var et2_dataview_gridContainer = Class.extend({
this.columnNodes = []; // Array with the header containers
this.columns = [];
this.columnMgr = null;
+ this.rowProvider = null;
this.grid = null;
@@ -80,6 +81,12 @@ var et2_dataview_gridContainer = Class.extend({
this.grid.free();
}
+ // Free the row provider
+ if (this.rowProvider)
+ {
+ this.rowProvider.free();
+ }
+
// Detatch the outer element
this.table.remove();
},
@@ -375,9 +382,17 @@ var et2_dataview_gridContainer = Class.extend({
colIds[i] = this.columns[i].id;
}
+ // Create the row provider
+ if (this.rowProvider)
+ {
+ this.rowProvider.free();
+ }
+
+ this.rowProvider = new et2_dataview_rowProvider(this.uniqueId, colIds);
+
// Create the grid class and pass "19" as the starting average row height
this.grid = new et2_dataview_grid(null, this.uniqueId, colIds,
- this.dataProvider, 19);
+ this.dataProvider, this.rowProvider, 19);
// Insert the grid into the DOM-Tree
this.containerTr.append(this.grid.getJNode());
diff --git a/etemplate/js/et2_dataview_view_partitionContainerNodes.js b/etemplate/js/et2_dataview_view_partitionContainerNodes.js
index 2e2a34e1f4..d29d282a00 100644
--- a/etemplate/js/et2_dataview_view_partitionContainerNodes.js
+++ b/etemplate/js/et2_dataview_view_partitionContainerNodes.js
@@ -236,11 +236,9 @@ var et2_dataview_partitionRowNode = et2_dataview_partitionContainerNode.extend({
init: function(_root, _avgHeight) {
var container = new et2_dataview_row(_root.getDataProvider(),
- _root.getRowProvider(), this);
+ _root.getRowProvider(), this, _avgHeight);
this._super(_root, container);
-
- this._avgHeight = _avgHeight;
},
initializeContainer: function() {
diff --git a/etemplate/js/et2_dataview_view_row.js b/etemplate/js/et2_dataview_view_row.js
index c8023d9573..e490818664 100644
--- a/etemplate/js/et2_dataview_view_row.js
+++ b/etemplate/js/et2_dataview_view_row.js
@@ -24,19 +24,66 @@ var et2_dataview_row = et2_dataview_container.extend(et2_dataview_IDataRow, {
this._avgHeight = _avgHeight;
+ this.rowWidget = null;
+ this.hasAvgHeight = false;
+
+ // Get the default row object and scale the row to the average height
this.tr = this.rowProvider.getPrototype("default");
+
+ // Append the row
this.appendNode(this.tr);
},
+ destroy: function() {
+
+ // Unregister the row from the data provider
+ this.dataProvider.unregisterDataRow(this);
+
+ // Free the row widget first, if it has been set
+ if (this.rowWidget)
+ {
+ this.rowWidget.free();
+ }
+
+ this._super();
+ },
+
setIdx: function(_idx) {
this._idx = _idx;
- $j("div:first", this.tr)
- .text(_idx + ":")
- .height((_idx % 10) * 10 + 20);
+ // Register the row in the data provider
+ this.dataProvider.registerDataRow(this, _idx);
+
+ // Set the default height of the rowWidget has not been immediately
+ // created
+ if (!this.rowWidget)
+ {
+ $j("td:first", this.tr).height(this._avgHeight);
+ this.hasAvgHeight = true;
+ }
},
updateData: function(_data) {
+
+ // Reset the height
+ if (this.hasAvgHeight)
+ {
+ $j("td:first", this.tr).height("auto");
+ this.hasAvgHeight = false;
+ }
+
+ // Free the row widget if it already existed
+ if (this.rowWidget != null)
+ {
+ this.rowWidget.free();
+ }
+
+ // Create the row widget - it automatically generates the widgets and
+ // attaches the given data to them
+ this.rowWidget = this.rowProvider.getDataRow(_data, this.tr, this._idx);
+
+ // Invalidate this element
+ this.invalidate();
}
});
diff --git a/etemplate/js/et2_dataview_view_rowProvider.js b/etemplate/js/et2_dataview_view_rowProvider.js
index 429228380b..04830a0ced 100644
--- a/etemplate/js/et2_dataview_view_rowProvider.js
+++ b/etemplate/js/et2_dataview_view_rowProvider.js
@@ -13,6 +13,9 @@
/*egw:uses
jquery.jquery;
et2_core_inheritance;
+ et2_core_interfaces;
+ et2_core_arrayMgr;
+ et2_core_widget;
*/
/**
@@ -27,6 +30,10 @@ var et2_dataview_rowProvider = Class.extend({
this._columnIds = _columnIds;
this._prototypes = {};
+ this._dataRowTemplate = null;
+ this._mgrs = null;
+ this._rootWidget = null;
+
// Create the default row "prototypes"
this._createFullRowPrototype();
this._createDefaultPrototype();
@@ -55,6 +62,25 @@ var et2_dataview_rowProvider = Class.extend({
return this._prototypes[_name].clone();
},
+ setDataRowTemplate: function(_template, _rootWidget) {
+ this._dataRowTemplate = _template;
+ this._rootWidget = _rootWidget;
+ },
+
+ getDataRow: function(_data, _row, _idx) {
+ // Create the row widget
+ var rowWidget = new et2_dataview_rowWidget(this._rootWidget, _row[0]);
+
+ // Create array managers with the given data merged in
+ var mgrs = et2_arrayMgrs_expand(rowWidget, this._rootWidget.getArrayMgrs(),
+ _data, _idx);
+
+ // Let the row widget create the widgets
+ rowWidget.createWidgets(mgrs, this._dataRowTemplate);
+
+ return rowWidget;
+ },
+
/* ---- PRIVATE FUNCTIONS ---- */
_createFullRowPrototype: function() {
@@ -93,3 +119,56 @@ var et2_dataview_rowProvider = Class.extend({
});
+var et2_dataview_rowWidget = et2_widget.extend(et2_IDOMNode, {
+
+ init: function(_parent, _row) {
+ // Call the parent constructor with some dummy attributes
+ this._super(_parent, {"id": "", "type": "rowWidget"});
+
+ // Initialize some variables
+ this._widgets = [];
+
+ // Copy the given DOM node
+ this._row = _row;
+ },
+
+ /**
+ * Copies the given array manager and clones the given widgets and inserts
+ * them into the row which has been passed in the constructor.
+ */
+ createWidgets: function(_mgrs, _widgets) {
+ // Set the array managers - don't use setArrayMgrs here as this creates
+ // an unnecessary copy of the object
+ this._mgrs = _mgrs;
+
+ // Clone the given the widgets with this element as parent
+ this._widgets = new Array(_widgets.length);
+ for (var i = 0; i < _widgets.length; i++)
+ {
+ this._widgets[i] = _widgets[i].clone(this);
+ this._widgets[i].loadingFinished();
+ }
+ },
+
+ /**
+ * Returns the column node for the given sender
+ */
+ getDOMNode: function(_sender) {
+
+ if (typeof _sender == "undefined" || !_sender)
+ {
+ return this.row;
+ }
+
+ for (var i = 0; i < this._widgets.length; i++)
+ {
+ if (this._widgets[i] == _sender)
+ {
+ return this._row.childNodes[i]; // Return the i-th td tag
+ }
+ }
+ }
+
+});
+
+
diff --git a/etemplate/js/et2_extension_nextmatch.js b/etemplate/js/et2_extension_nextmatch.js
index cbe6c5806b..e91b68af6d 100644
--- a/etemplate/js/et2_extension_nextmatch.js
+++ b/etemplate/js/et2_extension_nextmatch.js
@@ -214,6 +214,27 @@ var et2_nextmatch = et2_DOMWidget.extend(et2_IResizeable, {
},
+ _parseDataRow: function(_row, _colData) {
+ var columnWidgets = new Array(this.columns.length);
+
+ for (var x = 0; x < columnWidgets.length; x++)
+ {
+ if (typeof _row[x] != "undefined" && _row[x].widget)
+ {
+ columnWidgets[x] = _row[x].widget;
+
+ // Append the widget to this container
+ this.addChild(_row[x].widget);
+ }
+ else
+ {
+ columnWidgets[x] = _row[x].widget;
+ }
+ }
+
+ this.dataviewContainer.rowProvider.setDataRowTemplate(columnWidgets, this);
+ },
+
_parseGrid: function(_grid) {
// Search the rows for a header-row - if one is found, parse it
for (var y = 0; y < _grid.rowData.length; y++)
@@ -222,6 +243,10 @@ var et2_nextmatch = et2_DOMWidget.extend(et2_IResizeable, {
{
this._parseHeaderRow(_grid.cells[y], _grid.colData);
}
+ else
+ {
+ this._parseDataRow(_grid.cells[y], _grid.colData);
+ }
}
},
diff --git a/etemplate/js/test/et2_test_nextmatch.xet b/etemplate/js/test/et2_test_nextmatch.xet
index 62fd8c63a9..7b4e189061 100644
--- a/etemplate/js/test/et2_test_nextmatch.xet
+++ b/etemplate/js/test/et2_test_nextmatch.xet
@@ -62,6 +62,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+