forked from extern/egroupware
Implemented system for fast cloning of rows in the dataview - widgets which want to support this method have to implement et2_IDetachedDOM
This commit is contained in:
parent
a363919485
commit
8d5b990826
@ -43,7 +43,7 @@ var et2_arrayMgr = Class.extend({
|
||||
this.perspectiveData = {
|
||||
"owner": null,
|
||||
"key": null,
|
||||
"row": 0
|
||||
"row": null
|
||||
}
|
||||
},
|
||||
|
||||
@ -161,7 +161,12 @@ var et2_arrayMgr = Class.extend({
|
||||
var pos_var = _ident.indexOf('$');
|
||||
if (pos_var >= 0)
|
||||
{
|
||||
// TODO
|
||||
console.log("blub", _ident, this.perspectiveData);
|
||||
if (this.perspectiveData.row !== null)
|
||||
{
|
||||
_ident.replace(/\$\{row\}/, this.perspectiveData.row);
|
||||
console.log(_ident);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_index_in_content)
|
||||
@ -266,6 +271,7 @@ var et2_readonlysArrayMgr = et2_arrayMgr.extend({
|
||||
// If the attribute is set, return that
|
||||
if (typeof _attr != "undefined" && _attr !== null)
|
||||
{
|
||||
console.log(_attr, et2_evalBool(_attr));
|
||||
return et2_evalBool(_attr);
|
||||
}
|
||||
|
||||
@ -295,8 +301,11 @@ function et2_arrayMgrs_expand(_owner, _mgrs, _data, _row)
|
||||
if (typeof _mgrs[key] != "undefined")
|
||||
{
|
||||
// Open a perspective for the given data row
|
||||
var rowData = {};
|
||||
rowData[_row] = _data[key];
|
||||
|
||||
result[key] = _mgrs[key].openPerspective(_owner,
|
||||
_data[key], _row);
|
||||
_data[key], rowData);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -529,6 +529,12 @@ function et2_activateLinks(_content)
|
||||
*/
|
||||
function et2_insertLinkText(_text, _node, _target)
|
||||
{
|
||||
// Clear the node
|
||||
for (var i = _node.childNodes.length - 1; i >= 0; i--)
|
||||
{
|
||||
_node.removeChild(_node.childNodes[i]);
|
||||
}
|
||||
|
||||
for (var i = 0; i < _text.length; i++)
|
||||
{
|
||||
var s = _text[i];
|
||||
|
@ -85,4 +85,38 @@ var et2_ISubmitListener = new Interface({
|
||||
submit: function(_values) {}
|
||||
});
|
||||
|
||||
/**
|
||||
* Interface all widgets must support which can operate on given DOM-Nodes. This
|
||||
* is used in grid lists, when only a single row gets really stored in the widget
|
||||
* tree and this instance has to work on multiple copies of the DOM-Tree elements.
|
||||
*/
|
||||
var et2_IDetachedDOM = new Interface({
|
||||
|
||||
/**
|
||||
* Returns a list of attributes which can be set when working in the
|
||||
* "detached" mode. The result is stored in the _attrs array which is provided
|
||||
* by the calling code.
|
||||
*/
|
||||
getDetachedAttributes: function(_attrs) {},
|
||||
|
||||
/**
|
||||
* Returns an array of DOM nodes. The (relativly) same DOM-Nodes have to be
|
||||
* passed to the "setDetachedAttributes" function in the same order.
|
||||
*/
|
||||
getDetachedNodes: function() {},
|
||||
|
||||
/**
|
||||
* Sets the given associative attribute->value array and applies the
|
||||
* attributes to the given DOM-Node.
|
||||
*
|
||||
* @param _nodes is an array of nodes which has to be in the same order as
|
||||
* the nodes returned by "getDetachedNodes"
|
||||
* @param _values is an associative array which contains a subset of attributes
|
||||
* returned by the "getDetachedAttributes" function and sets them to the
|
||||
* given values.
|
||||
*/
|
||||
setDetachedAttributes: function(_nodes, _values) {}
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
@ -50,7 +50,8 @@ var et2_dataview_dataProvider = Class.extend({
|
||||
|
||||
// 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);
|
||||
//window.setTimeout(function() {_dataRow.updateData({"readonlys": {"__ALL__": true}});}, 0);
|
||||
_dataRow.updateData({});
|
||||
},
|
||||
|
||||
unregisterDataRow: function(_dataRow) {
|
||||
|
@ -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 = 100;
|
||||
var ET2_GRID_SCROLL_TIMEOUT = 25;
|
||||
|
||||
var partitionTree = null;
|
||||
|
||||
|
@ -28,7 +28,7 @@ var et2_dataview_row = et2_dataview_container.extend(et2_dataview_IDataRow, {
|
||||
this.hasAvgHeight = false;
|
||||
|
||||
// Get the default row object and scale the row to the average height
|
||||
this.tr = this.rowProvider.getPrototype("default");
|
||||
this.tr = this.rowProvider.getPrototype("dataRow");
|
||||
|
||||
// Append the row
|
||||
this.appendNode(this.tr);
|
||||
|
@ -30,7 +30,7 @@ var et2_dataview_rowProvider = Class.extend({
|
||||
this._columnIds = _columnIds;
|
||||
this._prototypes = {};
|
||||
|
||||
this._dataRowTemplate = null;
|
||||
this._template = null;
|
||||
this._mgrs = null;
|
||||
this._rootWidget = null;
|
||||
|
||||
@ -62,21 +62,330 @@ var et2_dataview_rowProvider = Class.extend({
|
||||
return this._prototypes[_name].clone();
|
||||
},
|
||||
|
||||
setDataRowTemplate: function(_template, _rootWidget) {
|
||||
this._dataRowTemplate = _template;
|
||||
/**
|
||||
* Returns an array containing objects which have variable attributes
|
||||
*/
|
||||
_getVariableAttributeSet: function(_widget) {
|
||||
var variableAttributes = [];
|
||||
|
||||
_widget.iterateOver(function(_widget) {
|
||||
// Create the attribtues
|
||||
var hasAttr = false;
|
||||
var widgetData = {
|
||||
"widget": _widget,
|
||||
"data": []
|
||||
};
|
||||
|
||||
// Include the "value" attribute if the widget is derrived from
|
||||
// et2_valueWidget
|
||||
if (_widget instanceof et2_valueWidget)
|
||||
{
|
||||
hasAttr = true;
|
||||
widgetData.data.push({
|
||||
"attribute": "value",
|
||||
"expression": "@${row}"
|
||||
});
|
||||
}
|
||||
|
||||
// Get all attribute values
|
||||
for (var key in _widget.attributes)
|
||||
{
|
||||
if (!_widget.attributes[key].ignore &&
|
||||
typeof _widget.options[key] != "undefined")
|
||||
{
|
||||
var val = _widget.options[key];
|
||||
|
||||
// TODO: Improve detection
|
||||
if (typeof val == "string" && val.indexOf("$") >= 0)
|
||||
{
|
||||
hasAttr = true;
|
||||
widgetData.data.push({
|
||||
"attribute": key,
|
||||
"expression": val
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add the entry if there is any data in it
|
||||
if (hasAttr)
|
||||
{
|
||||
variableAttributes.push(widgetData);
|
||||
}
|
||||
|
||||
}, this);
|
||||
|
||||
return variableAttributes;
|
||||
},
|
||||
|
||||
_seperateWidgets: function(_varAttrs) {
|
||||
// The detachable array contains all widgets which implement the
|
||||
// et2_IDetachedDOM interface for all needed attributes
|
||||
var detachable = [];
|
||||
|
||||
// The remaining array creates all widgets which have to be completely
|
||||
// cloned when the widget tree is created
|
||||
var remaining = [];
|
||||
|
||||
// Iterate over the widgets
|
||||
for (var i = 0; i < _varAttrs.length; i++)
|
||||
{
|
||||
var widget = _varAttrs[i].widget;
|
||||
|
||||
// Check whether the widget parents are not allready in the "remaining"
|
||||
// slot - if this is the case do not include the widget at all.
|
||||
var insertWidget = true;
|
||||
var checkWidget = function (_widget) {
|
||||
if (_widget.parent != null)
|
||||
{
|
||||
for (var i = 0; i < remaining.length; i++)
|
||||
{
|
||||
if (remaining[i].widget == _widget.parent)
|
||||
{
|
||||
insertWidget = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
checkWidget(_widget.parent);
|
||||
}
|
||||
};
|
||||
checkWidget(widget);
|
||||
|
||||
// Handle the next widget if this one should not be included.
|
||||
if (!insertWidget)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check whether the widget implements the et2_IDetachedDOM interface
|
||||
var isDetachable = false;
|
||||
if (widget.implements(et2_IDetachedDOM))
|
||||
{
|
||||
// Get all attributes the widgets supports to be set in the
|
||||
// "detached" mode
|
||||
var supportedAttrs = [];
|
||||
widget.getDetachedAttributes(supportedAttrs);
|
||||
isDetachable = true;
|
||||
|
||||
for (var j = 0; j < _varAttrs[i].data.length && isDetachable; j++)
|
||||
{
|
||||
var data = _varAttrs[i].data[j];
|
||||
|
||||
isDetachable &= supportedAttrs.indexOf(data.attribute) != -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Insert the widget into the correct slot
|
||||
if (isDetachable)
|
||||
{
|
||||
detachable.push(_varAttrs[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
remaining.push(_varAttrs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
"detachable": detachable,
|
||||
"remaining": remaining
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes to DOM code for all widgets in the "remaining" slot
|
||||
*/
|
||||
_stripTemplateRow: function(_rowTemplate) {
|
||||
_rowTemplate.placeholders = [];
|
||||
|
||||
for (var i = 0; i < _rowTemplate.seperated.remaining.length; i++)
|
||||
{
|
||||
var entry = _rowTemplate.seperated.remaining[i];
|
||||
|
||||
// Issue a warning - widgets which do not implement et2_IDOMNode
|
||||
// are very slow
|
||||
et2_debug("warn", "Non-clonable widget in dataview row - this " +
|
||||
"might be slow", entry);
|
||||
|
||||
// Set the placeholder for the entry to null
|
||||
entry.placeholder = null;
|
||||
|
||||
// Get the outer DOM-Node of the widget
|
||||
if (entry.widget.implements(et2_IDOMNode))
|
||||
{
|
||||
var node = entry.widget.getDOMNode(entry.widget);
|
||||
|
||||
if (node.parentNode)
|
||||
{
|
||||
// Get the parent node and replace the node with a placeholder
|
||||
entry.placeholder = document.createElement("span");
|
||||
node.parentNode.replaceChild(entry.placeholder, node);
|
||||
_rowTemplate.placeholders.push({
|
||||
"widget": entry.widget,
|
||||
"func": this._compileDOMAccessFunc(_rowTemplate.row,
|
||||
entry.placeholder)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_nodeIndex: function(_node) {
|
||||
for (var i = 0; i < _node.parentNode.childNodes.length; i++)
|
||||
{
|
||||
if (_node.parentNode.childNodes[i] == _node)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a function which does a relative access on the given DOM-Node
|
||||
*/
|
||||
_compileDOMAccessFunc: function(_root, _target) {
|
||||
function recordPath(_root, _target, _path)
|
||||
{
|
||||
if (typeof _path == "undefined")
|
||||
{
|
||||
_path = [];
|
||||
}
|
||||
|
||||
if (_root != _target)
|
||||
{
|
||||
// Get the index of _target in its parent node
|
||||
var idx = this._nodeIndex(_target);
|
||||
if (idx >= 0)
|
||||
{
|
||||
// Add the access selector
|
||||
_path.unshift("childNodes[" + idx + "]");
|
||||
|
||||
// Record the remaining path
|
||||
return recordPath.call(this, _root, _target.parentNode, _path);
|
||||
}
|
||||
|
||||
throw("Internal error while compiling DOM access function.");
|
||||
}
|
||||
else
|
||||
{
|
||||
_path.unshift("_node");
|
||||
return "return " + _path.join(".") + ";";
|
||||
}
|
||||
}
|
||||
|
||||
return new Function("_node", recordPath.call(this, _root, _target));
|
||||
},
|
||||
|
||||
/**
|
||||
* Builds relative paths to the DOM-Nodes and compiles fast-access functions
|
||||
*/
|
||||
_buildNodeAccessFuncs: function(_rowTemplate) {
|
||||
for (var i = 0; i < _rowTemplate.seperated.detachable.length; i++)
|
||||
{
|
||||
var entry = _rowTemplate.seperated.detachable[i];
|
||||
|
||||
// Get all needed nodes from the widget
|
||||
var nodes = entry.widget.getDetachedNodes();
|
||||
var nodeFuncs = entry.nodeFuncs = new Array(nodes.length);
|
||||
|
||||
// Record the path to each DOM-Node
|
||||
for (var j = 0; j < nodes.length; j++)
|
||||
{
|
||||
nodeFuncs[i] = this._compileDOMAccessFunc(_rowTemplate.row,
|
||||
nodes[j]);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates the data row prototype
|
||||
*/
|
||||
setDataRowTemplate: function(_widgets, _rootWidget) {
|
||||
// Copy the root widget
|
||||
this._rootWidget = _rootWidget;
|
||||
|
||||
// Create the base row
|
||||
var row = this.getPrototype("default");
|
||||
|
||||
// Copy the row template
|
||||
var rowTemplate = {
|
||||
"row": row[0],
|
||||
"widgets": _widgets,
|
||||
"root": _rootWidget,
|
||||
"seperated": null
|
||||
};
|
||||
|
||||
// Create the row widget and insert the given widgets into the row
|
||||
var rowWidget = new et2_dataview_rowWidget(row[0]);
|
||||
rowWidget.createWidgets(_widgets);
|
||||
|
||||
// Get the set containing all variable attributes
|
||||
var variableAttributes = this._getVariableAttributeSet(rowWidget);
|
||||
|
||||
// Filter out all widgets which do not implement the et2_IDetachedDOM
|
||||
// interface or do not support all attributes listed in the et2_IDetachedDOM
|
||||
// interface. A warning is issued for all those widgets as they heavily
|
||||
// degrade the performance of the widgets
|
||||
var seperated = rowTemplate.seperated =
|
||||
this._seperateWidgets(variableAttributes);
|
||||
|
||||
// Remove all DOM-Nodes of all widgets inside the "remaining" slot from
|
||||
// the row-template, then build the access functions for the detachable
|
||||
// widgets
|
||||
this._stripTemplateRow(rowTemplate);
|
||||
this._buildNodeAccessFuncs(rowTemplate);
|
||||
|
||||
this._prototypes["dataRow"] = row;
|
||||
this._template = rowTemplate;
|
||||
},
|
||||
|
||||
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);
|
||||
// Insert the widgets into the row which do not provide the functions
|
||||
// to set the _data directly
|
||||
var rowWidget = null;
|
||||
if (this._template.seperated.remaining.length > 0)
|
||||
{
|
||||
// Create the row widget
|
||||
var rowWidget = new et2_dataview_rowTemplateWidget(this._rootWidget,
|
||||
_row[0]);
|
||||
|
||||
// Let the row widget create the widgets
|
||||
rowWidget.createWidgets(mgrs, this._dataRowTemplate);
|
||||
// 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._template.placeholders);
|
||||
}
|
||||
|
||||
// Update the content of all other widgets
|
||||
for (var i = 0; i < this._template.seperated.detachable.length; i++)
|
||||
{
|
||||
var entry = this._template.seperated.detachable[i];
|
||||
|
||||
// Parse the attribute expressions
|
||||
var data = {};
|
||||
for (var j = 0; j < entry.data.length; j++)
|
||||
{
|
||||
var set = entry.data[i];
|
||||
data[set.attribute] = set.expression + " for " + _idx; // TODO: Parsing of the expression
|
||||
}
|
||||
|
||||
// Retrieve all DOM-Nodes
|
||||
var nodes = new Array(entry.nodeFuncs.length);
|
||||
for (var j = 0; j < nodes.length; j++)
|
||||
{
|
||||
// Use the previously compiled node function to get the node
|
||||
// from the entry
|
||||
nodes[j] = entry.nodeFuncs[j](_row[0]);
|
||||
}
|
||||
|
||||
// Call the setDetachedAttributes function
|
||||
entry.widget.setDetachedAttributes(nodes, data);
|
||||
}
|
||||
|
||||
return rowWidget;
|
||||
},
|
||||
@ -121,9 +430,9 @@ var et2_dataview_rowProvider = Class.extend({
|
||||
|
||||
var et2_dataview_rowWidget = et2_widget.extend(et2_IDOMNode, {
|
||||
|
||||
init: function(_parent, _row) {
|
||||
init: function(_row) {
|
||||
// Call the parent constructor with some dummy attributes
|
||||
this._super(_parent, {"id": "", "type": "rowWidget"});
|
||||
this._super(null, {"id": "", "type": "rowWidget"});
|
||||
|
||||
// Initialize some variables
|
||||
this._widgets = [];
|
||||
@ -136,11 +445,7 @@ var et2_dataview_rowWidget = et2_widget.extend(et2_IDOMNode, {
|
||||
* 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;
|
||||
|
||||
createWidgets: function(_widgets) {
|
||||
// Clone the given the widgets with this element as parent
|
||||
this._widgets = new Array(_widgets.length);
|
||||
for (var i = 0; i < _widgets.length; i++)
|
||||
@ -154,19 +459,65 @@ var et2_dataview_rowWidget = et2_widget.extend(et2_IDOMNode, {
|
||||
* 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
|
||||
return this._row.childNodes[i].childNodes[0]; // Return the i-th td tag
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
var et2_dataview_rowTemplateWidget = et2_widget.extend(et2_IDOMNode, {
|
||||
|
||||
init: function(_mgrs, _row) {
|
||||
// Call the parent constructor with some dummy attributes
|
||||
this._super(null, {"id": "", "type": "rowTemplateWidget"});
|
||||
|
||||
// Copy the managers - do not use "setArrayMgrs" here
|
||||
this._mgrs = _mgrs;
|
||||
this._row = _row;
|
||||
|
||||
// Clone the widgets inside the placeholders array
|
||||
this._widgets = [];
|
||||
},
|
||||
|
||||
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;
|
||||
|
||||
this._widgets = new Array(_widgets.length);
|
||||
for (var i = 0; i < _widgets.length; i++)
|
||||
{
|
||||
this._row.childNodes[0].childNodes[0];
|
||||
|
||||
this._widgets[i] = {
|
||||
"widget": _widgets[i].widget.clone(this),
|
||||
"node": _widgets[i].func(this._row)
|
||||
};
|
||||
this._widgets[i].widget.loadingFinished();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the column node for the given sender
|
||||
*/
|
||||
getDOMNode: function(_sender) {
|
||||
|
||||
for (var i = 0; i < this._widgets.length; i++)
|
||||
{
|
||||
if (this._widgets[i].widget == _sender)
|
||||
{
|
||||
return this._widgets[i].node;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -20,7 +20,7 @@
|
||||
/**
|
||||
* Class which implements the "description" XET-Tag
|
||||
*/
|
||||
var et2_description = et2_baseWidget.extend({
|
||||
var et2_description = et2_baseWidget.extend([et2_IDetachedDOM], {
|
||||
|
||||
attributes: {
|
||||
"value": {
|
||||
@ -94,26 +94,27 @@ var et2_description = et2_baseWidget.extend({
|
||||
this.span.attr("for", this.options["for"]);
|
||||
}
|
||||
|
||||
et2_insertLinkText(this._parseText(), this.span[0], this.options.extra_link_target);
|
||||
et2_insertLinkText(this._parseText(this.options.value), this.span[0],
|
||||
this.options.extra_link_target);
|
||||
|
||||
this.setDOMNode(this.span[0]);
|
||||
},
|
||||
|
||||
_parseText: function() {
|
||||
_parseText: function(_value) {
|
||||
if (this.options.href)
|
||||
{
|
||||
return [{
|
||||
"href": this.options.href,
|
||||
"text": this.options.value
|
||||
"text": _value
|
||||
}];
|
||||
}
|
||||
else if (this.options.activate_links)
|
||||
{
|
||||
return et2_activateLinks(this.options.value);
|
||||
return et2_activateLinks(_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return [this.options.value];
|
||||
return [_value];
|
||||
}
|
||||
},
|
||||
|
||||
@ -122,8 +123,30 @@ var et2_description = et2_baseWidget.extend({
|
||||
|
||||
this.span.toggleClass("et2_bold", _value.indexOf("b") >= 0);
|
||||
this.span.toggleClass("et2_italic", _value.indexOf("i") >= 0);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Code for implementing et2_IDetachedDOM
|
||||
*/
|
||||
|
||||
getDetachedAttributes: function(_attrs)
|
||||
{
|
||||
_attrs.push("value");
|
||||
},
|
||||
|
||||
getDetachedNodes: function()
|
||||
{
|
||||
return [this.span[0]];
|
||||
},
|
||||
|
||||
setDetachedAttributes: function(_nodes, _values)
|
||||
{
|
||||
if (typeof _values["value"] != "undefined")
|
||||
{
|
||||
et2_insertLinkText(this._parseText(_values["value"]), _nodes[0],
|
||||
this.options.extra_link_target);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
et2_register_widget(et2_description, ["description", "label"]);
|
||||
|
@ -63,69 +63,19 @@
|
||||
<nextmatch-sortheader label="last changed" id="info_datemodified" options="DESC"/>
|
||||
</row>
|
||||
<row class="$row_cont[info_cat] $row_cont[class]" valign="top">
|
||||
<hbox align="center" options="5">
|
||||
<image label="$row_cont[info_type]" src="${row}[info_type]"/>
|
||||
<button statustext="Change the status of an entry, eg. close it" label="$row_cont[info_status_label]" id="edit_status[$row_cont[info_id]]" onclick="window.open(egw::link('/index.php','menuaction=infolog.infolog_ui.edit&info_id=$row_cont[info_id]'),'_blank','dependent=yes,width=750,height=600,scrollbars=yes,status=yes'); return false;" image="$row_cont[info_status_label]" ro_image="$row_cont[info_status_label]"/>
|
||||
<button statustext="Change the status of an entry, eg. close it" label="$row_cont[info_percent]" id="edit_percent[$row_cont[info_id]]" onclick="window.open(egw::link('/index.php','menuaction=infolog.infolog_ui.edit&info_id=$row_cont[info_id]'),'_blank','dependent=yes,width=750,height=600,scrollbars=yes,status=yes'); return false;" image="$row_cont[info_percent]"/>
|
||||
<image label="$row_cont[info_percent2]" src="{$row}[info_percent2]" onclick="window.open(egw::link('/index.php','menuaction=infolog.infolog_ui.edit&info_id=$row_cont[info_id]'),'_blank','dependent=yes,width=750,height=600,scrollbars=yes,status=yes'); return false;"/>
|
||||
</hbox>
|
||||
<vbox options="0,0" class="fullWidth">
|
||||
<link label="%s $row_cont[info_addr]" id="${row}[info_link]" options="b"/>
|
||||
<hbox options="0,0">
|
||||
<description id="${row}[info_subject]" no_lang="1" class="$row_cont[sub_class]"/>
|
||||
<description align="right" id="{$row}[info_number]" no_lang="1" class="infoId"/>
|
||||
</hbox>
|
||||
<box class="infoDes">
|
||||
<description id="${row}[info_des]" no_lang="1" options=",,1"/>
|
||||
</box>
|
||||
<link-string id="${row}[filelinks]"/>
|
||||
</vbox>
|
||||
<customfields-list id="$row" class="customfields"/>
|
||||
<menulist>
|
||||
<menupopup type="select-cat" id="${row}[info_cat]" readonly="true"/>
|
||||
</menulist>
|
||||
<vbox cols="1" rows="3" options="0,0,1">
|
||||
<date-time id="${row}[info_startdate]" readonly="true" options=",8" class="fixedHeight"/>
|
||||
<date id="${row}[info_enddate]" readonly="true" class="$row_cont[end_class] fixedHeight"/>
|
||||
<date-time id="${row}[info_datecompleted]" readonly="true" class="fixedHeight"/>
|
||||
</vbox>
|
||||
<vbox cols="1" rows="3" options="0,0">
|
||||
<hbox readonly="true">
|
||||
<hbox readonly="true" options="1,0">
|
||||
<date-duration id="${row}[info_used_time]" readonly="true" options="@duration_format"/>
|
||||
<date-duration id="${row}[info_sum_timesheets]" readonly="true" options="@duration_format" class="timesheet"/>
|
||||
</hbox>
|
||||
<description/>
|
||||
</hbox>
|
||||
<date-duration id="${row}[info_planned_time]" readonly="true" options="@duration_format" span="all" class="planned"/>
|
||||
</vbox>
|
||||
<vbox cols="1" rows="3" options="0,0">
|
||||
<hbox id="r_used_time" options="1,0">
|
||||
<image label="Times" src="timesheet"/>
|
||||
<date-duration id="${row}[info_used_time]" readonly="true" options="@duration_format"/>
|
||||
<date-duration id="${row}[info_sum_timesheets]" readonly="true" options="@duration_format" class="timesheet"/>
|
||||
</hbox>
|
||||
<hbox id="planified" options="1,0">
|
||||
<image label="planned time" src="k_alarm.png"/>
|
||||
<date-duration id="${row}[info_planned_time]" readonly="true" options="@duration_format" span="all" class="planned"/>
|
||||
</hbox>
|
||||
<hbox id="replanified" options="1,0">
|
||||
<image label="Re-planned time" src="agt_reload.png"/>
|
||||
<date-duration id="${row}[info_replanned_time]" readonly="true" options="@duration_format" span="all" class="replanned"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
<vbox options="0,0">
|
||||
<menulist>
|
||||
<menupopup type="select-account" id="${row}[info_owner]" readonly="true"/>
|
||||
</menulist>
|
||||
<listbox type="select-account" id="${row}[info_responsible]" readonly="true" rows="5"/>
|
||||
</vbox>
|
||||
<vbox options="0" orient="0">
|
||||
<date-time id="${row}[info_datemodified]" readonly="true"/>
|
||||
<menulist>
|
||||
<menupopup type="select-account" id="${row}[info_modifier]" readonly="true"/>
|
||||
</menulist>
|
||||
<vbox>
|
||||
<description value="Dynamic description tag:" />
|
||||
<description value="${row}" />
|
||||
<button label="This is a button" />
|
||||
</vbox>
|
||||
<description value="test" />
|
||||
<description value="test" />
|
||||
<description value="test" />
|
||||
<description value="test" />
|
||||
<description value="test" />
|
||||
<description value="test" />
|
||||
<description value="test" />
|
||||
<description value="test2" />
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
|
Loading…
Reference in New Issue
Block a user