mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-01-13 17:38:28 +01:00
- Styled button a little bit
- Added test for textbox - Added baseWidget and inputWidget classes - Implemented attribute system - Implemented statustext as a test for the attribute system - Ported csv_split function to JS - Implemented system for the legacy options - Added function for iterating over the widget tree
This commit is contained in:
parent
858279ad84
commit
68c7a5550e
118
etemplate/js/et2_baseWidget.js
Normal file
118
etemplate/js/et2_baseWidget.js
Normal file
@ -0,0 +1,118 @@
|
||||
/**
|
||||
* eGroupWare eTemplate2 - JS Widget base class
|
||||
*
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @package etemplate
|
||||
* @subpackage api
|
||||
* @link http://www.egroupware.org
|
||||
* @author Andreas Stöckel
|
||||
* @copyright Stylite 2011
|
||||
* @version $Id: et2_widget.js 36021 2011-08-07 13:43:46Z igel457 $
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
/*egw:uses
|
||||
jquery.jquery;
|
||||
lib/tooltip.js;
|
||||
et2_widget;
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class which manages the DOM node itself. The simpleWidget class is derrived
|
||||
* from et2_DOMWidget and implements the getDOMNode function. A setDOMNode
|
||||
* function is provided, which attatches the given node to the DOM if possible.
|
||||
*/
|
||||
var et2_baseWidget = et2_DOMWidget.extend({
|
||||
|
||||
attributes: {
|
||||
"statustext": {
|
||||
"name": "Tooltip",
|
||||
"type": "string",
|
||||
"description": "Tooltip which is shown for this element"
|
||||
}
|
||||
},
|
||||
|
||||
init: function() {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
this.node = null;
|
||||
this.statustext = "";
|
||||
|
||||
this._tooltipElem = null;
|
||||
},
|
||||
|
||||
detatchFromDOM: function() {
|
||||
// Detach this node from the tooltip node
|
||||
if (this._tooltipElem)
|
||||
{
|
||||
egw_global_tooltip.unbindFromElement(this._tooltipElem);
|
||||
this._tooltipElem = null;
|
||||
}
|
||||
|
||||
this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
attachToDOM: function() {
|
||||
this._super.apply(this,arguments);
|
||||
|
||||
// Update the statustext
|
||||
this.set_statustext(this.statustext);
|
||||
},
|
||||
|
||||
setDOMNode: function(_node) {
|
||||
if (_node != this.node)
|
||||
{
|
||||
// Deatch the old node from the DOM
|
||||
this.detatchFromDOM();
|
||||
|
||||
// Set the new DOM-Node
|
||||
this.node = _node;
|
||||
|
||||
// Attatch the DOM-Node to the tree
|
||||
return this.attachToDOM();
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
getDOMNode: function() {
|
||||
return this.node;
|
||||
},
|
||||
|
||||
getTooltipElement: function() {
|
||||
return this.getDOMNode();
|
||||
},
|
||||
|
||||
set_statustext: function(_value) {
|
||||
// Don't execute the code below, if no tooltip will be attached/detached
|
||||
if (_value == "" && !this._tooltipElem)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.statustext = _value;
|
||||
|
||||
//Get the domnode the tooltip should be attached to
|
||||
var elem = $j(this.getTooltipElement());
|
||||
|
||||
if (elem)
|
||||
{
|
||||
//If a tooltip is already attached to the element, remove it first
|
||||
if (this._tooltipElem)
|
||||
{
|
||||
egw_global_tooltip.unbindFromElement(this._tooltipElem);
|
||||
this._tooltipElem = null;
|
||||
}
|
||||
|
||||
if (_value && _value != '')
|
||||
{
|
||||
egw_global_tooltip.bindToElement(elem, _value);
|
||||
this._tooltipElem = elem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
37
etemplate/js/et2_box.js
Normal file
37
etemplate/js/et2_box.js
Normal file
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* eGroupWare eTemplate2 - JS Box object
|
||||
*
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @package etemplate
|
||||
* @subpackage api
|
||||
* @link http://www.egroupware.org
|
||||
* @author Andreas Stöckel
|
||||
* @copyright Stylite 2011
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
/*egw:uses
|
||||
jquery.jquery;
|
||||
et2_baseWidget;
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class which implements the hbox and vbox tag
|
||||
*/
|
||||
var et2_box = et2_baseWidget.extend({
|
||||
|
||||
init: function(_parent, _type) {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
this.div = $j(document.createElement("div"))
|
||||
.addClass("et2_" + _type);
|
||||
|
||||
this.setDOMNode(this.div[0]);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
et2_register_widget(et2_box, ["hbox", "vbox"]);
|
||||
|
@ -14,20 +14,31 @@
|
||||
|
||||
/*egw:uses
|
||||
jquery.jquery;
|
||||
et2_widget;
|
||||
et2_baseWidget;
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class which implements the "button" XET-Tag
|
||||
*/
|
||||
var et2_button = et2_DOMWidget.extend({
|
||||
var et2_button = et2_baseWidget.extend({
|
||||
|
||||
attributes: {
|
||||
"label": {
|
||||
"name": "caption",
|
||||
"type": "string",
|
||||
"description": "Label of the button"
|
||||
}
|
||||
},
|
||||
|
||||
init: function(_parent) {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
this.label = "";
|
||||
|
||||
this.btn = $j(document.createElement("button"))
|
||||
.addClass("et2_button");
|
||||
|
||||
this._super.apply(this, arguments);
|
||||
this.label = "";
|
||||
this.setDOMNode(this.btn[0]);
|
||||
},
|
||||
|
||||
set_label: function(_value) {
|
||||
@ -37,10 +48,6 @@ var et2_button = et2_DOMWidget.extend({
|
||||
|
||||
this.btn.text(_value);
|
||||
}
|
||||
},
|
||||
|
||||
getDOMNode: function() {
|
||||
return this.btn[0];
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -10,27 +10,6 @@
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
function et2_debug(_level, _msg)
|
||||
{
|
||||
if (typeof console != "undefined")
|
||||
{
|
||||
if (_level == "log" && typeof console.log == "function")
|
||||
{
|
||||
console.log(_msg);
|
||||
}
|
||||
|
||||
if (_level == "warn" && typeof console.warn == "function")
|
||||
{
|
||||
console.warn(_msg);
|
||||
}
|
||||
|
||||
if (_level == "error" && typeof console.error == "function")
|
||||
{
|
||||
console.error(_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* IE Fix for array.indexOf
|
||||
*/
|
||||
@ -46,4 +25,302 @@ if (typeof Array.prototype.indexOf == "undefined")
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* ET2_DEBUGLEVEL specifies which messages are printed to the console. Decrease
|
||||
* the value of ET2_DEBUGLEVEL to get less messages.
|
||||
*/
|
||||
var ET2_DEBUGLEVEL = 0;
|
||||
|
||||
function et2_debug(_level, _msg)
|
||||
{
|
||||
if (typeof console != "undefined")
|
||||
{
|
||||
if (_level == "log" && ET2_DEBUGLEVEL >= 4 &&
|
||||
typeof console.log == "function")
|
||||
{
|
||||
console.log(_msg);
|
||||
}
|
||||
|
||||
if (_level == "info" && ET2_DEBUGLEVEL >= 3 &&
|
||||
typeof console.info == "function")
|
||||
{
|
||||
console.info(_msg);
|
||||
}
|
||||
|
||||
if (_level == "warn" && ET2_DEBUGLEVEL >= 2 &&
|
||||
typeof console.warn == "function")
|
||||
{
|
||||
console.warn(_msg);
|
||||
}
|
||||
|
||||
if (_level == "error" && ET2_DEBUGLEVEL >= 1 &&
|
||||
typeof console.error == "function")
|
||||
{
|
||||
console.error(_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Array with all types supported by the et2_checkType function.
|
||||
*/
|
||||
var et2_validTypes = ["boolean", "string", "float", "integer", "any"];
|
||||
|
||||
/**
|
||||
* Object whith default values for the above types. Do not specify array or
|
||||
* objects inside the et2_typeDefaults object, as this instance will be shared
|
||||
* between all users of it.
|
||||
*/
|
||||
var et2_typeDefaults = {
|
||||
"boolean": false,
|
||||
"string": "",
|
||||
"float": 0.0,
|
||||
"integer": 0,
|
||||
"any": null
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks whether the given value is of the given type. Strings are converted
|
||||
* into the corresponding type. The (converted) value is returned. All supported
|
||||
* types are listed in the et2_validTypes array.
|
||||
*/
|
||||
function et2_checkType(_val, _type)
|
||||
{
|
||||
function _err() {
|
||||
throw("'" + _val + "' is not of specified _type '" + _type + "'");
|
||||
}
|
||||
|
||||
// If the type is "any" simply return the value again
|
||||
if (_type == "any")
|
||||
{
|
||||
return _val;
|
||||
}
|
||||
|
||||
// If the type is boolean, check whether the given value is exactly true or
|
||||
// false. Otherwise check whether the value is the string "true" or "false".
|
||||
if (_type == "boolean")
|
||||
{
|
||||
if (_val === true || _val === false)
|
||||
{
|
||||
return _val;
|
||||
}
|
||||
|
||||
var lcv = _val.toLowerCase();
|
||||
if (lcv === "true" || lcv === "false" || lcv === "")
|
||||
{
|
||||
return _val === "true";
|
||||
}
|
||||
|
||||
_err();
|
||||
}
|
||||
|
||||
// Check whether the given value is of the type "string"
|
||||
if (_type == "string")
|
||||
{
|
||||
if (typeof _val == "string")
|
||||
{
|
||||
return _val;
|
||||
}
|
||||
|
||||
_err();
|
||||
}
|
||||
|
||||
// Check whether the value is already a number, otherwise try to convert it
|
||||
// to one.
|
||||
if (_type == "float")
|
||||
{
|
||||
if (typeof _val == "number")
|
||||
{
|
||||
return _val;
|
||||
}
|
||||
|
||||
if (!isNaN(_val))
|
||||
{
|
||||
return parseFloat(_val);
|
||||
}
|
||||
|
||||
_err();
|
||||
}
|
||||
|
||||
// Check whether the value is an integer by comparing the result of
|
||||
// parseInt(_val) to the value itself.
|
||||
if (_type == "integer")
|
||||
{
|
||||
if (parseInt(_val) == _val)
|
||||
{
|
||||
return parseInt(_val);
|
||||
}
|
||||
|
||||
_err();
|
||||
}
|
||||
|
||||
// We should never come here
|
||||
throw("Invalid type identifier supplied.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the given attribute with the given id. The validation checks for
|
||||
* the existance of a human name, a description, a type and a default value.
|
||||
* If the human name defaults to the given id, the description defaults to an
|
||||
* empty string, the type defaults to any and the default to the corresponding
|
||||
* type default.
|
||||
*/
|
||||
function et2_validateAttrib(_id, _attrib)
|
||||
{
|
||||
// Default ignore to false.
|
||||
if (typeof _attrib["ignore"] == "undefined")
|
||||
{
|
||||
_attrib["ignore"] = false
|
||||
}
|
||||
|
||||
// Break if "ignore" is set to true.
|
||||
if (_attrib.ignore)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof _attrib["name"] == "undefined")
|
||||
{
|
||||
_attrib["name"] = _id;
|
||||
et2_debug("log", "Human name ('name'-Field) for attribute '" +
|
||||
_id + "' has not been supplied, set to '" + _id + "'");
|
||||
}
|
||||
|
||||
if (typeof _attrib["description"] == "undefined")
|
||||
{
|
||||
_attrib["description"] = "";
|
||||
et2_debug("log", "Description for attribute '" +
|
||||
_id + "' has not been supplied");
|
||||
}
|
||||
|
||||
if (typeof _attrib["type"] == "undefined")
|
||||
{
|
||||
_attrib["type"] = "any";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (et2_validTypes.indexOf(_attrib["type"]) < 0)
|
||||
{
|
||||
et2_debug("error", "Invalid type for attribute '" + _id +
|
||||
"' supplied.");
|
||||
}
|
||||
}
|
||||
|
||||
// Set the defaults
|
||||
if (typeof _attrib["default"] == "undefined")
|
||||
{
|
||||
_attrib["default"] = et2_typeDefaults[_attrib["type"]];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalent to the PHP array_values function
|
||||
*/
|
||||
function et2_arrayValues(_arr)
|
||||
{
|
||||
var result = [];
|
||||
for (var key in _arr)
|
||||
{
|
||||
if (parseInt(key) == key)
|
||||
{
|
||||
result.push(_arr[key]);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalent to the PHP substr function, partly take from phpjs, licensed under
|
||||
* the GPL.
|
||||
*/
|
||||
function et2_substr (str, start, len) {
|
||||
var end = str.length;
|
||||
|
||||
if (start < 0)
|
||||
{
|
||||
start += end;
|
||||
}
|
||||
end = typeof len === 'undefined' ? end : (len < 0 ? len + end : len + start);
|
||||
|
||||
return start >= str.length || start < 0 || start > end ? "" : str.slice(start, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Split a $delimiter-separated options string, which can contain parts with
|
||||
* delimiters enclosed in $enclosure. Ported from class.boetemplate.inc.php
|
||||
*
|
||||
* Examples:
|
||||
* - et2_csvSplit('"1,2,3",2,3') === array('1,2,3','2','3')
|
||||
* - et2_csvSplit('1,2,3',2) === array('1','2,3')
|
||||
* - et2_csvSplit('"1,2,3",2,3',2) === array('1,2,3','2,3')
|
||||
* - et2_csvSplit('"a""b,c",d') === array('a"b,c','d') // to escape enclosures double them!
|
||||
*
|
||||
* @param string _str
|
||||
* @param int _num=null in how many parts to split maximal, parts over this
|
||||
* number end up (unseparated) in the last part
|
||||
* @param string _delimiter=','
|
||||
* @param string _enclosure='"'
|
||||
* @return array
|
||||
*/
|
||||
function et2_csvSplit(_str, _num, _delimiter, _enclosure)
|
||||
{
|
||||
// Default the parameters
|
||||
if (typeof _num == "undefined")
|
||||
{
|
||||
_num == null;
|
||||
}
|
||||
|
||||
if (typeof _delimiter == "undefined")
|
||||
{
|
||||
_delimiter = ",";
|
||||
}
|
||||
|
||||
if (typeof _enclosure == "undefined")
|
||||
{
|
||||
_enclosure = '"';
|
||||
}
|
||||
|
||||
// If the _enclosure string does not occur in the string, simply use the
|
||||
// split function
|
||||
if (_str.indexOf(_enclosure) == -1)
|
||||
{
|
||||
return _num === null ? _str.split(_delimiter) :
|
||||
_str.split(_delimiter, _num);
|
||||
}
|
||||
|
||||
// Split the string at the delimiter and join it again, when a enclosure is
|
||||
// found at the beginning/end of a part
|
||||
var parts = _str.split(_delimiter);
|
||||
for (var n = 0; typeof parts[n] != "undefined"; n++)
|
||||
{
|
||||
var part = parts[n];
|
||||
|
||||
if (part.charAt(0) === _enclosure)
|
||||
{
|
||||
var m = n;
|
||||
while (typeof parts[m + 1] != "undefined" && parts[n].substr(-1) !== _enclosure)
|
||||
{
|
||||
parts[n] += _delimiter + parts[++m];
|
||||
delete(parts[m]);
|
||||
}
|
||||
parts[n] = et2_substr(parts[n].replace(
|
||||
new RegExp(_enclosure + _enclosure, 'g'), _enclosure), 1 , -1);
|
||||
n = m;
|
||||
}
|
||||
}
|
||||
|
||||
// Rebuild the array index
|
||||
parts = et2_arrayValues(parts);
|
||||
|
||||
// Limit the parts to the given number
|
||||
if (_num !== null && _num > 0 && _num < parts.length && parts.length > 0)
|
||||
{
|
||||
parts[_num - 1] = parts.slice(_num - 1, parts.length).join(_delimiter);
|
||||
parts = parts.slice(0, _num);
|
||||
}
|
||||
|
||||
return parts;
|
||||
}
|
||||
|
||||
|
||||
|
@ -14,24 +14,82 @@
|
||||
|
||||
/*egw:uses
|
||||
jquery.jquery;
|
||||
et2_widget;
|
||||
et2_baseWidget;
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class which implements the "description" XET-Tag
|
||||
*/
|
||||
var et2_description = et2_DOMWidget.extend({
|
||||
var et2_description = et2_baseWidget.extend({
|
||||
|
||||
attributes: {
|
||||
"value": {
|
||||
"name": "Caption",
|
||||
"type": "string",
|
||||
"description": "Displayed text"
|
||||
},
|
||||
|
||||
/**
|
||||
* Options converted from the "options"-attribute.
|
||||
*/
|
||||
"font_style": {
|
||||
"name": "Font Style",
|
||||
"type": "string",
|
||||
"description": "Style may be a compositum of \"b\" and \"i\" which " +
|
||||
" renders the text bold and/or italic."
|
||||
},
|
||||
"href": {
|
||||
"name": "Link Target",
|
||||
"type": "string",
|
||||
"description": "Link URL, empty if you don't wan't to display a link."
|
||||
},
|
||||
"activate_links": {
|
||||
"name": "Replace URLs",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "If set, URLs in the text are automatically replaced " +
|
||||
"by links"
|
||||
},
|
||||
"label_for": {
|
||||
"name": "Label for widget",
|
||||
"type": "string",
|
||||
"description": "Marks the text as label for the given widget."
|
||||
},
|
||||
"extra_link_target": {
|
||||
"name": "Link target",
|
||||
"type": "string",
|
||||
"default": "_self",
|
||||
"description": "Link target descriptor"
|
||||
},
|
||||
"extra_link_popup": {
|
||||
"name": "Popup",
|
||||
"type": "string",
|
||||
"description": "???"
|
||||
},
|
||||
"extra_link_title": {
|
||||
"name": "Link Title",
|
||||
"type": "string",
|
||||
"description": "Link title which is displayed on mouse over."
|
||||
}
|
||||
},
|
||||
|
||||
legacyOptions: ["font_style", "href", "activate_links", "label_for",
|
||||
"extra_link_target", "extra_link_popup", "extra_link_title"],
|
||||
|
||||
init: function(_parent) {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
this.value = "";
|
||||
this.font_style = "";
|
||||
|
||||
this.span = $j(document.createElement("span"))
|
||||
.addClass("et2_label");
|
||||
|
||||
this._super.apply(this, arguments);
|
||||
this.value = "";
|
||||
this.setDOMNode(this.span[0]);
|
||||
},
|
||||
|
||||
set_value: function(_value) {
|
||||
if (_value != this.value)
|
||||
set_value: function(_value, _force) {
|
||||
if (_value != this.value || _force)
|
||||
{
|
||||
this.value = _value;
|
||||
|
||||
@ -39,8 +97,14 @@ var et2_description = et2_DOMWidget.extend({
|
||||
}
|
||||
},
|
||||
|
||||
getDOMNode: function() {
|
||||
return this.span[0];
|
||||
set_font_style: function(_value) {
|
||||
if (_value != this.font_style)
|
||||
{
|
||||
this.font_style = _value;
|
||||
|
||||
this.span.toggleClass("et2_bold", _value.indexOf("b") >= 0);
|
||||
this.span.toggleClass("et2_italic", _value.indexOf("i") >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -98,12 +98,6 @@ var et2_grid = et2_DOMWidget.extend({
|
||||
};
|
||||
},
|
||||
|
||||
_readAttrWithDefault: function(_node, _name, _default) {
|
||||
var val = _node.getAttribute(_name);
|
||||
|
||||
return (val === null) ? _default : val;
|
||||
},
|
||||
|
||||
_getCell: function(_cells, _x, _y) {
|
||||
if ((0 <= _y) && (_y < _cells.length))
|
||||
{
|
||||
@ -132,10 +126,10 @@ var et2_grid = et2_DOMWidget.extend({
|
||||
var colDataEntry = this._getColDataEntry();
|
||||
if (nodeName == "column")
|
||||
{
|
||||
colDataEntry["width"] = this._readAttrWithDefault(node, "width", "auto");
|
||||
colDataEntry["class"] = this._readAttrWithDefault(node, "class", "");
|
||||
colDataEntry["align"] = this._readAttrWithDefault(node, "align", "");
|
||||
colDataEntry["span"] = this._readAttrWithDefault(node, "span", "1");
|
||||
colDataEntry["width"] = et2_readAttrWithDefault(node, "width", "auto");
|
||||
colDataEntry["class"] = et2_readAttrWithDefault(node, "class", "");
|
||||
colDataEntry["align"] = et2_readAttrWithDefault(node, "align", "");
|
||||
colDataEntry["span"] = et2_readAttrWithDefault(node, "span", "1");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -149,10 +143,10 @@ var et2_grid = et2_DOMWidget.extend({
|
||||
var rowDataEntry = this._getRowDataEntry();
|
||||
if (nodeName == "row")
|
||||
{
|
||||
rowDataEntry["height"] = this._readAttrWithDefault(node, "height", "auto");
|
||||
rowDataEntry["class"] = this._readAttrWithDefault(node, "class", "");
|
||||
rowDataEntry["valign"] = this._readAttrWithDefault(node, "valign", "");
|
||||
rowDataEntry["span"] = this._readAttrWithDefault(node, "span", "1");
|
||||
rowDataEntry["height"] = et2_readAttrWithDefault(node, "height", "auto");
|
||||
rowDataEntry["class"] = et2_readAttrWithDefault(node, "class", "");
|
||||
rowDataEntry["valign"] = et2_readAttrWithDefault(node, "valign", "");
|
||||
rowDataEntry["span"] = et2_readAttrWithDefault(node, "span", "1");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -12,6 +12,10 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
/*egw:uses
|
||||
et2_common;
|
||||
*/
|
||||
|
||||
/**
|
||||
* Usage of the JS inheritance system
|
||||
* ----------------------------------
|
||||
@ -84,10 +88,10 @@
|
||||
};
|
||||
|
||||
/**
|
||||
* The addInterfaceStuff function adds all interface functions the class has
|
||||
* The addInterfaceFunctions function adds all interface functions the class has
|
||||
* to implement to the class prototype.
|
||||
*/
|
||||
function addInterfaceStuff(prototype, interfaces)
|
||||
function addInterfaceFunctions(prototype, interfaces)
|
||||
{
|
||||
// Remember all interface functions in the prototype
|
||||
var ifaces = ((typeof prototype["_ifacefuncs"] == "undefined") ? [] :
|
||||
@ -107,7 +111,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
throw("Interfaces must be instanceof Interface!");
|
||||
throw("Interfaces must be instance of Interface!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,6 +148,118 @@
|
||||
}
|
||||
};
|
||||
|
||||
function addAttributeFunctions(prototype, _super)
|
||||
{
|
||||
var attributes = prototype.attributes;
|
||||
|
||||
// Add the old attributes to the new ones. If the attributes already
|
||||
// exist, they are merged.
|
||||
for (var key in _super.attributes)
|
||||
{
|
||||
var attrib = _super.attributes[key];
|
||||
|
||||
if (typeof attributes[key] == "undefined")
|
||||
{
|
||||
// In the case that the old attribute has no equivalent in the
|
||||
// new class, simply create a reference to the old one.
|
||||
attributes[key] = attrib;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise merge the two attribute descriptors.
|
||||
for (var key2 in attrib)
|
||||
{
|
||||
if (typeof attributes[key][key2] == "undefined")
|
||||
{
|
||||
attributes[key][key2] = attrib[key2];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Validate the attributes
|
||||
for (var key in attributes)
|
||||
{
|
||||
et2_validateAttrib(key, attributes[key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* The initAttributes function sets the attributes to their default
|
||||
* values. The attributes are not overwritten, which means, that the
|
||||
* default is only set, if either a setter exists or this[propName] does
|
||||
* not exist yet.
|
||||
*/
|
||||
prototype.initAttributes = function() {
|
||||
for (var key in this.attributes)
|
||||
{
|
||||
if (!this.attributes[key].ignore)
|
||||
{
|
||||
this.setAttribute(key, this.attributes[key]["default"],
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
this._attrsInitialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The setAttribute function sets the attribute with the given name to
|
||||
* the given value. _override defines, whether this[_name] will be set,
|
||||
* if this key already exists. _override defaults to true. A warning
|
||||
* is issued if the attribute does not exist.
|
||||
*/
|
||||
prototype.setAttribute = function(_name, _value, _override) {
|
||||
if (typeof this.attributes[_name] != "undefined")
|
||||
{
|
||||
if (!this.attributes[_name].ignore)
|
||||
{
|
||||
if (typeof _override == "undefined")
|
||||
{
|
||||
_override = true;
|
||||
}
|
||||
|
||||
var val = et2_checkType(_value, this.attributes[_name].type);
|
||||
|
||||
if (typeof this["set_" + _name] == "function")
|
||||
{
|
||||
this["set_" + _name](val);
|
||||
}
|
||||
else if (_override || typeof this[_name] == "undefined")
|
||||
{
|
||||
this[_name] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
et2_debug("warn", "Attribute '" + _name + "' does not exist!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the given attribute. If the property does not
|
||||
* exist, an error message is issued.
|
||||
*/
|
||||
prototype.getAttribute = function(_name) {
|
||||
if (typeof this.attributes[_name] != "undefined" &&
|
||||
!this.attributes[_name].ignore)
|
||||
{
|
||||
if (typeof this["get_" + _name] == "function")
|
||||
{
|
||||
return this["get_" + _name]();
|
||||
}
|
||||
else
|
||||
{
|
||||
return this[_name];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
et2_error("error", "Attribute '" + _name + "' does not exist!");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function classExtend(interfaces, prop) {
|
||||
|
||||
if (typeof prop == "undefined")
|
||||
@ -158,6 +274,11 @@
|
||||
interfaces = [interfaces];
|
||||
}
|
||||
|
||||
if (typeof prop.attributes == "undefined")
|
||||
{
|
||||
prop.attributes = {};
|
||||
}
|
||||
|
||||
var _super = this.prototype;
|
||||
|
||||
// Instantiate a base class (but only create the instance,
|
||||
@ -199,7 +320,11 @@
|
||||
|
||||
// Add the interface functions and the "implements" function to the
|
||||
// prototype
|
||||
addInterfaceStuff(prototype, interfaces);
|
||||
addInterfaceFunctions(prototype, interfaces);
|
||||
|
||||
// Merge the attributes and create the functions corresponding to the
|
||||
// attributes
|
||||
addAttributeFunctions(prototype, _super);
|
||||
|
||||
// The dummy class constructor
|
||||
function Class() {
|
||||
@ -221,6 +346,12 @@
|
||||
{
|
||||
this.init.apply(this, arguments);
|
||||
}
|
||||
|
||||
// Initialize the attributes
|
||||
if (typeof this._attrsInitialized == "undefined")
|
||||
{
|
||||
this.initAttributes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -243,5 +374,8 @@
|
||||
// is an array which defines a set of interfaces the object has to
|
||||
// implement. An interface is simply an object with named functions.
|
||||
Class.extend = classExtend;
|
||||
|
||||
// The base class has no attributes
|
||||
Class.attributes = {};
|
||||
}).call(window);
|
||||
|
||||
|
94
etemplate/js/et2_inputWidget.js
Normal file
94
etemplate/js/et2_inputWidget.js
Normal file
@ -0,0 +1,94 @@
|
||||
/**
|
||||
* eGroupWare eTemplate2 - JS Widget base class
|
||||
*
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @package etemplate
|
||||
* @subpackage api
|
||||
* @link http://www.egroupware.org
|
||||
* @author Andreas Stöckel
|
||||
* @copyright Stylite 2011
|
||||
* @version $Id: et2_widget.js 36021 2011-08-07 13:43:46Z igel457 $
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
/*egw:uses
|
||||
jquery.jquery;
|
||||
et2_baseWidget;
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interface for all widgets which support returning a value
|
||||
*/
|
||||
var et2_IInput = new Interface({
|
||||
/**
|
||||
* getValue has to return the value of the input widget
|
||||
*/
|
||||
getValue: function() {},
|
||||
|
||||
/**
|
||||
* Is dirty returns true if the value of the widget has changed since it
|
||||
* was loaded.
|
||||
*/
|
||||
isDirty: function() {},
|
||||
|
||||
/**
|
||||
* Causes the dirty flag to be reseted.
|
||||
*/
|
||||
resetDirty: function() {}
|
||||
});
|
||||
|
||||
/**
|
||||
* et2_inputWidget derrives from et2_simpleWidget and implements the IInput
|
||||
* interface. When derriving from this class, call setDOMNode with an input
|
||||
* DOMNode.
|
||||
*/
|
||||
var et2_inputWidget = et2_simpleWidget.extend(et2_IInput, {
|
||||
|
||||
attributes: {
|
||||
"value": {
|
||||
"name": "Value",
|
||||
"description": "The value of the widget",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
},
|
||||
|
||||
init: function() {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
this._oldValue = "";
|
||||
},
|
||||
|
||||
set_value: function(_value) {
|
||||
this._oldValue = _value;
|
||||
|
||||
if (this.node)
|
||||
{
|
||||
$j(this.node).val(_value);
|
||||
}
|
||||
},
|
||||
|
||||
get_value: function() {
|
||||
return this.getValue();
|
||||
},
|
||||
|
||||
getValue: function() {
|
||||
if (this.node)
|
||||
{
|
||||
return $j(this.node).val();
|
||||
}
|
||||
|
||||
return this._oldValue;
|
||||
},
|
||||
|
||||
isDirty: function() {
|
||||
return this._oldValue != this.getValue();
|
||||
},
|
||||
|
||||
resetDirty: function() {
|
||||
this._oldValue = this.getValue();
|
||||
}
|
||||
|
||||
});
|
||||
|
178
etemplate/js/et2_tabs.js
Normal file
178
etemplate/js/et2_tabs.js
Normal file
@ -0,0 +1,178 @@
|
||||
/**
|
||||
* eGroupWare eTemplate2 - JS Tabs object
|
||||
*
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @package etemplate
|
||||
* @subpackage api
|
||||
* @link http://www.egroupware.org
|
||||
* @author Andreas Stöckel
|
||||
* @copyright Stylite 2011
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
/*egw:uses
|
||||
jquery.jquery;
|
||||
et2_widget;
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class which implements the tabbox-tag
|
||||
*/
|
||||
var et2_tabbox = et2_DOMWidget.extend({
|
||||
|
||||
init: function(_parent, _type) {
|
||||
// Create the outer tabbox container
|
||||
this.container = $j(document.createElement("div"))
|
||||
.addClass("et2_tabbox");
|
||||
|
||||
// Create the upper container for the tab flags
|
||||
var cntr = $j(document.createElement("div"))
|
||||
.addClass("et2_flags")
|
||||
.appendTo(this.container);
|
||||
|
||||
this.flagContainer = $j(document.createElement("span"))
|
||||
.addClass("et2_tabflagcntr")
|
||||
.appendTo(cntr);
|
||||
|
||||
$j(document.createElement("span"))
|
||||
.addClass("et2_tabspacer")
|
||||
.appendTo(cntr);
|
||||
|
||||
// Create the lower tab container
|
||||
this.tabContainer = $j(document.createElement("div"))
|
||||
.addClass("et2_tabs")
|
||||
.appendTo(this.container);
|
||||
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
this.tabData = [];
|
||||
},
|
||||
|
||||
destroy: function(_parent, _type) {
|
||||
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
this.container = null;
|
||||
this.flagContainer = null;
|
||||
this.tabData = [];
|
||||
},
|
||||
|
||||
_readTabs: function(tabData, tabs) {
|
||||
et2_filteredNodeIterator(tabs, function(node, nodeName) {
|
||||
if (nodeName == "tab")
|
||||
{
|
||||
tabData.push({
|
||||
"label": et2_readAttrWithDefault(node, "label", "Tab"),
|
||||
"widget": null,
|
||||
"contentDiv": null,
|
||||
"flagDiv": null
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
throw("Error while parsing: Invalid tag '" + nodeName +
|
||||
"' in tabs tag");
|
||||
}
|
||||
}, this);
|
||||
},
|
||||
|
||||
_readTabPanels: function(tabData, tabpanels) {
|
||||
var i = 0;
|
||||
et2_filteredNodeIterator(tabpanels, function(node, nodeName) {
|
||||
if (i < tabData.length)
|
||||
{
|
||||
// Create the widget corresponding to the given node
|
||||
tabData[i].widget = this.createElementFromNode(node,
|
||||
nodeName);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw("Error while reading tabpanels tag, too many widgets!");
|
||||
}
|
||||
i++;
|
||||
}, this);
|
||||
},
|
||||
|
||||
loadFromXML: function(_node) {
|
||||
// Get the tabs and tabpanels tags
|
||||
var tabsElems = et2_directChildrenByTagName(_node, "tabs");
|
||||
var tabpanelsElems = et2_directChildrenByTagName(_node, "tabpanels");
|
||||
|
||||
if (tabsElems.length == 1 && tabpanelsElems.length == 1)
|
||||
{
|
||||
var tabs = tabsElems[0];
|
||||
var tabpanels = tabpanelsElems[0];
|
||||
|
||||
var tabData = [];
|
||||
|
||||
// Parse the "tabs" tag
|
||||
this._readTabs(tabData, tabs);
|
||||
|
||||
// Read and create the widgets defined in the "tabpanels"
|
||||
this._readTabPanels(tabData, tabpanels);
|
||||
|
||||
// Create the tab DOM-Nodes
|
||||
this.createTabs(tabData)
|
||||
}
|
||||
else
|
||||
{
|
||||
throw("Error while parsing tabbox, none or multiple tabs or tabpanels tags!");
|
||||
}
|
||||
},
|
||||
|
||||
createTabs: function(tabData) {
|
||||
this.tabData = tabData;
|
||||
|
||||
this.tabContainer.empty();
|
||||
this.flagContainer.empty();
|
||||
|
||||
for (var i = 0; i < this.tabData.length; i++)
|
||||
{
|
||||
// Add a spacer to the flag container
|
||||
$j(document.createElement("span"))
|
||||
.addClass("et2_flagspacer")
|
||||
.text("-")
|
||||
.appendTo(this.flagContainer);
|
||||
|
||||
var entry = this.tabData[i];
|
||||
|
||||
entry.flagDiv = $j(document.createElement("span"))
|
||||
.addClass("et2_tabflag")
|
||||
.text(entry.label)
|
||||
.appendTo(this.flagContainer);
|
||||
|
||||
entry.contentDiv = $j(document.createElement("div"))
|
||||
.addClass("et2_tabcntr")
|
||||
.hide()
|
||||
.appendTo(this.tabContainer);
|
||||
|
||||
// Let the widget appear on its corresponding page
|
||||
entry.widget.onSetParent();
|
||||
}
|
||||
},
|
||||
|
||||
getDOMNode: function(_sender) {
|
||||
if (_sender == this)
|
||||
{
|
||||
return this.container[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = 0; i < this.tabData.length; i++)
|
||||
{
|
||||
if (this.tabData[i].widget == _sender)
|
||||
{
|
||||
return this.tabData[i].contentDiv[0];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
et2_register_widget(et2_tabbox, ["tabbox"]);
|
||||
|
@ -26,6 +26,23 @@
|
||||
*/
|
||||
var et2_template = et2_DOMWidget.extend({
|
||||
|
||||
attributes: {
|
||||
"template": {
|
||||
},
|
||||
"group": {
|
||||
},
|
||||
"version": {
|
||||
"name": "Version",
|
||||
"type": "string",
|
||||
"description": "Version of the template"
|
||||
},
|
||||
"lang": {
|
||||
"name": "Language",
|
||||
"type": "string",
|
||||
"description": "Language the template is written in"
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Initializes this template widget as a simple container.
|
||||
*/
|
||||
@ -34,6 +51,7 @@ var et2_template = et2_DOMWidget.extend({
|
||||
this.isProxied = false;
|
||||
|
||||
this.div = document.createElement("div");
|
||||
this.id = "";
|
||||
|
||||
this._super.apply(this, arguments);
|
||||
},
|
||||
|
@ -14,33 +14,56 @@
|
||||
|
||||
/*egw:uses
|
||||
jquery.jquery;
|
||||
et2_widget;
|
||||
et2_inputWidget;
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class which implements the "textbox" XET-Tag
|
||||
*/
|
||||
var et2_textbox = et2_DOMWidget.extend({
|
||||
var et2_textbox = et2_baseWidget.extend({
|
||||
|
||||
init: function(_parent) {
|
||||
this.input = $j(document.createElement("input"))
|
||||
.addClass("et2_input");
|
||||
|
||||
this._super.apply(this, arguments);
|
||||
this.label = "";
|
||||
},
|
||||
|
||||
set_value: function(_value) {
|
||||
if (_value != this.value)
|
||||
{
|
||||
this.label = _value;
|
||||
|
||||
this.input.attr("value", _value);
|
||||
attributes: {
|
||||
"multiline": {
|
||||
"name": "multiline",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "If true, the textbox is a multiline edit field."
|
||||
}
|
||||
},
|
||||
|
||||
getDOMNode: function() {
|
||||
return this.input[0];
|
||||
init: function(_parent) {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
this.input = null;
|
||||
|
||||
this.createInputWidget();
|
||||
},
|
||||
|
||||
createInputWidget: function() {
|
||||
if (this.multiline)
|
||||
{
|
||||
this.input = $j(document.createElement("textarea"));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.input = $j(document.createElement("input"));
|
||||
}
|
||||
|
||||
this.input.addClass("et2_textbox");
|
||||
|
||||
this.setDOMNode(this.input[0]);
|
||||
},
|
||||
|
||||
set_multiline: function(_value) {
|
||||
if (_value != this.multiline)
|
||||
{
|
||||
this.multiline = _value;
|
||||
|
||||
this.createInputWidget();
|
||||
|
||||
// Write all settings again
|
||||
this.update();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
/*egw:uses
|
||||
jquery.jquery;
|
||||
lib/tooltip.js;
|
||||
et2_xml;
|
||||
et2_common;
|
||||
et2_inheritance;
|
||||
@ -53,6 +54,26 @@ function et2_register_widget(_constructor, _types)
|
||||
*/
|
||||
var et2_widget = Class.extend({
|
||||
|
||||
attributes: {
|
||||
"id": {
|
||||
"name": "ID",
|
||||
"type": "string",
|
||||
"description": "Unique identifier of the widget"
|
||||
},
|
||||
|
||||
/**
|
||||
* Ignore the "span" property by default - it is read by the grid and
|
||||
* other widgets.
|
||||
*/
|
||||
"span": {
|
||||
"ignore": true
|
||||
}
|
||||
},
|
||||
|
||||
// Set the legacyOptions array to the names of the properties the "options"
|
||||
// attribute defines.
|
||||
legacyOptions: [],
|
||||
|
||||
/**
|
||||
* The init function is the constructor of the widget. When deriving new
|
||||
* classes from the widget base class, always call this constructor unless
|
||||
@ -82,7 +103,6 @@ var et2_widget = Class.extend({
|
||||
}
|
||||
|
||||
this._children = [];
|
||||
this.id = "";
|
||||
this.type = _type;
|
||||
|
||||
// The supported widget classes array defines a whitelist for all widget
|
||||
@ -148,12 +168,12 @@ var et2_widget = Class.extend({
|
||||
_obj._children[i].clone(this, _obj._children[i].type);
|
||||
}
|
||||
|
||||
// Copy all properties for which a setter function exists
|
||||
for (var key in _obj)
|
||||
// Copy all properties
|
||||
for (var key in _obj.attributes)
|
||||
{
|
||||
if (key != "id" && typeof this["set_" + key] == "function")
|
||||
if (!_obj.attributes[key].ignore && key != "id")
|
||||
{
|
||||
this["set_" + key](_obj[key]);
|
||||
this.setAttribute(key, _obj.getAttribute(key));
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -265,6 +285,31 @@ var et2_widget = Class.extend({
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Function which allows iterating over the complete widget tree.
|
||||
*
|
||||
* @param _callback is the function which should be called for each widget
|
||||
* @param _context is the context in which the function should be executed
|
||||
* @param _type is an optional parameter which specifies a class/interface
|
||||
* the elements have to be instanceOf.
|
||||
*/
|
||||
iterateOver: function(_callback, _context, _type) {
|
||||
if (typeof _type == "undefined")
|
||||
{
|
||||
_type = et2_widget;
|
||||
}
|
||||
|
||||
if (this.instanceOf(_type))
|
||||
{
|
||||
_callback.call(_context, this);
|
||||
}
|
||||
|
||||
for (var i = 0; i < this._children.length; i++)
|
||||
{
|
||||
this._children[i].iterateOver(_callback, _context, _type);
|
||||
}
|
||||
},
|
||||
|
||||
isOfSupportedWidgetClass: function(_obj)
|
||||
{
|
||||
for (var i = 0; i < this.supportedWidgetClasses.length; i++)
|
||||
@ -336,12 +381,19 @@ var et2_widget = Class.extend({
|
||||
loadAttributes: function(_attrs) {
|
||||
for (var i = 0; i < _attrs.length; i++)
|
||||
{
|
||||
var attr = _attrs[i];
|
||||
|
||||
// Check whether a setter exists for the given attribute
|
||||
if (typeof this["set_" + attr.name] == "function" && attr.name.charAt(0) != "_")
|
||||
if (_attrs[i].name == "options")
|
||||
{
|
||||
this["set_" + attr.name](attr.value);
|
||||
// Parse the legacy options
|
||||
var splitted = et2_csvSplit(_attrs[i].value);
|
||||
|
||||
for (var i = 0; i < splitted.length && i < this.legacyOptions.length; i++)
|
||||
{
|
||||
this.setAttribute(this.legacyOptions[i], splitted[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setAttribute(_attrs[i].name, _attrs[i].value);
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -357,13 +409,14 @@ var et2_widget = Class.extend({
|
||||
* update function of all child nodes.
|
||||
*/
|
||||
update: function() {
|
||||
|
||||
// Go through every property of this object and check whether a
|
||||
// corresponding setter function exists. If yes, it is called.
|
||||
for (var key in this)
|
||||
for (var key in this.attributes)
|
||||
{
|
||||
if (typeof this["set_" + key] == "function" && key.charAt(0) != "_")
|
||||
if (!this.attributes[key].ignore && key != "id")
|
||||
{
|
||||
this["set_" + key](this[key]);
|
||||
this.setAttribute(key, this.getAttribute(key));
|
||||
}
|
||||
}
|
||||
|
||||
@ -372,19 +425,8 @@ var et2_widget = Class.extend({
|
||||
{
|
||||
this._children[i].update();
|
||||
}
|
||||
},
|
||||
|
||||
get_id: function() {
|
||||
return this.id;
|
||||
},
|
||||
|
||||
set_id: function(_value) {
|
||||
this.id = _value;
|
||||
},
|
||||
|
||||
get_type: function() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
@ -392,7 +434,13 @@ var et2_widget = Class.extend({
|
||||
*/
|
||||
var et2_IDOMNode = new Interface({
|
||||
/**
|
||||
* Returns the DOM-Node of the current widget.
|
||||
* Returns the DOM-Node of the current widget. The return value has to be
|
||||
* a plain DOM node. If you want to return an jQuery object as you receive
|
||||
* it with
|
||||
*
|
||||
* obj = $j(node);
|
||||
*
|
||||
* simply return obj[0];
|
||||
*
|
||||
* @param _sender The _sender parameter defines which widget is asking for
|
||||
* the DOMNode.depending on that, the widget may return different nodes.
|
||||
@ -417,19 +465,32 @@ var et2_DOMWidget = et2_widget.extend(et2_IDOMNode, {
|
||||
*/
|
||||
init: function(_parent, _type) {
|
||||
this.parentNode = null;
|
||||
this.visible = true;
|
||||
|
||||
this._attachSet = {
|
||||
"node": null,
|
||||
"parent": null
|
||||
};
|
||||
|
||||
// Call the inherited constructor
|
||||
this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
/**
|
||||
* Detatches the node from the DOM and clears all references to the parent
|
||||
* node or the dom node of this widget.
|
||||
*/
|
||||
destroy: function() {
|
||||
|
||||
this.detatchFromDOM();
|
||||
this.parentNode = null;
|
||||
this._attachSet = {};
|
||||
|
||||
this._super();
|
||||
},
|
||||
|
||||
/**
|
||||
* Automatically tries to attach this node to the parent widget.
|
||||
*/
|
||||
onSetParent: function() {
|
||||
// Check whether the parent implements the et2_IDOMNode interface. If
|
||||
// yes, grab the DOM node and create our own.
|
||||
@ -438,16 +499,53 @@ var et2_DOMWidget = et2_widget.extend(et2_IDOMNode, {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Detaches the widget from the DOM tree, if it had been attached to the
|
||||
* DOM-Tree using the attachToDOM method.
|
||||
*/
|
||||
detatchFromDOM: function() {
|
||||
if (this.parentNode)
|
||||
|
||||
if (this._attachSet.node && this._attachSet.parent)
|
||||
{
|
||||
var node = this.getDOMNode(this);
|
||||
if (node)
|
||||
{
|
||||
this.parentNode.removeChild(node);
|
||||
this.parentNode = null;
|
||||
}
|
||||
// Remove the current node from the parent node
|
||||
this._attachSet.parent.removeChild(this._attachSet.node);
|
||||
|
||||
// Reset the "attachSet"
|
||||
this._attachSet = {
|
||||
"node": null,
|
||||
"parent": null
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Attaches the widget to the DOM tree. Fails if the widget is already
|
||||
* attached to the tree or no parent node or no node for this widget is
|
||||
* defined.
|
||||
*/
|
||||
attachToDOM: function() {
|
||||
// Attach the DOM node of this widget (if existing) to the new parent
|
||||
var node = this.getDOMNode(this);
|
||||
if (node && this.parentNode &&
|
||||
(node != this._attachSet.node ||
|
||||
this.parentNode != this._attachSet.parent))
|
||||
{
|
||||
this.parentNode.appendChild(node);
|
||||
|
||||
// Store the currently attached nodes
|
||||
this._attachSet = {
|
||||
"node": node,
|
||||
"parent": this.parentNode
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -462,51 +560,77 @@ var et2_DOMWidget = et2_widget.extend(et2_IDOMNode, {
|
||||
|
||||
this.parentNode = _node;
|
||||
|
||||
// Attach the DOM node of this widget (if existing) to the new parent
|
||||
var node = this.getDOMNode(this);
|
||||
if (node && this.parentNode)
|
||||
{
|
||||
this.parentNode.appendChild(node);
|
||||
}
|
||||
// And attatch the element to the DOM tree
|
||||
this.attachToDOM();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the parent node.
|
||||
*/
|
||||
getParentDOMNode: function() {
|
||||
return this.parentNode;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the id of the DOM-Node.
|
||||
*/
|
||||
set_id: function(_value) {
|
||||
this._super(_value);
|
||||
|
||||
this.id = _value;
|
||||
|
||||
var node = this.getDOMNode(this);
|
||||
if (node)
|
||||
{
|
||||
node.setAttribute("id", _value);
|
||||
if (_value != "")
|
||||
{
|
||||
node.setAttribute("id", _value);
|
||||
}
|
||||
else
|
||||
{
|
||||
node.removeAttribute("id");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Container object for not-yet supported widgets
|
||||
* Common container object
|
||||
*/
|
||||
var et2_placeholder = et2_DOMWidget.extend({
|
||||
var et2_container = et2_simpleWidget.extend({
|
||||
|
||||
init: function() {
|
||||
// Create the placeholder div
|
||||
this.placeDiv = $j(document.createElement("span"))
|
||||
.addClass("et2_placeholder");
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
this.setDOMNode(document.createElement("div"));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Container object for not-yet supported widgets
|
||||
*/
|
||||
var et2_placeholder = et2_baseWidget.extend({
|
||||
|
||||
init: function() {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
// The attrNodes object will hold the DOM nodes which represent the
|
||||
// values of this object
|
||||
this.attrNodes = {};
|
||||
|
||||
this._super.apply(this, arguments);
|
||||
// Create the placeholder div
|
||||
this.placeDiv = $j(document.createElement("span"))
|
||||
.addClass("et2_placeholder");
|
||||
|
||||
var headerNode = $j(document.createElement("span"))
|
||||
.text(this.type)
|
||||
.addClass("et2_caption");
|
||||
$j(this.placeDiv).append(headerNode);
|
||||
.addClass("et2_caption")
|
||||
.appendTo(this.placeDiv);
|
||||
|
||||
this.setDOMNode(this.placeDiv[0]);
|
||||
},
|
||||
|
||||
loadAttributes: function(_attrs) {
|
||||
@ -523,37 +647,6 @@ var et2_placeholder = et2_DOMWidget.extend({
|
||||
|
||||
this.attrNodes[attr.name].text(attr.name + "=" + attr.value);
|
||||
}
|
||||
},
|
||||
|
||||
getDOMNode: function() {
|
||||
return this.placeDiv[0];
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Common container object
|
||||
*/
|
||||
var et2_container = et2_DOMWidget.extend({
|
||||
|
||||
init: function() {
|
||||
this.div = document.createElement("div");
|
||||
|
||||
this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
getDOMNode: function() {
|
||||
return this.div;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Interface for all widgets which support returning a value
|
||||
*/
|
||||
|
||||
var et2_IValue = new Interface({
|
||||
getValue: function() {}
|
||||
});
|
||||
|
||||
|
||||
|
@ -114,3 +114,11 @@ function et2_filteredNodeIterator(_node, _callback, _context)
|
||||
}
|
||||
}
|
||||
|
||||
function et2_readAttrWithDefault(_node, _name, _default)
|
||||
{
|
||||
var val = _node.getAttribute(_name);
|
||||
|
||||
return (val === null) ? _default : val;
|
||||
}
|
||||
|
||||
|
||||
|
180
etemplate/js/lib/tooltip.js
Normal file
180
etemplate/js/lib/tooltip.js
Normal file
@ -0,0 +1,180 @@
|
||||
/**
|
||||
* eGroupware2 UI - Tooltip JS
|
||||
*
|
||||
* This javascript file contains the JavaScript code for the etemplate2 tooltip
|
||||
*
|
||||
* @link http://www.egroupware.org
|
||||
* @author Andreas Stoeckel (as@stylite.de)
|
||||
* @version $Id: tooltip.js 31497 2010-07-22 09:50:11Z igel457 $
|
||||
*/
|
||||
|
||||
/* Tooltip handling */
|
||||
function egw_tooltip()
|
||||
{
|
||||
this.tooltip_div = null;
|
||||
this.current_elem = null;
|
||||
this.time_delta = 100;
|
||||
this.show_delta = 0;
|
||||
this.show_delay = 800;
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
}
|
||||
|
||||
egw_tooltip.prototype.bindToElement = function(_elem, _text)
|
||||
{
|
||||
if (_text != '')
|
||||
{
|
||||
var self = this;
|
||||
_elem.bind('mouseenter.tooltip', function(e) {
|
||||
if (_elem != self.current_elem)
|
||||
{
|
||||
//Prepare the tooltip
|
||||
self._prepare(_text);
|
||||
|
||||
self.current_elem = _elem;
|
||||
self.show_delta = 0;
|
||||
self.x = e.clientX;
|
||||
self.y = e.clientY;
|
||||
|
||||
window.setTimeout(function() {self.showHintTimeout();}, self.time_delta);
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
_elem.bind('mouseleave.tooltip', function() {
|
||||
self.current_elem = null;
|
||||
self.show_delta = 0;
|
||||
//self.hide();
|
||||
if (self.tooltip_div)
|
||||
{
|
||||
self.tooltip_div.fadeOut(100);
|
||||
}
|
||||
});
|
||||
|
||||
_elem.bind('mousemove.tooltip', function(e) {
|
||||
//Calculate the distance the mouse took since the last call of mousemove
|
||||
var dx = self.x - e.clientX;
|
||||
var dy = self.y - e.clientY;
|
||||
var movedist = Math.sqrt(dx * dx + dy * dy);
|
||||
|
||||
//Block appereance of the tooltip on fast movements (with small movedistances)
|
||||
if (movedist > 2)
|
||||
self.show_delta = 0;
|
||||
|
||||
self.x = e.clientX;
|
||||
self.y = e.clientY;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
egw_tooltip.prototype.unbindFromElement = function(_elem)
|
||||
{
|
||||
_elem.unbind('mouseenter.tooltip');
|
||||
_elem.unbind('mouseleave.tooltip');
|
||||
_elem.unbind('mousemove.tooltip');
|
||||
}
|
||||
|
||||
egw_tooltip.prototype.showHintTimeout = function()
|
||||
{
|
||||
if (this.current_elem != null)
|
||||
{
|
||||
this.show_delta += this.time_delta;
|
||||
if (this.show_delta < this.show_delay)
|
||||
{
|
||||
//Repeat the call of timeout
|
||||
var self = this;
|
||||
window.setTimeout(function() {self.showHintTimeout();}, this.time_delta);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.show_delta = 0;
|
||||
this.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
egw_tooltip.prototype._prepare = function(_text)
|
||||
{
|
||||
var self = this;
|
||||
|
||||
//Remove the old tooltip
|
||||
if (this.tooltip_div)
|
||||
this.hide();
|
||||
|
||||
//Generate the tooltip div, set it's text and append it to the body tag
|
||||
this.tooltip_div = $j(document.createElement('div'));
|
||||
this.tooltip_div.hide();
|
||||
this.tooltip_div.append(_text);
|
||||
this.tooltip_div.addClass("egw_tooltip");
|
||||
$j('body').append(this.tooltip_div);
|
||||
|
||||
//The tooltip should automatically hide when the mouse comes over it
|
||||
this.tooltip_div.mouseenter(function() {
|
||||
self.hide();
|
||||
});
|
||||
}
|
||||
|
||||
egw_tooltip.prototype.show = function()
|
||||
{
|
||||
if (this.tooltip_div)
|
||||
{
|
||||
//Calculate the cursor_rectangle - this is a space the tooltip might
|
||||
//not overlap with
|
||||
var cursor_rect = {
|
||||
left: (this.x - 8),
|
||||
top: (this.y - 8),
|
||||
right: (this.x + 8),
|
||||
bottom: (this.y + 8)
|
||||
};
|
||||
|
||||
//Calculate how much space is left on each side of the rectangle
|
||||
var window_width = $j(document).width();
|
||||
var window_height = $j(document).height();
|
||||
var space_left = {
|
||||
left: (cursor_rect.left),
|
||||
top: (cursor_rect.top),
|
||||
right: (window_width - cursor_rect.right),
|
||||
bottom: (window_height - cursor_rect.bottom)
|
||||
};
|
||||
|
||||
//Get the width and the height of the tooltip
|
||||
var tooltip_width = this.tooltip_div.width();
|
||||
if (tooltip_width > 300) tooltip_width = 300;
|
||||
var tooltip_height = this.tooltip_div.height();
|
||||
|
||||
|
||||
if (space_left.right < tooltip_width) {
|
||||
this.tooltip_div.css('left', cursor_rect.left - tooltip_width);
|
||||
} else if (space_left.left >= tooltip_width) {
|
||||
this.tooltip_div.css('left', cursor_rect.right);
|
||||
} else {
|
||||
this.tooltip_div.css('left', cursor_rect.right);
|
||||
this.tooltip_div.css('max-width', space_left.right);
|
||||
}
|
||||
|
||||
if (space_left.bottom < tooltip_height) {
|
||||
this.tooltip_div.css('top', cursor_rect.top - tooltip_height);
|
||||
} else if (space_left.top >= tooltip_height) {
|
||||
this.tooltip_div.css('top', cursor_rect.bottom);
|
||||
} else {
|
||||
this.tooltip_div.css('top', cursor_rect.bottom);
|
||||
this.tooltip_div.css('max-height', space_left.bottom);
|
||||
}
|
||||
|
||||
this.tooltip_div.fadeIn(100);
|
||||
}
|
||||
}
|
||||
|
||||
egw_tooltip.prototype.hide = function()
|
||||
{
|
||||
if (this.tooltip_div)
|
||||
{
|
||||
this.tooltip_div.remove();
|
||||
this.tooltip_div = null;
|
||||
}
|
||||
}
|
||||
|
||||
//A reference to the current tooltip object
|
||||
window.egw_global_tooltip = new egw_tooltip();
|
||||
|
8
etemplate/js/test/et2_test_description.xet
Normal file
8
etemplate/js/test/et2_test_description.xet
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0"?>
|
||||
<overlay>
|
||||
<vbox>
|
||||
<description value="This is only a test" options="bi" />
|
||||
<description value="This is only a test" font_style="italic" statustext="This is only an italic label!"/>
|
||||
</vbox>
|
||||
</overlay>
|
||||
|
@ -25,15 +25,16 @@
|
||||
<columns>
|
||||
<column>
|
||||
<label value="Northwest"/>
|
||||
<label value="Northeast"/>
|
||||
<label value="Southwest"/>
|
||||
</column>
|
||||
<label value="Equator"/>
|
||||
<column>
|
||||
<label value="Northeast"/>
|
||||
<label value="Southwest"/>
|
||||
<label value="Southeast"/>
|
||||
</column>
|
||||
</columns>
|
||||
|
||||
|
||||
<rows>
|
||||
<row/>
|
||||
<row/>
|
||||
@ -121,12 +122,12 @@
|
||||
<columns>
|
||||
<column>
|
||||
<label value="Northwest"/>
|
||||
<label value="Northeast"/>
|
||||
<label value="Southwest"/>
|
||||
</column>
|
||||
<label value="Equator"/>
|
||||
<column>
|
||||
<label value="Northeast"/>
|
||||
<label value="Southwest"/>
|
||||
<label value="Southeast"/>
|
||||
</column>
|
||||
</columns>
|
||||
|
||||
|
18
etemplate/js/test/et2_test_tabbox.xet
Normal file
18
etemplate/js/test/et2_test_tabbox.xet
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0"?>
|
||||
<overlay>
|
||||
<tabbox>
|
||||
<tabs>
|
||||
<tab label="Test1" />
|
||||
<tab label="Test2" />
|
||||
<tab label="Test3" />
|
||||
<tab label="Test4" />
|
||||
</tabs>
|
||||
<tabpanels>
|
||||
<label value="This is the content of tab 1"/>
|
||||
<label value="This is the content of tab 2"/>
|
||||
<label value="This is the content of tab 3"/>
|
||||
<label value="This is the content of tab 4"/>
|
||||
</tabpanels>
|
||||
</tabbox>
|
||||
</overlay>
|
||||
|
13
etemplate/js/test/et2_test_textbox.xet
Normal file
13
etemplate/js/test/et2_test_textbox.xet
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0"?>
|
||||
<overlay>
|
||||
<textbox value="This is a single line textbox." statustext="Write something here!"/>
|
||||
<textbox multiline="true" value="This is a multi line textbox."/>
|
||||
|
||||
<template id="testbox">
|
||||
<textbox value="This is a single line textbox." statustext="And something else here!"/>
|
||||
<textbox multiline="true" value="This is a multi line textbox."/>
|
||||
</template>
|
||||
|
||||
<template id="testbox"/>
|
||||
</overlay>
|
||||
|
@ -145,7 +145,7 @@
|
||||
</grid>
|
||||
</row>
|
||||
<row class="row" disabled="@ts_viewtype">
|
||||
<description value="Unitprice" options=",,ts_unitprice"/>
|
||||
<description value="Unitprice" options=",,,ts_unitprice"/>
|
||||
<grid>
|
||||
<columns>
|
||||
<column disabled="@pm_integration=none"/>
|
||||
|
BIN
etemplate/js/test/gfx/gradient01.png
Normal file
BIN
etemplate/js/test/gfx/gradient01.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 249 B |
85
etemplate/js/test/gfx/gradient01.svg
Normal file
85
etemplate/js/test/gfx/gradient01.svg
Normal file
@ -0,0 +1,85 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="32"
|
||||
height="128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.0 r9654"
|
||||
sodipodi:docname="Neues Dokument 1">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
id="linearGradient3755">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0.52499998;"
|
||||
offset="0"
|
||||
id="stop3757" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop3759" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3755"
|
||||
id="linearGradient3761"
|
||||
x1="15.357142"
|
||||
y1="948.78522"
|
||||
x2="15.357142"
|
||||
y2="1021.8951"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.979899"
|
||||
inkscape:cx="88.135153"
|
||||
inkscape:cy="46.311537"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1600"
|
||||
inkscape:window-height="823"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Ebene 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-924.36218)">
|
||||
<rect
|
||||
style="color:#000000;fill:url(#linearGradient3761);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.50000000000000000;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2985"
|
||||
width="32"
|
||||
height="128"
|
||||
x="0"
|
||||
y="924.36218" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.5 KiB |
BIN
etemplate/js/test/gfx/gradient02.png
Normal file
BIN
etemplate/js/test/gfx/gradient02.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 246 B |
90
etemplate/js/test/gfx/gradient02.svg
Normal file
90
etemplate/js/test/gfx/gradient02.svg
Normal file
@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="32"
|
||||
height="128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.0 r9654"
|
||||
sodipodi:docname="gradient02.svg"
|
||||
inkscape:export-filename="/home/andreas/source/egroupware/trunk/egroupware/etemplate/js/test/gfx/gradient02.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
id="linearGradient3755">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0.52499998;"
|
||||
offset="0"
|
||||
id="stop3757" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop3759" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3755"
|
||||
id="linearGradient3761"
|
||||
x1="15.357142"
|
||||
y1="948.78522"
|
||||
x2="15.357142"
|
||||
y2="1021.8951"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-32,-1976.7244)" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.979899"
|
||||
inkscape:cx="88.135153"
|
||||
inkscape:cy="46.311537"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1600"
|
||||
inkscape:window-height="823"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Ebene 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-924.36218)">
|
||||
<rect
|
||||
style="color:#000000;fill:url(#linearGradient3761);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2985"
|
||||
width="32"
|
||||
height="128"
|
||||
x="-32"
|
||||
y="-1052.3622"
|
||||
transform="scale(-1,-1)" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.7 KiB |
@ -11,7 +11,10 @@
|
||||
<script src="../et2_description.js"></script>
|
||||
<script src="../et2_grid.js"></script>
|
||||
<script src="../et2_button.js"></script>
|
||||
<script src="../et2_box.js"></script>
|
||||
<script src="../et2_textbox.js"></script>
|
||||
<!--<script src="../et2_tabs.js"></script>-->
|
||||
<script src="../lib/tooltip.js"></script>
|
||||
<style type="text/css">
|
||||
body {
|
||||
font-family: Lucida Grande, sans-serif;
|
||||
@ -75,6 +78,86 @@
|
||||
color: #101050;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
button.et2_button {
|
||||
background-color: #E0E0E0;
|
||||
background-image: url(gfx/gradient01.png);
|
||||
background-position: center;
|
||||
background-repeat: repeat-x;
|
||||
|
||||
border: 1px solid silver;
|
||||
color: #101010;
|
||||
cursor: pointer;
|
||||
margin: 5px;
|
||||
padding: 3px;
|
||||
text-align: center;
|
||||
|
||||
font-size: 9pt;
|
||||
|
||||
text-shadow: 1px 1px #E0E0E0;
|
||||
}
|
||||
|
||||
button.et2_button:hover {
|
||||
color: #050505;
|
||||
border: 1px solid gray;
|
||||
background-color: #D0D0EE;
|
||||
}
|
||||
|
||||
button.et2_button:active {
|
||||
background-image: url(gfx/gradient02.png);
|
||||
background-color: #D0D0E0;
|
||||
}
|
||||
|
||||
button.et2_button:focus {
|
||||
border: 1px solid #2c3d6f;
|
||||
color: #202d52;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
div.et2_hbox {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.et2_tabflag {
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
height: 20px;
|
||||
padding: 5px;
|
||||
cursor: pointer;
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-style: solid;
|
||||
border-color: silver;
|
||||
}
|
||||
|
||||
.et2_tabflag.active {
|
||||
border-bottom: 1px solid white;
|
||||
}
|
||||
|
||||
.et2_textbox {
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.et2_bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.et2_italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.et2_vbox div, .et2_vbox span {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.egw_tooltip
|
||||
{
|
||||
position: fixed;
|
||||
border: 1px solid #897f51;
|
||||
padding: 3px;
|
||||
background-color: #FDF9DB;
|
||||
max-width: 300px;
|
||||
color: black;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@ -84,6 +167,9 @@
|
||||
<a href="#" onclick="open_xet('et2_test_timesheet_edit.xet');">Timesheet edit dialog</a>
|
||||
<a href="#" onclick="open_xet('et2_test_template.xet');">Template proxy test</a>
|
||||
<a href="#" onclick="open_xet('et2_test_grid.xet');">Grid test</a>
|
||||
<a href="#" onclick="open_xet('et2_test_tabbox.xet');">Tabs test</a>
|
||||
<a href="#" onclick="open_xet('et2_test_textbox.xet');">Textbox test</a>
|
||||
<a href="#" onclick="open_xet('et2_test_description.xet');">Description test</a>
|
||||
</div>
|
||||
<div class="header">ETemplate2 container:</div>
|
||||
<div id="container"></div>
|
||||
|
Loading…
Reference in New Issue
Block a user