diff --git a/etemplate/js/et2_core_arrayMgr.js b/etemplate/js/et2_core_arrayMgr.js index 7fc6623dd3..8285d08f77 100644 --- a/etemplate/js/et2_core_arrayMgr.js +++ b/etemplate/js/et2_core_arrayMgr.js @@ -61,14 +61,14 @@ var et2_arrayMgr = Class.extend({ return this; }, - getValueForID : function(_id) { +/* getValueForID : function(_id) { if (typeof this.data[_id] != "undefined") { return this.data[_id]; } return null; - }, + },*/ /** * Returns the path to this content array manager perspective as an array @@ -306,7 +306,6 @@ 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); } diff --git a/etemplate/js/et2_core_common.js b/etemplate/js/et2_core_common.js index 5a13119dd4..d336f769c6 100644 --- a/etemplate/js/et2_core_common.js +++ b/etemplate/js/et2_core_common.js @@ -335,6 +335,32 @@ function et2_arrayValues(_arr) return result; } +/** + * Equivalent to the PHP array_keys function + */ +function et2_arrayKeys(_arr) +{ + var result = []; + for (var key in _arr) + { + result.push(key); + } + + return result; +} + +function et2_arrayIntKeys(_arr) +{ + var result = []; + for (var key in _arr) + { + result.push(parseInt(key)); + } + + return result; +} + + /** * Equivalent to the PHP substr function, partly take from phpjs, licensed under * the GPL. diff --git a/etemplate/js/et2_core_inputWidget.js b/etemplate/js/et2_core_inputWidget.js index d6dfda1bce..fc8f8fe535 100644 --- a/etemplate/js/et2_core_inputWidget.js +++ b/etemplate/js/et2_core_inputWidget.js @@ -80,7 +80,7 @@ var et2_inputWidget = et2_valueWidget.extend(et2_IInput, { // Check whether an validation error entry exists if (this.id) { - var val = this.getArrayMgr("validation_errors").getValueForID(this.id); + var val = this.getArrayMgr("validation_errors").getEntry(this.id); if (val) { _attrs["validation_error"] = val; diff --git a/etemplate/js/et2_core_interfaces.js b/etemplate/js/et2_core_interfaces.js index 29370f9101..3a522dcd23 100644 --- a/etemplate/js/et2_core_interfaces.js +++ b/etemplate/js/et2_core_interfaces.js @@ -119,4 +119,3 @@ var et2_IDetachedDOM = new Interface({ }); - diff --git a/etemplate/js/et2_core_phpExpressionCompiler.js b/etemplate/js/et2_core_phpExpressionCompiler.js index 5db77f9583..6f2a688739 100644 --- a/etemplate/js/et2_core_phpExpressionCompiler.js +++ b/etemplate/js/et2_core_phpExpressionCompiler.js @@ -343,12 +343,14 @@ } var parts = []; + var hasString = false; for (var i = 0; i < _string.length; i++) { var part = _string[i]; if (typeof part == "string") { + hasString = true; // Escape all "'" and "\" chars and add the string to the parts array parts.push("'" + part.replace(/\\/g, "\\\\").replace(/'/g, "\\'") + "'"); } @@ -358,7 +360,7 @@ } } - if (parts.length == 0) + if (!hasString) // Force the result to be of the type string { parts.push('""'); } @@ -433,6 +435,7 @@ test("${row}[title]", "10[title]"); test("{$row_cont[title]}", "Hello World!"); test('{$cont["$row"][\'title\']}', "Hello World!"); + test("$row_cont[${row}[title]]"); test("\\\\", "\\"); test("", ""); })();*/ diff --git a/etemplate/js/et2_core_valueWidget.js b/etemplate/js/et2_core_valueWidget.js index e89bd1f4a8..0e4d67c01e 100644 --- a/etemplate/js/et2_core_valueWidget.js +++ b/etemplate/js/et2_core_valueWidget.js @@ -41,7 +41,7 @@ var et2_valueWidget = et2_baseWidget.extend({ // Set the value for this element var contentMgr = this.getArrayMgr("content"); if (contentMgr != null) { - var val = contentMgr.getValueForID(this.id); + var val = contentMgr.getEntry(this.id); if (val !== null) { _attrs["value"] = val; diff --git a/etemplate/js/et2_core_widget.js b/etemplate/js/et2_core_widget.js index 27f36f3613..a86ef7976a 100644 --- a/etemplate/js/et2_core_widget.js +++ b/etemplate/js/et2_core_widget.js @@ -510,7 +510,12 @@ var et2_widget = Class.extend({ // Apply the content of the modifications array if (this.id) { - var data = this.getArrayMgr("modifications").getValueForID(this.id); + if (typeof this.id != "string") + { + console.log(this.id); + } + + var data = this.getArrayMgr("modifications").getEntry(this.id); if (data instanceof Object) { for (var key in data) @@ -769,7 +774,7 @@ var et2_widget = Class.extend({ this._template_application = this.getParent().getTemplateApp(); return this._template_application; } - return null; + return "phpgwapi"; } }); diff --git a/etemplate/js/et2_dataview_interfaces.js b/etemplate/js/et2_dataview_interfaces.js index f3084f3f83..6c4fc960ea 100644 --- a/etemplate/js/et2_dataview_interfaces.js +++ b/etemplate/js/et2_dataview_interfaces.js @@ -33,3 +33,49 @@ var et2_dataview_IViewRange = new Interface({ setViewRange: function(_range) {} }); + +/** + * Interface which objects have to implement, that want to act as low level + * datasource. + */ +var et2_IRowFetcher = new Interface({ + + /** + * @param _fetchList is an array consisting of objects whith the entries + * "startIdx" and "count" + * @param _callback is the callback which is called when the data is ready + * (may be immediately or deferred). The callback has the following + * signature: + * function (_rows) + * where _rows is an associative array which contains the data for that row. + * @param _context is the context in which the callback should run. + */ + getRows: function(_fetchList, _callback, _context) {} + +}); + +/** + * Interface the data provider has to implement + */ +var et2_IDataProvider = new Interface({ + + /** + * Returns the total count of grid elements + */ + getCount: function() {}, + + /** + * Registers the given dataRow for the given index. Calls _dataRow.updateData + * as soon as data is available for that row. + */ + registerDataRow: function(_dataRow, _idx) {}, + + /** + * Stops calling _dataRow.updateData for the dataRow registered for the given + * index. + */ + unregisterDataRow: function(_idx) {} + +}); + + diff --git a/etemplate/js/et2_dataview_model_dataProvider.js b/etemplate/js/et2_dataview_model_dataProvider.js index 2a3734194c..591ec807a6 100644 --- a/etemplate/js/et2_dataview_model_dataProvider.js +++ b/etemplate/js/et2_dataview_model_dataProvider.js @@ -13,49 +13,234 @@ "use strict" /*egw:uses - et2_inheritance; + et2_core_inheritance; + et2_core_common; et2_dataview_interfaces; */ -var et2_dataview_dataProvider = Class.extend({ +var et2_dataview_dataProvider = Class.extend(et2_IDataProvider, { - init: function() { - this.updateQueue = 0; + /** + * Creates this instance of the data provider. + */ + init: function(_source, _total) { + this._source = _source; + this._total = _total; + + this._registeredRows = {}; + + this._data = {}; + this._dataCount = 0; + + this._queue = {}; + this._queueSize = 0; + + this._stepSize = 25; // Count of elements which is loaded at once + this._maxCount = 1000; // Maximum count before the elements are cleaned up + + var self = this; + this._cleanupInterval = window.setInterval(function() {self._cleanup()}, + 10 * 1000); + this._queueFlushTimeout = null; }, + destroy: function() { + // Destroy the cleanup timer callback + window.clearInterval(this._cleanupInterval); + + // Destroy the _queueFlushTimeout + if (this._queueFlushTimeout !== null) + { + window.clearTimeout(this._queueFlushTimeout); + } + }, + + /** + * Returns the total count + */ getCount: function() { - return 10000; + return this._total; }, registerDataRow: function(_dataRow, _idx) { -/* var row = { - "type": "dataRow", - "data": { - "ts_title": "Row " + _idx - } - }; + // Make sure _idx is a int + _idx = parseInt(_idx); - // Get a random value which is used to simulate network latency and time - // it needs to load the data. - var rnd = Math.round(Math.random() * 1000); + et2_debug("log", "--> registering row", _idx); - if (rnd < 200) + if (typeof this._registeredRows[_idx] != "undefined") { - _dataRow.updateData(row); + et2_debug("warn", "Overriding data row for index " + _idx); } - window.setTimeout(function() {_dataRow.updateData(row); }, - Math.round(rnd / 2));*/ + // Associate the given data row with that index + this._registeredRows[_idx] = _dataRow; - - // 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); - _dataRow.updateData({"content": {"ts_title": "Idx: " + _idx}}); + // Check whether an entry exists in the data array - if yes, call the + // request immediately + if (typeof this._data[_idx] != "undefined") + { + this._callUpdateData(_idx); + } + else + { + this._queueIndex(_idx); + } }, - unregisterDataRow: function(_dataRow) { - // + unregisterDataRow: function(_idx) { + // Make sure _idx is a int + _idx = parseInt(_idx); + + et2_debug("log", "<-- unregistering row", _idx); + + delete(this._data[_idx]); + }, + + /* ---- PRIVATE FUNCTIONS ---- */ + + _queueIndex: function(_idx) { + // Mark the index as queued + if (typeof this._queue[_idx] == "undefined") + { + this._queue[_idx] = true; + this._queueSize++; + } + + if (this._queueSize > this._stepSize) + { + this._flushQueue(); + } + else + { + // (Re)start the queue flush timer + var self = this; + this._stopFlushTimer(); + this._queueFlushTimeout = window.setTimeout(function() { + self._queueFlushTimeout = null; + self._flushQueue(); + }, 50); + } + }, + + _flushQueue: function() { + // Stop the flush timer if it is still active + this._stopFlushTimer(); + + // Mark all elements in a radius of this._stepSize / 2 + var marked = {}; + var r = Math.floor(this._stepSize / 2); + for (var key in this._queue) + { + key = parseInt(key); + + var b = Math.max(0, key - r); + var t = Math.min(key + r, this._total - 1); + for (var i = b; i <= t; i ++) + { + marked[i] = true; + } + } + + // Reset the queue + this._queue = {}; + this._queueSize = 0; + + // Create a list with start indices and counts + var fetchList = []; + var entry = null; + var last = 0; + + // Get the int keys and sort the array numeric + var arr = et2_arrayIntKeys(marked).sort(function(a,b){return a > b ? 1 : (a == b ? 0 : -1)}); + + for (var i = 0; i < arr.length; i++) + { + if (i == 0 || arr[i] - last > 1) + { + if (entry) + { + fetchList.push(entry); + } + entry = { + "startIdx": arr[i], + "count": 1 + }; + } + else + { + entry.count++; + } + + last = arr[i]; + } + + if (entry) + { + fetchList.push(entry); + } + + // Call the "getRows" callback + this._source.getRows(fetchList, this._receiveData, this); + }, + + _receiveData: function(_data) { + var time = (new Date).getTime(); + + for (var key in _data) + { + // Make sure the key is a int + key = parseInt(key); + + // Copy the data for the given index + this._data[key] = { + "data": _data[key], + "timestamp": time + }; + + // Update the row associated to the index + this._callUpdateData(key); + } + }, + + _stopFlushTimer: function() { + // Stop the queue flush timer + if (this._queueFlushTimeout !== null) + { + window.clearTimeout(this._queueFlushTimeout); + } + }, + + _callUpdateData: function(_idx) { + if (typeof this._registeredRows[_idx] != "undefined") + { +// this._data[idx].timestamp = (new Date).getTime(); + this._registeredRows[_idx].updateData({ + "content": this._data[_idx].data + }); + } + }, + + _cleanup: function() { + // Delete all data rows which have not been accessed for more than + // "delta" ms (5 minutes) - this method does not ensure that _dataCount + // gets below _maxCount! + var delta = 5 * 60 * 1000; + var now = (new Date).getTime(); + + if (this._dataCount > this._maxCount) + { + for (var key in this._data) + { + var entry = this._data[key]; + + if (now - entry.timestamp > delta) + { + delete(this._data[key]); + this._dataCount--; + } + } + } } }); diff --git a/etemplate/js/et2_dataview_view_partitionNode.js b/etemplate/js/et2_dataview_view_partitionNode.js index 9f5a532c59..43203a52b4 100644 --- a/etemplate/js/et2_dataview_view_partitionNode.js +++ b/etemplate/js/et2_dataview_view_partitionNode.js @@ -101,6 +101,12 @@ var et2_dataview_partitionNode = Class.extend([et2_dataview_IPartitionHeight, // Invalidate the parent node if (this._parent) { + // Invalidate the neighbor node + if (this._pidx < this._parent._children.length - 1) + { + this._parent._children[this._pidx + 1].invalidate(); + } + this._parent.invalidate(origin ? this : _sender); } } diff --git a/etemplate/js/et2_dataview_view_row.js b/etemplate/js/et2_dataview_view_row.js index d2e53f60d5..fc0c59626b 100644 --- a/etemplate/js/et2_dataview_view_row.js +++ b/etemplate/js/et2_dataview_view_row.js @@ -23,6 +23,7 @@ var et2_dataview_row = et2_dataview_container.extend(et2_dataview_IDataRow, { this._super(_dataProvider, _rowProvider, _invalidationElem); this._avgHeight = _avgHeight; + this._idx = null; this.rowWidget = null; this.hasAvgHeight = false; @@ -37,7 +38,10 @@ var et2_dataview_row = et2_dataview_container.extend(et2_dataview_IDataRow, { destroy: function() { // Unregister the row from the data provider - this.dataProvider.unregisterDataRow(this); + if (this._idx !== null) + { + this.dataProvider.unregisterDataRow(this._idx); + } // Free the row widget first, if it has been set if (this.rowWidget) diff --git a/etemplate/js/et2_dataview_view_rowProvider.js b/etemplate/js/et2_dataview_view_rowProvider.js index 978947db32..5a9bbbfca4 100644 --- a/etemplate/js/et2_dataview_view_rowProvider.js +++ b/etemplate/js/et2_dataview_view_rowProvider.js @@ -76,17 +76,6 @@ var et2_dataview_rowProvider = Class.extend({ "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) { @@ -166,13 +155,22 @@ var et2_dataview_rowProvider = Class.extend({ // "detached" mode var supportedAttrs = []; widget.getDetachedAttributes(supportedAttrs); + supportedAttrs.push("id"); isDetachable = true; - for (var j = 0; j < _varAttrs[i].data.length && isDetachable; j++) + for (var j = 0; j < _varAttrs[i].data.length/* && isDetachable*/; j++) { var data = _varAttrs[i].data[j]; - isDetachable &= supportedAttrs.indexOf(data.attribute) != -1; + var supportsAttr = supportedAttrs.indexOf(data.attribute) != -1; + + if (!supportsAttr) + { + et2_debug("warn", "et2_IDetachedDOM widget " + + widget._type + " does not support " + data.attribute); + } + + isDetachable &= supportsAttr; } } @@ -294,7 +292,7 @@ var et2_dataview_rowProvider = Class.extend({ // Record the path to each DOM-Node for (var j = 0; j < nodes.length; j++) { - nodeFuncs[i] = this._compileDOMAccessFunc(_rowTemplate.row, + nodeFuncs[j] = this._compileDOMAccessFunc(_rowTemplate.row, nodes[j]); } } @@ -320,7 +318,7 @@ var et2_dataview_rowProvider = Class.extend({ }; // Create the row widget and insert the given widgets into the row - var rowWidget = new et2_dataview_rowWidget(row[0]); + var rowWidget = new et2_dataview_rowWidget(_rootWidget, row[0]); rowWidget.createWidgets(_widgets); // Get the set containing all variable attributes @@ -354,6 +352,18 @@ var et2_dataview_rowProvider = Class.extend({ var rowWidget = null; if (this._template.seperated.remaining.length > 0) { + // Transform the variable attributes + for (var i = 0; i < this._template.seperated.remaining.length; i++) + { + var entry = this._template.seperated.remaining[i]; + + for (var j = 0; j < entry.data.length; j++) + { + var set = entry.data[j]; + entry.widget.options[set.attribute] = mgrs["content"].expandName(set.expression); + } + } + // Create the row widget var rowWidget = new et2_dataview_rowTemplateWidget(this._rootWidget, _row[0]); @@ -371,7 +381,7 @@ var et2_dataview_rowProvider = Class.extend({ var data = {}; for (var j = 0; j < entry.data.length; j++) { - var set = entry.data[i]; + var set = entry.data[j]; data[set.attribute] = mgrs["content"].expandName(set.expression); } @@ -384,6 +394,13 @@ var et2_dataview_rowProvider = Class.extend({ nodes[j] = entry.nodeFuncs[j](_row[0]); } + // Set the array managers first + entry.widget._mgrs = mgrs; + if (typeof data.id != "undefined") + { + entry.widget.id = data.id; + } + // Call the setDetachedAttributes function entry.widget.setDetachedAttributes(nodes, data); } @@ -431,9 +448,9 @@ var et2_dataview_rowProvider = Class.extend({ var et2_dataview_rowWidget = et2_widget.extend(et2_IDOMNode, { - init: function(_row) { + init: function(_parent, _row) { // Call the parent constructor with some dummy attributes - this._super(null, {"id": "", "type": "rowWidget"}); + this._super(_parent, {"id": "", "type": "rowWidget"}); // Initialize some variables this._widgets = []; diff --git a/etemplate/js/et2_extension_nextmatch.js b/etemplate/js/et2_extension_nextmatch.js index e91b68af6d..3ea50d1b49 100644 --- a/etemplate/js/et2_extension_nextmatch.js +++ b/etemplate/js/et2_extension_nextmatch.js @@ -71,7 +71,7 @@ var et2_nextmatch = et2_DOMWidget.extend(et2_IResizeable, { // Create the data provider which cares about streaming the row data // efficiently to the rows - this.dataProvider = new et2_dataview_dataProvider(); + this.dataProvider = new et2_dataview_dataProvider(this, 100); // Create the outer grid container this.dataviewContainer = new et2_dataview_gridContainer(this.div, @@ -101,6 +101,26 @@ var et2_nextmatch = et2_DOMWidget.extend(et2_IResizeable, { }, this); }, + /** + * Get Rows callback + */ + getRows: function(_fetchList, _callback, _context) { + console.log("Nextmatch will fetch ", _fetchList); + // Create the entries: + var entries = {}; + for (var i = 0; i < _fetchList.length; i++) + { + var start = _fetchList[i].startIdx; + for (var j = 0; j < _fetchList[i].count; j++) + { + entries[start + j] = +{"info_id":"5","info_type":"email","info_from":"tracker","info_addr":"tracker","info_subject":"InfoLog grid view: problem with Opera; 'permission denied' while saving","info_des":"","info_owner":"5","info_responsible":[],"info_access":"public","info_cat":"0","info_datemodified":1307112528,"info_startdate":1306503000,"info_enddate":"0", "info_id_parent":"0","info_planned_time":"0","info_replanned_time":"0","info_used_time":"0","info_status":"done", "info_confirm":"not","info_modifier":"5","info_link_id":0,"info_priority":"1","pl_id":"0","info_price":null, "info_percent":"100%","info_datecompleted":1307112528,"info_location":"","info_custom_from":1, "info_uid":"infolog-5-18d12c7bf195f6b9d602e1fa5cde28f1","info_cc":"","caldav_name":"5.ics","info_etag":"0", "info_created":1307112528,"info_creator":"5","links":[],"info_anz_subs":0,"sub_class":"normal_done","info_link":{"title":"tracker"},"class":"rowNoClose rowNoCloseAll ","info_type_label":"E-Mail","info_status_label":"done","info_number":"5"} + } + } + + _callback.call(_context, entries); + }, + /** * Sorts the nextmatch widget by the given ID. * @@ -253,7 +273,6 @@ var et2_nextmatch = et2_DOMWidget.extend(et2_IResizeable, { /** * When the template attribute is set, the nextmatch widget tries to load * that template and to fetch the grid which is inside of it. It then calls - * _parseGrid in order to get the information for the column headers etc. */ set_template: function(_value) { if (!this.template) diff --git a/etemplate/js/et2_widget_description.js b/etemplate/js/et2_widget_description.js index 9598cdc5f5..807cf318a9 100644 --- a/etemplate/js/et2_widget_description.js +++ b/etemplate/js/et2_widget_description.js @@ -81,9 +81,6 @@ var et2_description = et2_baseWidget.extend([et2_IDetachedDOM], { init: function() { this._super.apply(this, arguments); - this.value = ""; - this.font_style = ""; - // Create the span/label tag which contains the label text this.span = $j(document.createElement(this.options["for"] ? "label" : "span")) .addClass("et2_label"); @@ -100,6 +97,20 @@ var et2_description = et2_baseWidget.extend([et2_IDetachedDOM], { this.setDOMNode(this.span[0]); }, + transformAttributes: function(_attrs) { + this._super.apply(arguments); + + if (this.id) + { + var val = this.getArrayMgr("content").getEntry(this.id); + + if (val) + { + _attrs["value"] = val; + } + } + }, + _parseText: function(_value) { if (this.options.href) { @@ -131,7 +142,7 @@ var et2_description = et2_baseWidget.extend([et2_IDetachedDOM], { getDetachedAttributes: function(_attrs) { - _attrs.push("value"); + _attrs.push("value", "class"); }, getDetachedNodes: function() @@ -141,11 +152,18 @@ var et2_description = et2_baseWidget.extend([et2_IDetachedDOM], { setDetachedAttributes: function(_nodes, _values) { + this.transformAttributes(_values); + if (typeof _values["value"] != "undefined") { et2_insertLinkText(this._parseText(_values["value"]), _nodes[0], this.options.extra_link_target); } + + if (typeof _values["class"] != "undefined") + { + this.set_class(_values["class"]); + } } }); diff --git a/etemplate/js/et2_widget_image.js b/etemplate/js/et2_widget_image.js index 063e4b51df..09d97fb4c9 100644 --- a/etemplate/js/et2_widget_image.js +++ b/etemplate/js/et2_widget_image.js @@ -14,13 +14,14 @@ /*egw:uses jquery.jquery; + et2_core_interfaces; et2_core_baseWidget; */ /** * Class which implements the "image" XET-Tag */ -var et2_image = et2_baseWidget.extend({ +var et2_image = et2_baseWidget.extend(/*et2_IDetachedDOM,*/ { attributes: { "src": { @@ -44,17 +45,31 @@ var et2_image = et2_baseWidget.extend({ this._super.apply(this, arguments); // Create the image or a/image tag - this.image = this.node = $j(document.createElement("img")); + var node = this.image = $j(document.createElement("img")); if(this.options.link) { - this.node = $j(document.createElement("a")); - this.image.appendTo(this.node); + this._node = $j(document.createElement("a")); + this.image.appendTo(node); } if(this.options["class"]) { - this.node.addClass(this.options["class"]); + node.addClass(this.options["class"]); + } + this.setDOMNode(node[0]); + }, + + transformAttributes: function(_attrs) { + this._super.apply(arguments); + + // Check to expand name + if (typeof _attrs["src"] != "undefined") + { + var src = this.getArrayMgr("content").getEntry(_attrs["src"]); + if (src) + { + _attrs["src"] = src; + } } - this.setDOMNode(this.node[0]); }, set_label: function(_value) { @@ -62,7 +77,7 @@ var et2_image = et2_baseWidget.extend({ this.options.label = _value; // label is NOT the alt attribute in eTemplate, but the title/tooltip this.image.attr("alt", _value); - this.image.set_statustext(_value); + this.set_statustext(_value); }, setValue: function(_value) { @@ -70,36 +85,69 @@ var et2_image = et2_baseWidget.extend({ this.set_src(_value); }, + percentagePreg: /^[0-9]+%$/, + set_src: function(_value) { if(!this.isInTree()) { return; } - // Check to expand name - if(_value.indexOf("$") != -1 || _value.indexOf("@") != -1) { - var contentMgr = this.getArrayMgr("content"); - if (contentMgr != null) { - var val = contentMgr.getValueForID(_value); - if (val !== null) - { - _value = val; - } - } - } this.options.src = _value; - // Get application to use from template ID - var appname = this.getTemplateApp(); - var src = egw.image(_value,appname || "phpgwapi"); - if(src ) + + // Check whether "src" is a percentage + if (this.percentagePreg.test(_value)) { - this.image.attr("src", src).show(); + this.getSurroundings().prependDOMNode(document.createTextNode(_value)); } else { - this.image.css("display","none"); + // Get application to use from template ID + var src = egw.image(_value, this.getTemplateApp()); + if(src) + { + this.image.attr("src", src).show(); + } + else + { + this.image.css("display","none"); + } } - } + }, + + /** + * Implementation of "et2_IDetachedDOM" for fast viewing in gridview + */ + + // Does currently not work for percentages, as the surroundings manager + // cannot opperate on other DOM-Nodes. + +/* getDetachedAttributes: function(_attrs) { + _attrs.push("src", "label"); + }, + + getDetachedNodes: function() { + return [this.node, this.image[0]]; + }, + + setDetachedAttributes: function(_nodes, _values) { + // Set the given DOM-Nodes + this.node = _nodes[0]; + this.image = $j(_nodes[1]); + + this.transformAttributes(_values); + + // Set the attributes + if (_values["src"]) + { + this.set_src(_values["src"]); + } + + if (_values["label"]) + { + this.set_label(_values["label"]); + } + }*/ }); et2_register_widget(et2_image, ["image"]); diff --git a/etemplate/js/et2_widget_link.js b/etemplate/js/et2_widget_link.js index 9b99735bb8..38f21a8698 100644 --- a/etemplate/js/et2_widget_link.js +++ b/etemplate/js/et2_widget_link.js @@ -118,7 +118,7 @@ var et2_link_to = et2_inputWidget.extend({ if (_attrs["select_options"] == null) { _attrs["select_options"] = this.getArrayMgr('content') - .getValueForID("options-" + this.id) + .getEntry("options-" + this.id) } // Default to an empty object diff --git a/etemplate/js/et2_widget_selectbox.js b/etemplate/js/et2_widget_selectbox.js index 891f26bdba..ae856eb256 100644 --- a/etemplate/js/et2_widget_selectbox.js +++ b/etemplate/js/et2_widget_selectbox.js @@ -77,14 +77,14 @@ var et2_selectbox = et2_inputWidget.extend({ this._super.apply(this, arguments); // Try to find the options inside the "sel-options" array - _attrs["select_options"] = this.getArrayMgr("sel_options").getValueForID(this.id); + _attrs["select_options"] = this.getArrayMgr("sel_options").getEntry(this.id); // Check whether the options entry was found, if not read it from the // content array. if (_attrs["select_options"] == null) { _attrs["select_options"] = this.getArrayMgr('content') - .getValueForID("options-" + this.id) + .getEntry("options-" + this.id) } // Default to an empty object diff --git a/etemplate/js/et2_widget_tabs.js b/etemplate/js/et2_widget_tabs.js index 39f16458c3..080b6f4579 100644 --- a/etemplate/js/et2_widget_tabs.js +++ b/etemplate/js/et2_widget_tabs.js @@ -64,7 +64,7 @@ var et2_tabbox = et2_DOMWidget.extend({ // Set the value for this element var contentMgr = this.getArrayMgr("content"); if (contentMgr != null) { - var val = contentMgr.getValueForID(this.id); + var val = contentMgr.getEntry(this.id); if (val !== null) { selected = val; @@ -72,7 +72,7 @@ var et2_tabbox = et2_DOMWidget.extend({ } contentMgr = this.getArrayMgr("readonlys"); if (contentMgr != null) { - var val = contentMgr.getValueForID(this.id); + var val = contentMgr.getEntry(this.id); if (val !== null) { hidden = val; diff --git a/etemplate/js/test/et2_test_nextmatch.xet b/etemplate/js/test/et2_test_nextmatch.xet index 0a1c786640..7b4e189061 100644 --- a/etemplate/js/test/et2_test_nextmatch.xet +++ b/etemplate/js/test/et2_test_nextmatch.xet @@ -63,19 +63,69 @@ - - - -