Implemented hirachical rows

This commit is contained in:
Andreas Stöckel 2012-03-30 11:43:39 +00:00
parent d7bd469ed9
commit 1d405d05ba
9 changed files with 189 additions and 33 deletions

View File

@ -437,7 +437,7 @@ var et2_dataview = Class.extend({
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.egw, this.rowProvider, 19);
this.grid = new et2_dataview_grid(null, null, this.egw, this.rowProvider, 19);
// Insert the grid into the DOM-Tree
var tr = $j(this.grid._nodes[0]);

View File

@ -446,7 +446,7 @@ var et2_dataview_controller = Class.extend({
this.self._rowCallback.call(
this.self._context,
_data,
tr,
this.entry.row,
this.entry.idx,
this.entry
);

View File

@ -394,20 +394,24 @@ var et2_dataview_selectionManager = Class.extend({
this._indexMap[i].uid)
{
// Add the range to the "queryRanges"
if (naStart !== false) {
if (naStart !== false)
{
queryRanges.push(et2_bounds(naStart, i - 1));
naStart = false;
}
// Select the element
this.setSelected(this._indexMap[i].uid, true);
} else if (naStart === false) {
}
else if (naStart === false)
{
naStart = i;
}
}
// Add the last range to the "queryRanges"
if (naStart !== false) {
if (naStart !== false)
{
queryRanges.push(et2_bounds(naStart, i - 1));
naStart = false;
}

View File

@ -157,7 +157,7 @@ var et2_dataview_container = Class.extend(et2_dataview_IInvalidatable, {
// tree.
if (this._inTree)
{
if (_nodes.length === 1)
if (this._nodes.length === 1)
{
if (this._attachData.prepend)
{
@ -170,7 +170,7 @@ var et2_dataview_container = Class.extend(et2_dataview_IInvalidatable, {
}
else
{
_node.after(this._nodes[this._nodes.length - 2]);
this._nodes[this._nodes.length - 2].after(_node);
}
this.invalidate();

View File

@ -53,17 +53,17 @@ var et2_dataview_grid = et2_dataview_container.extend(et2_dataview_IViewRange, {
* parameters are ignored and copied from the given grid instance.
* @param _avgHeight is the starting average height of the column rows.
*/
init: function (_parent, _egw, _rowProvider, _avgHeight) {
init: function (_parent, _parentGrid, _egw, _rowProvider, _avgHeight) {
// Call the inherited constructor
this._super(_parent);
// If the parent is given, copy all other parameters from it
if (_parent != null)
if (_parentGrid != null)
{
this.egw = _parent.egw;
this._orgAvgHeight = false;
this._rowProvider = _parent._rowProvider;
this._rowProvider = _parentGrid._rowProvider;
}
else
{
@ -77,6 +77,8 @@ var et2_dataview_grid = et2_dataview_container.extend(et2_dataview_IViewRange, {
this._scrollTimeout = null;
}
this._parentGrid = _parentGrid;
this._invalidateTimeout = null;
this._invalidateCallback = null;
@ -483,17 +485,11 @@ var et2_dataview_grid = et2_dataview_container.extend(et2_dataview_IViewRange, {
}
var self = this;
var _super = this._super;
this._invalidateTimeout = window.setTimeout(function() {
self._invalidateTimeout = null;
self._doInvalidate();
self._doInvalidate(_super);
}, ET2_GRID_INVALIDATE_TIMEOUT);
// Call the inherited invalidate function, broadcast the invalidation
// through the container tree.
if (this._parent !== null)
{
this._super();
}
},
/**
@ -805,7 +801,7 @@ var et2_dataview_grid = et2_dataview_container.extend(et2_dataview_IViewRange, {
* Invalidate iterates over the "mapping" array. It calculates which
* containers have to be removed and where new containers should be added.
*/
_doInvalidate: function() {
_doInvalidate: function(_super) {
// Update the pixel positions
this._recalculateElementPosition();
@ -831,6 +827,13 @@ var et2_dataview_grid = et2_dataview_container.extend(et2_dataview_IViewRange, {
// Update the view range of all visible elements that implement the
// corresponding interface and request elements for all visible spacers
this._updateContainers();
// Call the inherited invalidate function, broadcast the invalidation
// through the container tree.
if (this._parent && _super)
{
_super.call(this);
}
},
/**
@ -1294,12 +1297,12 @@ var et2_dataview_grid = et2_dataview_container.extend(et2_dataview_IViewRange, {
this.outerCell = $j(document.createElement("td"))
.addClass("frame")
.attr("colspan", this._rowProvider.getColumnCount()
+ (this._parent ? 0 : 1))
+ (this._parentGrid ? 0 : 1))
.appendTo(this.tr);
// Create the scrollarea div if this is the outer grid
this.scrollarea = null;
if (this._parent == null)
if (this._parentGrid == null)
{
this.scrollarea = $j(document.createElement("div"))
.addClass("egwGridView_scrollarea")
@ -1347,7 +1350,7 @@ var et2_dataview_grid = et2_dataview_container.extend(et2_dataview_IViewRange, {
.appendTo(table);
// Set the tr as container element
this.appendNode(this.tr[0]);
this.appendNode($j(this.tr[0]));
}
});

View File

@ -18,7 +18,7 @@
et2_dataview_view_container;
*/
var et2_dataview_row = et2_dataview_container.extend({
var et2_dataview_row = et2_dataview_container.extend(et2_dataview_IViewRange, {
/**
* Creates the row container. Use the "setRow" function to load the actual
@ -33,18 +33,148 @@ var et2_dataview_row = et2_dataview_container.extend({
// Create the outer "tr" tag and append it to the container
this.tr = $j(document.createElement("tr"));
this.appendNode(this.tr);
// Grid row which gets expanded when clicking on the corresponding
// button
this.expansionContainer = null;
this.expansionVisible = false;
// Toggle button which is used to show and hide the expansionContainer
this.expansionButton = null;
},
clear: function() {
this.tr.empty();
},
getDOMNode: function() {
makeExpandable: function (_expandable, _callback, _context) {
if (_expandable)
{
// Create the tr and the button if this has not been done yet
if (!this.expansionButton)
{
this.expansionButton = $j(document.createElement("span"));
this.expansionButton.addClass("arrow closed").text(">");
var self = this;
this.expansionButton.click(function () {
self._handleExpansionButtonClick(_callback, _context);
});
$j("td:first", this.tr).prepend(this.expansionButton);
}
}
else
{
// If the row is made non-expandable, remove the created DOM-Nodes
if (this.expansionButton)
{
this.expansionButton.remove();
}
if (this.expansionContainer)
{
this.expansionContainer.removeFromTree();
}
this.expansionButton = null;
this.expansionContainer = null;
}
},
removeFromTree: function () {
if (this.expansionContainer)
{
this.expansionContainer.removeFromTree();
}
this.expansionContainer = null;
this.expansionButton = null;
this._super();
},
getDOMNode: function () {
return this.tr[0];
},
getJNode: function() {
getJNode: function () {
return this.tr;
},
getHeight: function () {
var h = this._super();
if (this.expansionContainer && this.expansionVisible)
{
h += this.expansionContainer.getHeight();
}
return h;
},
getAvgHeightData: function() {
// Only take the height of the own tr into account
var oldVisible = this.expansionVisible;
this.expansionVisible = false;
var res = {
"avgHeight": this.getHeight(),
"avgCount": 1
}
this.expansionVisible = true;
return res;
},
/** -- PRIVATE FUNCTIONS -- **/
_handleExpansionButtonClick: function (_callback, _context) {
// Create the "expansionContainer" if it does not exist yet
if (!this.expansionContainer)
{
this.expansionContainer = _callback.call(_context);
this.expansionContainer.insertIntoTree(this.tr);
this.expansionVisible = false;
}
// Toggle the visibility of the expansion tr
this.expansionVisible = !this.expansionVisible;
$j(this.expansionContainer._nodes[0]).toggle(this.expansionVisible);
// Set the class of the arrow
if (this.expansionVisible)
{
this.expansionButton.addClass("opened");
this.expansionButton.removeClass("closed");
}
else
{
this.expansionButton.addClass("closed");
this.expansionButton.removeClass("opened");
}
this.invalidate();
},
/** -- Implementation of et2_dataview_IViewRange -- **/
setViewRange: function (_range) {
if (this.expansionContainer && this.expansionVisible
&& this.expansionContainer.implements(et2_dataview_IViewRange))
{
// Substract the height of the own row from the container
var oh = $j(this._nodes[0]).height()
_range.top -= oh;
// Proxy the setViewRange call to the expansion container
this.expansionContainer.setViewRange(_range);
}
}
});

View File

@ -28,13 +28,19 @@ function nm_action(_action, _senders, _target, _ids)
// ----------------------
// TODO: Parse the _ids.inverted flag!
// ----------------------
var idsArr = _ids.ids;
// Translate the internal uids back to server uids
var idsArr = _ids.ids;
for (var i = 0; i < idsArr.length; i++)
{
idsArr[i] = idsArr[i].split("::").pop();
}
// Calculate the ids parameters
var ids = "";
for (var i = 0; i < idsArr.length; i++)
{
var app_id = idsArr[i].split('::', 2);
var id = app_id[1];
var id = idsArr[i];
ids += (id.indexOf(',') >= 0 ? '"'+id.replace(/"/g,'""')+'"' : id) +
((i < idsArr.length - 1) ? "," : "");
}

View File

@ -86,7 +86,7 @@ var et2_nextmatch_rowProvider = Class.extend({
this._template = rowTemplate;
},
getDataRow: function(_data, _tr, _idx) {
getDataRow: function(_data, _row, _idx) {
// Clone the row template
var row = this._dataRow.cloneNode(true);
@ -157,10 +157,11 @@ var et2_nextmatch_rowProvider = Class.extend({
}
// Insert the row into the tr
_tr.appendChild(row);
var tr = _row.getDOMNode();
tr.appendChild(row);
// Set the row data
this._setRowData(this._template.rowData, _tr, mgrs);
this._setRowData(this._template.rowData, tr, mgrs);
return rowWidget;
},

View File

@ -128,11 +128,23 @@
* the actual DOM-Nodes for a node with the given data have to be
* created.
*/
function rowCallback(_data, _tr, _idx)
function rowCallback(_data, _row, _idx)
{
var tr = _row.getDOMNode();
var row = dataview.rowProvider.getPrototype("default");
$j("div", row).each(function () { $j(this).text("#" + _idx + " " + _data.caption) });
$j(_tr).append(row.children());
$j(tr).append(row.children());
_row.makeExpandable(true, function () {
var grid = new et2_dataview_grid(_row, dataview.grid);
var controller = new et2_dataview_controller(grid,
new dataprovider(), rowCallback, linkCallback, null,
objectManager);
controller.update();
return grid;
});
}
function linkCallback() {