diff --git a/etemplate/inc/class.etemplate_widget_menupopup.inc.php b/etemplate/inc/class.etemplate_widget_menupopup.inc.php index 67c80ca2d7..eb1491816b 100644 --- a/etemplate/inc/class.etemplate_widget_menupopup.inc.php +++ b/etemplate/inc/class.etemplate_widget_menupopup.inc.php @@ -120,8 +120,8 @@ class etemplate_widget_menupopup extends etemplate_widget { $form_name = self::form_name($cname, $this->id); // += to keep further options set by app code - if (!isset(self::$request->sel_options[$form_name])) self::$request->sel_options[$form_name] = array(); - self::$request->sel_options[$form_name] += self::typeOptions($this->attrs['type'], $this->attrs['options']); + if (!is_array(self::$request->sel_options[$form_name])) self::$request->sel_options[$form_name] = array(); + self::$request->sel_options[$form_name] += (array)self::typeOptions($this->attrs['type'], $this->attrs['options']); } } diff --git a/etemplate/js/et2_baseWidget.js b/etemplate/js/et2_baseWidget.js index e5529b3f48..fef2c554b3 100644 --- a/etemplate/js/et2_baseWidget.js +++ b/etemplate/js/et2_baseWidget.js @@ -36,7 +36,8 @@ var et2_baseWidget = et2_DOMWidget.extend(et2_IAligned, { "statustext": { "name": "Tooltip", "type": "string", - "description": "Tooltip which is shown for this element" + "description": "Tooltip which is shown for this element", + "translate": true }, "align": { "name": "Align", diff --git a/etemplate/js/et2_button.js b/etemplate/js/et2_button.js index 419cd482de..c7be43be98 100644 --- a/etemplate/js/et2_button.js +++ b/etemplate/js/et2_button.js @@ -27,7 +27,8 @@ var et2_button = et2_baseWidget.extend(et2_IInput, { "label": { "name": "caption", "type": "string", - "description": "Label of the button" + "description": "Label of the button", + "translate": true }, "onclick": { diff --git a/etemplate/js/et2_description.js b/etemplate/js/et2_description.js index 9d3681ab76..4d253aff15 100644 --- a/etemplate/js/et2_description.js +++ b/etemplate/js/et2_description.js @@ -26,7 +26,8 @@ var et2_description = et2_baseWidget.extend({ "value": { "name": "Caption", "type": "string", - "description": "Displayed text" + "description": "Displayed text", + "translate": true }, /** @@ -50,7 +51,7 @@ var et2_description = et2_baseWidget.extend({ "description": "If set, URLs in the text are automatically replaced " + "by links" }, - "label_for": { + "for": { "name": "Label for widget", "type": "string", "description": "Marks the text as label for the given widget." @@ -73,7 +74,7 @@ var et2_description = et2_baseWidget.extend({ } }, - legacyOptions: ["font_style", "href", "activate_links", "label_for", + legacyOptions: ["font_style", "href", "activate_links", "for", "extra_link_target", "extra_link_popup", "extra_link_title"], init: function(_parent) { @@ -83,13 +84,13 @@ var et2_description = et2_baseWidget.extend({ this.font_style = ""; // Create the span/label tag which contains the label text - this.span = $j(document.createElement(this.options.label_for ? "label" : "span")) + this.span = $j(document.createElement(this.options["for"] ? "label" : "span")) .addClass("et2_label"); - if (this.options.label_for) + if (this.options["for"]) { // TODO: Get the real id of the widget in the doLoadingFinished method. - this.span.attr("for", this.options.label_for); + this.span.attr("for", this.options["for"]); } et2_insertLinkText(this._parseText(), this.span[0], this.options.extra_link_target); diff --git a/etemplate/js/et2_inputWidget.js b/etemplate/js/et2_inputWidget.js index 23170cf53d..79d6c28a39 100644 --- a/etemplate/js/et2_inputWidget.js +++ b/etemplate/js/et2_inputWidget.js @@ -56,7 +56,8 @@ var et2_inputWidget = et2_valueWidget.extend(et2_IInput, { "name": "Label", "default": "", "type": "string", - "description": "The label is displayed by default in front (for radiobuttons behind) each widget (if not empty). If you want to specify a different position, use a '%s' in the label, which gets replaced by the widget itself. Eg. '%s Name' to have the label Name behind a checkbox. The label can contain variables, as descript for name. If the label starts with a '@' it is replaced by the value of the content-array at this index (with the '@'-removed and after expanding the variables)." + "description": "The label is displayed by default in front (for radiobuttons behind) each widget (if not empty). If you want to specify a different position, use a '%s' in the label, which gets replaced by the widget itself. Eg. '%s Name' to have the label Name behind a checkbox. The label can contain variables, as descript for name. If the label starts with a '@' it is replaced by the value of the content-array at this index (with the '@'-removed and after expanding the variables).", + "translate": true }, "onchange": { "name": "onchange", @@ -97,10 +98,13 @@ var et2_inputWidget = et2_valueWidget.extend(et2_IInput, { this._super.apply(this, arguments); // Check whether an validation error entry exists - var val = this.getArrayMgr("validation_errors").getValueForID(this.id); - if (val) + if (this.id) { - _attrs["validation_error"] = val; + var val = this.getArrayMgr("validation_errors").getValueForID(this.id); + if (val) + { + _attrs["validation_error"] = val; + } } }, diff --git a/etemplate/js/et2_valueWidget.js b/etemplate/js/et2_valueWidget.js index ac6bde4a9a..193b020325 100644 --- a/etemplate/js/et2_valueWidget.js +++ b/etemplate/js/et2_valueWidget.js @@ -36,7 +36,7 @@ var et2_valueWidget = et2_baseWidget.extend({ transformAttributes: function(_attrs) { this._super.apply(this, arguments); - if (this.id != "") + if (this.id) { // Set the value for this element var contentMgr = this.getArrayMgr("content"); diff --git a/etemplate/js/et2_widget.js b/etemplate/js/et2_widget.js index c81de268cc..0ed87a2566 100644 --- a/etemplate/js/et2_widget.js +++ b/etemplate/js/et2_widget.js @@ -13,6 +13,7 @@ "use strict"; /*egw:uses + jsapi/egw; et2_xml; et2_common; et2_inheritance; @@ -107,6 +108,13 @@ var et2_widget = Class.extend({ "description": "Unique identifier of the widget" }, + "no_lang": { + "name": "No translation", + "type": "boolean", + "default": false, + "description": "If true, no translations are made for this widget" + }, + /** * Ignore the "span" property by default - it is read by the grid and * other widgets. @@ -189,12 +197,12 @@ var et2_widget = Class.extend({ { this.checkCreateNamespace(); } - - // Add all attributes hidden in the content arrays to the attributes - // parameter - this.transformAttributes(_attrs); } + // Add all attributes hidden in the content arrays to the attributes + // parameter + this.transformAttributes(_attrs); + // Create a local copy of the options object this.options = et2_cloneObject(_attrs); }, @@ -484,18 +492,35 @@ var et2_widget = Class.extend({ }, /** - * Apply the "modifications" to the element + * Apply the "modifications" to the element and translate attributes marked + * with "translate: true" */ transformAttributes: function(_attrs) { - var data = this.getArrayMgr("modifications").getValueForID(this.id); - if (data instanceof Object) + // Apply the content of the modifications array + if (this.id) { - for (var key in data) + var data = this.getArrayMgr("modifications").getValueForID(this.id); + if (data instanceof Object) { - if (!(data[key] instanceof Object)) + for (var key in data) { - _attrs[key] = data[key]; + if (!(data[key] instanceof Object)) + { + _attrs[key] = data[key]; + } + } + } + } + + // Translate the attributes + if (!_attrs["no_lang"]) + { + for (var key in _attrs) + { + if (typeof this.attributes[key] != "undefined" && this.attributes[key].translate) + { + _attrs[key] = egw.lang(_attrs[key]); } } } diff --git a/etemplate/js/test/test_xml.html b/etemplate/js/test/test_xml.html index 56fb53b831..8d78f3a41e 100644 --- a/etemplate/js/test/test_xml.html +++ b/etemplate/js/test/test_xml.html @@ -33,6 +33,7 @@ + diff --git a/etemplate/templates/default/app.css b/etemplate/templates/default/app.css index 8574c15eb5..830747080f 100644 --- a/etemplate/templates/default/app.css +++ b/etemplate/templates/default/app.css @@ -144,4 +144,3 @@ padding-right: 15px; } -